Pivotal Knowledge Base

Follow

How can Tomcat require (redirect to) a secure connection when behind an Apache HTTP Server reverse proxy? (2007800)

How can Tomcat require (redirect to) a secure connection when behind an Apache HTTP Server reverse proxy? (2007800)

Purpose

Tomcat can automatically enforce security constraints specified in your web application and cause requests for secured functionality on a non-secure connection to be redirected to a secure (HTTPS) connection instead. However, when the client is accessing Tomcat via a reverse proxy, Tomcat must be configured to specify the redirect headers relative to the proxy, not itself.

Resolution

The configuration required depends on how the proxy is connected to Tomcat. The AJP or HTTP connectors may be used, and the HTTP connector may be used with or without SSL (HTTPS).
 
We assume for all these examples that Tomcat is expected to enforce the security constraint itself (for example, when it has been specified in an application's web.xml as follows):

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Automatic SSL Forwarding</web-resource-name>
    <url-pattern>/secure/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>
      CONFIDENTIAL
    </transport-guarantee>
  </user-data-constraint>
</security-constraint>

1. Using an AJP connector only

The easiest configuration requires only an AJP connector. Note that his does not encrypt the connection between the proxy and Tomcat.
 
An AJP connector is simple because the details of the request to the proxy are conveyed to Tomcat, which serves the request as if it had been made directly, and thus constructs all redirects relative to the proxy's host. The only thing that the connector needs for the redirect to work is the "redirectPort" property, which should specify the secure (HTTPS) port on the proxy (not Tomcat).

<Connector executor="tomcatThreadPool"
    protocol="AJP/1.3"
    port="8009"
    redirectPort="443"
/>
 
This connector can be used for both the non-secure and secure reverse proxy connections. Via mod_proxy_ajp or mod_jk, Apache HTTP Server will convey the secure status of the connection so that Tomcat can correctly assess security constraints. It can also be used in conjunction with a secured HTTP connector if a secure connection is required between the proxy and Tomcat (see Using an HTTP connector for the non-secure connection).

2. Using an HTTP connector for the non-secure connection

An HTTP connector does not automatically convey the proxy_トホs request information to Tomcat, as it has request headers of its own. Thus, for Tomcat to form proper redirect requests, specify the proxy host information as part of the connector, as well as the secure (HTTPS) port with redirectPort:
 
<Connector executor="tomcatThreadPool"
    protocol="HTTP/1.1"
    port="8080"
    proxyName="proxy.example.com"
    proxyPort="80"
    redirectPort="443"
/>

By specifying the proxy host information, Tomcat creates all redirects relative to that host. This means the proxy configuration does not need the customary ProxyPassReverse directive to rewrite redirects. However, it also means that requests made directly to this connector (not via the proxy) redirect to the proxy, so testing is a little harder.

This connector cannot be re-used as the connector for the secure connection. For this purpose, a different HTTP connector is needed, either with SSL transport enabled or with properties indicating secure transport (see Using an HTTP connector with SSL and Using a clear-text HTTP connector for secure transport).

3. Using an HTTP connector with SSL

If secure transmission is required between the proxy and Tomcat, then this type of connector should be used. An HTTPS connector is simply an HTTP connector with added properties to specify SSL parameters.
 
<!-- server.xml HTTPS connector -->
<Connector executor="tomcatThreadPool"
    protocol="HTTP/1.1"
    port="8443"
    SSLEnabled="true"
    SSLProtocol="TLS"
    proxyName="proxy.example.com"
    proxyPort="443"
    keystoreFile="conf/keystore.jks"
    keystorePass="changeit"
    scheme="https"
    secure="true"
/>

The proxyName and proxyPort are optional here. As with the previous HTTP connector, they cause Tomcat to form redirects relative to the proxy. The keystoreFile/keystorePass properties specify how to access the server's key and certificate for SSL purposes. You can also set up client certificate authentication and specify other SSL parameters -see the connector documentation for more details. The "scheme" and "secure" properties are redundant here as they are implied (in fact, overridden) by the use of SSL, but it is good to be explicit.

 There is no need for the redirectPort property, as the secure connector should not need to redirect for secure transport. The Apache HTTP Server would be configured to access this connector with this example configuration:

# httpd.conf
# mod_proxy_http - secured https
<VirtualHost *:443>
  ServerName proxy.example.com:443
  SSLEngine on
  SSLProxyEngine on
  # other SSL parameters (e.g. specifying the key/cert and logs) omitted
  ProxyPass / https://backend.example.com:8443/
</VirtualHost>

Note the need for SSLProxyEngine to enable SSL over the secured backend connection, and no need for a ProxyPassReverse as the connector above specified the proxy host information.

4. Using a clear-text HTTP connector for secure transport

A non-secure connection between proxy and Tomcat might be desired (for performance reasons) for a client connection that is actually secure. A plain HTTP connector can be used with the "secure" property set to indicate to Tomcat that the transport is actually secure (satisfying security constraints so no redirect is needed).

<!-- server.xml "secure" HTTP connector -->
<Connector executor="tomcatThreadPool"
    protocol="HTTP/1.1"
    port="8443"
    scheme="https"
    proxyName="proxy.example.com"
    proxyPort="443"
    secure="true"
/>
 
The "secure" property designates this connector for secure transport; thus it should not be re-used to serve a proxy connection for a request that's not actually secured - there should be separate HTTP connectors for the two purposes. The "scheme", "proxyName", and "proxyPort" properties are optional here, for the purpose of Tomcat creating proxy-referencing URLs (as opposed to requiring ProxyPassReverse in the Apache HTTP server config).

This Article Replaces

1037406
©VMware 2013

Comments

Powered by Zendesk