November 21, 2024

Redirect from HTTP to HTTPS and viceversa with Apache ProxyPass

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

giuseppe-urso-redirect-http-https-01

$ 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

giuseppe-urso-redirect-http-https-02

$ 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>

 

Related posts

24 Comments

  1. deepak

    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.

    Reply
  2. Leonel

    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?

    Reply
    1. Giuseppe Urso

      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

  3. Sathish

    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

    Reply
    1. Giuseppe Urso

      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

  4. digonzales

    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

    Reply
    1. Giuseppe Urso

      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?

      Check first the Apache HTTPS: use a directive DocumentRoot instead of the ProxyPass/ProxyPassReverse to test the connection (for example DocumentRoot “/var/www/html/test.html”)
      Check the Tomcat HTTPS: try to make a request from the Apache server to Tomcat with wget or curl (for example curl -Ik https://your_tomcat_server:your_tomcat_port/your_webapp)

      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

  5. Ashwini Ravi

    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.

    Reply
    1. Giuseppe Urso

      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

  6. Mrityunjay Kumar

    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.

    Reply
    1. Giuseppe

      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:

      https://www.digicert.com/transitioning-to-sha-2.htm

      I hope this will help you.
      Giuseppe

  7. rasbian

    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

    Reply
  8. rasbian

    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.

    Reply
    1. Giuseppe

      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

  9. Anuj Kaushik

    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.

    Reply
    1. Giuseppe

      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.

    1. Giuseppe

      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)

  10. Sas

    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

    –>

    <!–

    Reply

Leave a Reply

Your email address will not be published.