Nginx Reverse Proxy With Ssl Offloading and Apache Tomcat Backends

Estimated reading time: 2 mins

Nginx SSL offloading

In our current native Docker environment, we are using Nginx as our border controller (link) to get the traffic and the user sessions (sticky) managed with our Apache Tomcat servers. But together with our developers we found out that there is a major problem with https encryption on Nginx and using Apache Tomcat http connector as backend interface.

The problem

If the Apache Tomcat is not configured correctly (server.xml and web.xml) some of the automatically created redirect links (created by Apache Tomcat himself) in application will still point to http resource urls. This will lead to double requests and of course to a not working application if you are using a modern browser like Chrome (insecure content in secure context).

The solution(s)

Apache Tomcat server.xml

You have to modify the Apache Tomcat server.xml to add the parameters{xhtml}scheme=“https”, secure=“true”, proxyPort=“443”{/xhtml} . Afterwards your http connector setting should looks like the following code. Afterwards the request object in the Apache Tomcat will have the correct scheme.

1
2
3
4
5
6
7
8
9
<Connector port="${port.prefix}1"
  URIEncoding="UTF-8"
  executor="tomcatThreadPool"
  protocol="HTTP/1.1"
  scheme="https"
  secure="true"
  proxyPort="443"
  connectionTimeout="410000"
/>

web.xml

Usually you will enable the {apache}x-forwarded-for{/apache} header in the Nginx configuration. Afterwards on the backend you can retrieve the header inside your, in case of Apache Tomcat, Java code. But this would be a manual way to do it. To be compatible with this header out of the box, you can add a filter to you web.xml. Afterwards the x-forwarded-proto will be automatically set inside the Apache Tomcat request object. Here is the needed part of the web.xml.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    <filter>
        &lt;filter-name&gt;RemoteIpFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.apache.catalina.filters.RemoteIpFilter&lt;/filter-class&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;protocolHeader&lt;/param-name&gt;
            &lt;param-value&gt;x-forwarded-proto&lt;/param-value&gt;
        &lt;/init-param&gt;
    </filter>

    <filter-mapping>
        &lt;filter-name&gt;RemoteIpFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
        &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
    </filter-mapping>

Summary

After some research we figured out on how to configure Apache Tomcat to work seamlessly with Nginx as reverse proxy in conjunction with Apache Tomcat backends.

Posted on: Fri, 07 Jul 2017 07:15:37 +0200 by Mario Kleinsasser
  • General
  • Doing Linux since 2000 and containers since 2009. Like to hack new and interesting stuff. Containers, Python, DevOps, automation and so on. Interested in science and I like to read (if I found the time). My motto is "𝗜𝗺𝗮𝗴𝗶𝗻𝗮𝘁𝗶𝗼𝗻 𝗶𝘀 𝗺𝗼𝗿𝗲 𝗶𝗺𝗽𝗼𝗿𝘁𝗮𝗻𝘁 𝘁𝗵𝗮𝗻 𝗸𝗻𝗼𝘄𝗹𝗲𝗱𝗴𝗲. [Einstein]". Interesting contacts are always welcome - nice to meet you out there - if you like, do not hesitate and contact me!