Apache HTTPD / mod_proxy / Tomcat and SSL with client authorization

I am sure these are frequently asked questions, but I could not find anything that I considered the same question.

I have several web applications running on Tomcat, with some pages, for example. SSL protected login page as defined by the privacy elements in their web.xmls. One of the applications also accepts client authentication through a certificate. I also have a fairly extensive JAAS-based authorization and authentication scheme, and there are all kinds of common code and various JAAS configurations between different web applications, etc.

I really don't want to break this by doing below.

I am currently in the process of adding Apache HTTPD with mod-proxy and mod-proxy-balancer before Tomcat as a load balancer, before adding additional instances of Tomcat.

What I want to do for HTTPS requests is that they are redirected β€œblind” to Tomcat, and HTTPD is not an SSL endpoint, i.e. HTTPD simply passes the ciphertext directly to Tomcat so that TC can continue to do what it already does with inputs, SSL, the guarantee of privacy in web.xml and, most importantly, client authentication.

Is this possible with the configuration I described?

I am very familiar with webapps and SSL and HTTPS and Tomcat, but my knowledge of Apache HTTPD external paths is limited.

Happy if necessary, but it will be programming with configuration files;)

+6
source share
1 answer

This is similar to this question where I answered that this is not possible:

You cannot just transfer SSL / TLS traffic to Tomcat from Apache. Either your SSL connection ends in Apache, and then you need to cancel proxy server traffic on Tomcat (SSL (between Httpd and Tomcat) is rarely useful in this case), or you make clients connect directly to Tomcat and allow you to handle the SSL connection.

I acknowledge that this is slightly related to the links to this claim. I guess I'm wrong (I never saw this, but that does not mean that it does not exist ...).

As you know, you need a direct connection or a full connection between the user agent and the SSL endpoint (in this case you want it to be Tomcat). This means that Apache Httpd will not be able to view the URL: it will know the host name at best (when using the server name).

The only option that does not seem to depend on the URL in the mod_proxy documentation is AllowCONNECT , which is used for advanced proxies for HTTPS.

Even the parameters in mod_proxy_balancer expect a path at some point in the configuration. Its documentation does not mention SSL / HTTPS ("It provides load balancing support for the HTTP, FTP, and AJP13 protocols"), while mod_proxy says at least SSL when mentioning CONNECT .

I would suggest several options:

  • Using the iptables load balancer, without going through Httpd, ending directly with connections in Tomcat.

  • End the SSL / TLS connection on Httpd and use the simple HTTP reverse proxy for Tomcat.

This second option requires a slightly larger configuration to handle client certificates and Tomcat security restrictions.

If you configured your webapp using <transport-guarantee>CONFIDENTIAL</transport-guarantee> , you need to make the Tomcat flag safe, even though it sees that they come from its simple HTTP port. For Tomcat 5, here is an article (originally in French, but automatic translations are not so bad), describing how to implement a valve for install isSecure() . (If you are not familiar with valves , they are similar to filters, but they work inside Tomcat itself before the request is distributed in the webapp. They can be configured in Catalina). I think that from Tomcat 5.5 the HTTP secure connector option does exactly this without requiring its own valve. The AJP connector also has a similar option (when using mod_proxy_ajp or mod_jk ).

If an AJP connector is used, mod_proxy_ajp redirect the first certificate in the chain and make it available in Tomcat (via the regular request attribute). You will SSLOptions +ExportCertData +StdEnvVars need SSLOptions +ExportCertData +StdEnvVars . mod_jk (although deprecated as far as I know) can also redirect the entire chain sent by the client (using JkOptions +ForwardSSLCertChain ). This may be required when using proxy certificates (which do not make sense without a chain to their endpoint certificate).

If you want to use mod_proxy_http , the trick is to pass the certificate through the HTTP header ( mod_header ) using something like RequestHeader set X-ClientCert %{SSL_CLIENT_CERT}s . I cannot remember the exact details, but it is important to make sure that this header is cleared so that it never comes from the client browser (who can fake it otherwise). If you need a complete chain, you can try this attempt to fix Httpd . This will probably require an additional valve / filter to include the header in javax.servlet.request.X509Certificate (by parsing the PEM blocks).

A few other points that may be of interest:

  • If I remember well, you need to explicitly download the CRL files for Httpd and configure it to use . Depending on the version of Httpd you are using, you may need to reload it in order to reload the CRL .
  • If you use renegotiation to obtain your client certificate, the CLIENT-CERT directive will not request an Httpd client certificate as far as I know (this is done differently with a valve that can access SSLSession when using the JSSE connector directly). You may need to configure the appropriate path in Httpd to request a client certificate.
+7
source

Source: https://habr.com/ru/post/913093/


All Articles