Apache

Proxying encrypted traffic to your application server

on Apr 9, 19 • by Andrew Carr • with No Comments

An introduction to implementing SSL in Apache Tomcat and configuring your proxy to use SSL when connecting to ensure end-to-end encryption...

Home » Open Source » Proxying encrypted traffic to your application server

If you recall in part 1 of my blog post, application servers are required to allow an end-user to access your applications. So by this point, you should have a proxy server that is proxying the end user’s request through the web server and to the application server, as shown in the drawing below.

Proxying the end user’s request through the web server and to the application server

In part 2 of my post, I’ll cover an introduction to implementing SSL in Apache Tomcat and configuring your proxy to use SSL when connecting, thus ensuring end-to-end encryption.

Setting up an encrypted connector on the Tomcat side will allow encryption of traffic between the Apache web server and the Apache Tomcat container. Note that this just ensures encryption on the traffic between the web server and the application container, this does not provide encryption for the end user’s connection to the web server, that is a different configuration.

To achieve true end-to-end encryption, which means the users request and response data is never unencrypted while in transit, you need to have encryption enabled on the web server as well as the application container.

Setup: Apache Web Server and application container

Our setup is very similar to the setup we used in part 1 of this blog. We have an Apache Web Server that we have configured to proxy the user’s request to an application container. This application container is hidden to the public world in most cases, this is done for security reasons.

Proxying traffic to an application server allows you to prevent unauthorized access to the application server. The end user that is making the request only has to have visibility to the “front-end,” or the Apache Web Server in this case. Since the application server is accessible by the web server, and the traffic is proxied from the web server, there is no need to expose the application server to the end user. This limits the number of vulnerabilities your system has. Instead of having to deal with a vulnerable Apache Web Server and a vulnerable Apache Tomcat Server (the application server,) you only have to deal with the vulnerabilities of the web server that is exposed to the end user.

We proxied using the http proxy, now we will change it to use the https proxy. To do this simply change your proxy configuration protocol from “http” to “https.”

Configuration: Secure connector on Apache Tomcat

ProxyPass “/test” “https://:8443/test/”
ProxyPassReverse “/test” “https://:8443/test/”

Explaining how SSL works, how to determine what type of SSL to use, and what expectations to have based on these choices is beyond the scope of this blog. I will simply explain how to setup a secure connector on Tomcat, which will serve as a generic SSL endpoint. You can replace this with any application server or web server you are sending proxied traffic to.

Below is a cut down configuration file for the Tomcat server, it is standard and complete. The section that is not standard I have highlighted. It is a configuration of a SSL endpoint.

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA"
                         certificateKeystorePassword="password" />
        </SSLHostConfig>
    </Connector>
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

Note the connector configuration references a file, localhost-rsa.jks. This is a java keystore where your certificate is stored. Rename this to your keystore, if you have one, and replace the password with the proper password. If you do not have a keystore, the command below will create the keystore for you, with the password of “password.”

keytool -genkey -keyalg RSA -alias selfsigned -keystore localhost-rsa.jks -storepass password -validity 365 -keysize 2048

After running this command, answer the questions with information for your certificate. This information is not crucial, as this is a self-signed certificate just for testing. You will have a file in the directory you ran the command in, move the file to the conf folder located in your Tomcat directory.

Start the Tomcat server. You should see it create a connector during the startup log, and it should be similar to this:

30-Mar-2019 06:12:45.135 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-8443"]
Initialization of the server with SSL will take significantly longer than with no SSL.

I have direct access to the server, so I will test it, by browsing to the IP of the server at host 8443, using the https protocol. See the picture below:

Browsing to the IP of the server at host 8443

This is a security warning because I have used a certificate that is not signed by a trusted authority. We will just hit “Advanced” and “Proceed…” or “Add Security Exception,” etc… This will take us to the Tomcat homepage.

Tomcat homepage

We can see that SSL is working, even though it has a red line through it (that just means it is an un-trusted cert.)

Now if we access our proxy server using the “https” protocol, we will be redirected to the application container using encryption. This allows us to encrypt the connection from end to end.

Conclusion

We see that installing Apache Web Server, Mod Proxy, Apache Tomcat, and Java is straightforward in Linux, as demonstrated in part 1. Once the appropriate packages are installed, it is easy to set up a proxy. After proxying normal traffic, we can easily proxy encrypted traffic.

We did not set up an SSL endpoint on the web server, which is something you will need to do if you want security from start to finish of the user’s connection, but this will give you encryption from your proxy to whatever is behind it, Tomcat in this case.

Using “https” vs. “http” is relatively simple, you just change the connector definition in the proxy configuration, and you make sure there is an SSL connector accepting connections on the backend. Don’t forget to update your proxy configuration to use the correct port as well.

Please feel free to reach out and let me know if you would like a more detailed example of proxying traffic with encryption, I am always available to help.

And don’t forget … our open source architects are available to assist you with this and other popular open source solutions.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top