In this post I configure a url redirection from HTTP to HTTPS and viceversa using the Apache mod_proxy and the ProxyPass directive. I assume an environment consisting of two hosts: a Web Server Apache in front of a Tomcat Applicaton Server. In the following first example the Apache ProxyPass redirects the HTTP requests to the SSL port 8443 of the Tomcat Server. In the second example the Apache Web Server is configured to accept SSL connections, so a self-signed certificate is locally installed and the requests are redirected from HTTPS to the non-ssl url of Tomcat Server.
Example 1. From Apache HTTP to Tomcat HTTPS
$ yum install mod_ssl $ vi /etc/httpd/conf.d/virtual_hosts.conf
NameVirtualHost *:80 <VirtualHost *:80> ServerName mysite.com SSLProxyEngine On RequestHeader set Front-End-Https "On" CacheDisable * ProxyPass /myapp https://tomcat-host:8443/myapp ProxyPassReverse /myapp https://tomcat-host:8443/myapp RedirectMatch ^/$ http://mysite.com/myapp </VirtualHost>
Example 2. From Apache HTTPS to Tomcat HTTP
$ yum install mod_ssl openssl $ mkdir /etc/httpd/certs $ cd /etc/httpd/certs $ openssl genrsa -out mysite.com.key 1024 $ openssl req -new -key mysite.com.key -out mysite.com.csr $ openssl x509 -req -days 100000 -in mysite.com.csr -signkey mysite.com.key -out mysite.com.crt
$ vi /etc/httpd/conf.d/ssl.conf SSLCertificateFile /etc/httpd/certs/mysite.com.crt SSLCertificateKeyFile /etc/httpd/certs/mysite.com.key $ vi /etc/httpd/conf.d/virtual_hosts.conf
NameVirtualHost *:443 <VirtualHost *:443> ServerName mysite.com ProxyPass /myapp http://tomcat-host:8080/myapp ProxyPassReverse /myapp http://tomcat-host:8080/myapp RedirectMatch ^/$ https://mysite.com/myapp SSLEngine on SSLCertificateFile /etc/httpd/certs/mysite.com.crt SSLCertificateKeyFile /etc/httpd/certs/mysite.com.key </VirtualHost>
This solved problem which i was struggling for some time now.
I have one question in case of Example 1. From Apache HTTP to Tomcat HTTPS
if you have do a mutual authentication between apache and tomcat where do you configure the certificates . will this configuration take care of it
NameVirtualHost *:80
ServerName mysite.com
SSLProxyEngine On
RequestHeader set Front-End-Https “On”
CacheDisable *
ProxyPass /myapp https://tomcat-host:8443/myapp
ProxyPassReverse /myapp https://tomcat-host:8443/myapp
RedirectMatch ^/$ http://mysite.com/myapp
SSLCertificateFile /etc/httpd/certs/tomcat-host.crt
SSLCertificateKeyFile /etc/httpd/certs/tomcat-host.key
tomcat-host.cer and key are configured on tomcat and tomcat verifies the ssl client.
Hi deepak,
thanks for your commnet.
I think the mod_ssl directive
SSLProxyMachineCertificateFile
could be useful for you.Take a look here:
http://stackoverflow.com/questions/11323309/making-a-two-way-ssl-authentication-between-apache-httpd-reverse-proxy-and-tomca
http://www.tomcatexpert.com/blog/2012/07/10/enabling-ssl-communication-and-client-certificate-authentication-between-apache-web-
Giuseppe.
Just want to say thank you.
also resolved my problem.
HI,
Thanks a lot for your post! It helped me a lot, but there’s an issue that I cant fix. The application that is running in the tomcat server calls a .ajax URL and it’s giving me 401.
A cookie of some sort is not getting through the proxy. Do you know how can I fix this?
Hi Leonel,
thanks for comment.
Make sure that your application does not lose the authentication during the ajax call. 401 error code means Unauthorized access to the requested URL. It requires user authentication but It seems the session loses the credentials when the server invokes the URL with ajax. You should check both the log files of Apache and the Tomcat when the error occurs, in order to figure out if the issue happens from the Apache side or the Tomcat Server side and check also if the http header include the Authentication info.
Giuseppe
Hi,
Thanks a lot for your post!! It helped me a bit, but I have a different scenario which I’m trying mutual SSL
Client(https) -> Apache -> Weblogic(https)
In the above scenario, Apache has to redirect the client request to Weblogic server without verifying the client certificate in Apache. The client certificate verification has to happen in WebLogic server.
Kindly please any suggestions on this.
Thanks
Sathish
Hi Sathish,
supposing that Apache is the public fornt-end, I think you should configure two different SSL certificates and use two virtual host entries on your Apache. The first one, serves a normal HTTPS public client access to the Apache server. The second one serves only requests between Apache and Weblogic with a Two-way SSL authentication certificate. Take a look here:
https://linuxconfig.org/apache-web-server-ssl-authentication
Regards
Giuseppe
I need help to do the both as https, APACHE https and Tomcat https, I tried but I can’t connect, I receive always error 503
Hi,
503 error code means your server is unavailable and it can happen due to multiple reasons. At first you should figure out which server generates the problem. The 503 error comes from the Apache side or the Tomcat side?
If no errors occur replace the DocumentRoot with the ProxyPass/ProxyPassReverse directive and make sure you specify the same Tomcat url used in the Tomcat check.
Giuseppe
Hi ,
Current implementation ( From Apache HTTPS to Tomcat HTTP)
I have a Apache server with Client certificate authentication . I’m not able to pass the certificate details to the tomcat server.
I wanted to certificate details in my java code to implement certificate based login.
I had tried to pass the certificate details through the http header , apparently i din’t see the details when i printed all the header details.
configuration in default-ssl.conf ( snipet )
# initialize to a blank value to avoid http header forgeries
RequestHeader set SSL_CLIENT_M_SERIAL ""
# set the actual value
RequestHeader set SSL_CLIENT_M_SERIAL "%{SSL_CLIENT_M_SERIAL}s"
I had used the below code to get all header details:
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
logger.info(headerName+" : "+request.getHeader(headerName));
}
Kindly let me know how can i extract certificate details and get those in java code.
Hi Ashwini,
it seems you have not enable the SSL support on Tomcat. Make sure both Tomcat and Apache Httpd are enabled to receives HTTPS connections.
Remember that from the Tomcat side (that means Java) you need to create your certificate keystore with “keytool”. Take a look at the official Tomcat documentation.
https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
After this, the quick way to test your SSL configuration on Tomcat is to write a java client that simulates Https requests directly to Tomcat. You can find a lot of examples around the web. Here is a nice snippet that make use of HttpsURLConnection of javax.net:
https://www.mkyong.com/java/java-https-client-httpsurlconnection-example/
Take a look at the method which prints the certificate’s parts.
Giuseppe
Hi Giuseppe,
I have a query. I have a communication channel with an entity outside my organization. My system generate a http request which is then sent to a proxy server. The proxy server converts that http request to https and sends it to outside entity. Similarly the outside entity generates a https request to proxy which is then converted to http and sent back to our application. We have a message encrytption algorithm called SHA1 to sign them. We want to convert them to SHA2. We need to confirm few things for the same.
1. If we convert the SHA2 algorithm for messages, do we have to worry about the proxy server. Whether the proxy server needs to be configured to handle a SHA2 algorithm.
2. Do we have to take any extra steps.
Please help me understand here. Thanks in advance.
Hi Mrityunjay,
is not easy to understand your needs. There are not enough information and details. Anyway it seems, you use SHA-1 only to sign messages exchanged between your client and the outside entity. In this case, I think both the client and the outside entity (not the proxy) should update the algorithm and the process of signature . As you described, it seems, the task of proxy is only to encrypt the communication torwards the outside entity.
Contrariwise, if you want to update the HTTPS link (proxy-outside_entity) with a SHA-2 certificate, take a look a this:
I hope this will help you.
Giuseppe
Hi,
I want to do bridge between http and https among two applications in raspberrypi. I installed apache.
I dont see httpd directory in pi .
In this case, which file i should modify to make it work.
Thanks for this stunning guide and your time
Hello,
the configuration files are usually located in /etc/httpd or /etc/apache2.
You can find the location of the Apache files following this tip:
http://www.commanigy.com/blog/2011/6/8/finding-apache-configuration-file-httpd-conf-location
Hi, thanks for your reply.
Now that I need to modify sites-avilable [apache2.conf is a tar file, though can be opened in editor ],
i like to know the purpose of Paroxypass an dproxypassreverse. both are same.
if i put below lines in sites-availble , will the http to https and vice versa will happen?
NameVirtualHost *:80
ServerName localhost.com
SSLProxyEngine On
RequestHeader set Front-End-Https "On"
CacheDisable *
ProxyPass /system/console https://localhost.com:8443/system/console
ProxyPassReverse /system/console https://localhost.com:8443/system/console
NameVirtualHost *:443
ServerName localhost.com
ProxyPass /system/console http://localhost.com
ProxyPassReverse /system/console http://localhost.com
SSLEngine on
I am a beginner in this http ,webserver stuff so, please excuse my naive questions.
The apache.conf is a simple text file so you can open it with any text editor.
ProxyPass and ProxyPassReverse are the two Apache directives which implement the Reverse proxy pattern when a client connects to a server, requesting some service. If you need to offer both the HTTP and HTTPS url to the outside, you have to configure two VirtualHost entries which point to the same destination url. Something like this:
NameVirtualHost *:80
NameVirtualHost *:443
# Start VirtualHost *:80
ServerName localhost.com
ProxyPass /yourPath http://destinationHost/yourPath
ProxyPassReverse /yourPath http://destinationHost/yourPath
# End VirtualHost
# Start VirtualHost *:443
ServerName localhost.com
ProxyPass /yourPath http://destinationHost/yourPath
ProxyPassReverse /yourPath http://destinationHost/yourPath
SSLEngine on
SSLCertificateFile /yourCertificate.crt
SSLCertificateKeyFile /yourCertificateKey.key
# End VirtualHost
In addition, I think, you should take a look at some basic concepts about the Apache mod_proxy and its directives. Here is some useful resources:
http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypass
http://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassreverse
HI,
I have a query if we are using apache to proxy request using reverse proxy from app to apache on http and then apache making https request to a server and this server is returning SSL back to apache in response can apache decrypt the response and send back http to app.
if yes please guide me the configuration required in apache to do the same apache is Oracle http server being used in my case.
Hi,
what you’ve described seems a bit confused. Is the Apache between the Tomcat and the SSL Server? Where do the requests come from?
Anyway I think that first of all, you should understand which server layer generates the problem:
1) make sure the Tomcat server responds as you aspect
2) make sure Apache server responds to Tomcat as you aspect
3) make sure SSL server responds to Apache as you aspect
4) finally make an integration test with the full stack
Take a look at the log files of every layer and check if errors occur.
Such a clean blog.. My Savior.. Thanks 🙂
Hi,
I have this configuratiom
Listen 4443
ServerName HOST
SSLProxyEngine on
RequestHeader set Front-End-Https “On”
#CacheDisable *
ProxyPass /myapp https://HOST:9013/app
#Redirect Permanent /myapp https://HOST::9013/app
ProxyPassReverse /myapp https://HOST::9013/app
RedirectMatch ^/$ http://HOST:4443/myapp
When I hit the URL http://HOST:443, url is not chnaging to https://HOST:9013/app. Do we need to add any other parameters?
Hi,
it seems you have duplicated colon “:” in the ProxyPassReverse directive.
I suggest you to use a fake domain name in order to perform a valid test.
Add a test domain entry in your client /etc/hosts, something like this:
## /etc/hosts
IP_OF_APACHE_SERVER_HERE test.domain.example
Make sure you are able to ping that server:
$ ping test.domain.example
Finally configure a virtual host like this:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName test.domain.example
SSLProxyEngine On
RequestHeader set Front-End-Https "On"
CacheDisable *
ProxyPass /myapp https://tomcat-host:8443/myapp
ProxyPassReverse /myapp https://tomcat-host:8443/myapp
RedirectMatch ^/$ http://test.domain.example/myapp
</VirtualHost>
Also make sure Tomcat host (port 8443) is reachable form the Apache server.
Open your browser on http://test.domain.example (do not insert any port, default is 80)
These are actually enormous ideas in on the topic of
blogging. You have touched some fastidious things here.
Any way keep up wrinting.
hi all,
i have some issues…seeking for experts help.
I manage to setup web and app server but stuck at reverse proxy configuration.
OS is redhat linux 7.7 somereason mod_jk is not available to install and configure for tomcar app server.
So i am opting for reverse proxy configuration.
User will access the URL..https site, https://sasitsgp.com:3486
Gateway will NAT the Public IP and Port number to private IP (sasitsgp.com) and Port Number 8011.
When i try the url from outside to webserver, it was loading https but the page background color and content allignment is not correct.
After entering username and password, clicking sign but not proceeding/ logging.
Also noticed js css etc being blocked..
Can help me/ advise me what went wrong or to be modified…
Frontend server is httpd (https) and backend is tomcat (http).
Error and configuration below.
Mixed Content: The page at ‘https://sasitsgp.com:6542/’ was loaded over HTTPS, but requested an insecure image ‘http://sasitsgp.com:6542/html/themes/classic/images/spacer.png’. This content should also be served over HTTPS.
(index):1
Mixed Content: The page at ‘https://sasitsgp.com:6542/’ was loaded over HTTPS, but requested an insecure image ‘http://sasitsgp.com:6542/html/themes/classic/images/common/openid.gif’. This content should also be served over HTTPS.
Mixed Content: The page at ‘https://sasitsgp.com:6542/’ was loaded over HTTPS, but requested an insecure script ‘http://sasitsgp.com:6542/notifications-portlet/notifications/js/main.js?browserId=other&minifierType=js&languageId=en_US&b=6205&t=1571730210000’. This request has been blocked; the content must be served over HTTPS.
Redhat Linux 7.7, HTTPD Server (Apache) configuration below.
ServerAdmin appadmin@sasitsgp.com
ServerName https://sasitsgp.com:6542/
ProxyRequests On
ProxyPreserveHost On
ProxyPass / http://tomcat-server.com:18021/
ProxyPassReverse / http://tomcat-server.com:18021/
RedirectMatch ^/$ https://sasitsgp.com:6542/
SSLEngine on
SSLCertificateFile /etc/httpd/sslconfig/87497670_sasitsgp.com.cert
SSLCertificateKeyFile /etc/httpd/sslconfig/87497670_sasitsgp.com.key
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder on
SSLCompression off
SSLSessionTickets off
Tomcat application server below.
Redhat Linux 7.7.
Application server server.xml file
–>
<!–