How to encrypt the connection between Apache mod_proxy or mod_cluster and EAP 4 or 5 with SSL

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 4
    • 5
  • Red Hat JBoss Enterprise Web Server (EWS)
    • 1.0.x
  • Apache
    • 2.2
  • mod_proxy
  • mod_cluster

Issue

  • How do I encrypt the connection between Apache mod_proxy or mod_cluster and JBoss with SSL?
  • How do I forward SSL environment information in mod_proxy or mod_cluster when using HTTPS?
  • I need a suggestion for HTTPS-based mod_cluster between Apache HTTPD and JBoss EAP server. Currently, we are using AJP. If we need to use HTTPS, then what are the changes required?
  • I request you to provide the steps to configure SSL between the web server and JBoss EAP 5.2.

Resolution

Disclaimer: Links contained herein to external website(s) are provided for convenience only. Red Hat has not reviewed the links and is not responsible for the content or its availability. The inclusion of any link to an external website does not imply endorsement by Red Hat of the website or their entities, products or services. You agree that Red Hat is not responsible or liable for any loss or expenses that may result due to your use of (or reliance on) the external site or content.

First and foremost, the recommended solution, if you are using the EAP 5, is to use mod_cluster which is the successor to mod_proxy and as a much cleaner ability to encrypt the connection. See: Content from docs.jboss.org is not included.Using SSL in mod_cluster for instructions on using SSL with mod_cluster to encrypt the connection between Apache HTTPD and JBossWeb.

mod_proxy

Encrypting the connection between HTTPD and JBoss Web using mod_proxy

In httpd.conf you need something like:

SSLProxyEngine On
SSLProxyVerify require
SSLProxyCACertificateFile conf/cacert.pem
SSLProxyMachineCertificateFile conf/proxy.pem
ProxyPass / https://127.0.0.1:8443/
ProxyPassReverse / https://127.0.0.1:8443/

Note: conf/cacert.pem must contain the CA that signed the Tomcat certificate.
Note: conf/proxy.pem should contain both key and certificate (and the certificate must be trusted by Tomcat).

Note: The ProxyPass, etc. configuration for HTTPS connections should be defined inside the SSL VirtualHost in Apache. This is how Apache knows to send the requests from HTTPS on port 443 to the HTTPS port on EAP.

Red Hat Enterprise Linux (RHEL)

When running in RHEL there are default localhost certs already on the operating system that can be used to quickly get an SSL setup up and running. The certs should be generated for a production machine, but the default certs are good for testing purposes. A full setup for this is the following:

  • Make sure you have Apache and Tomcat installed from the JBoss Enterprise Web Server channel.  You will need to subscribe to that channel in RHN for your sytem.
yum -y install httpd
yum -y install httpd-devel
yum -y install openssl
yum -y install tomcat6*
service httpd restart
  • Open your browser and hit http://localhost/   Make sure in httpd.conf that you are Listening on the right ip, ex. Listen 127.0.0.1:80
  • Setup SSL between Apache and JBoss with mod_proxy
SSLProxyEngine On
ProxyPass / https://127.0.0.1:8443/
ProxyPassReverse / https://127.0.0.1:8443/
  • In /etc/tomcat6/server.xml uncomment the 8443 connector and change it to:
<Connector port="8443" maxHttpHeaderSize="8192" 
           maxThreads="150"
           protocol="org.apache.coyote.http11.Http11AprProtocol"
           enableLookups="false" disableUploadTimeout="true"
           acceptCount="100" scheme="https" secure="true"
           SSLEnabled="true"
           SSLCertificateFile="/etc/pki/tls/certs/localhost.crt"
           SSLCertificateKeyFile="/etc/pki/tls/private/localhost.key" />
  • If you get the following in your catalina.out or tomcat.log in /var/log/tomcat6:
java.lang.Exception: Unable to load certificate key /etc/pki/tls/private/localhost.key (error:0200100D:system library:fopen:Permission denied)
  • Make sure that localhost.key and localhost.crt are readable by Tomcat:
chmod 644 /etc/pki/tls/certs/localhost.crt
chmod 644 /etc/pki/tls/private/localhost.key
  • Now both Apache and Tomcat should be using SSL you can hit https://localhost/ to verify, you should get the Tomcat page.
Forwarding the SSL environment information to JBoss Web

The variables supported by the servlet interface are the following

  • javax.servlet.request.X509Certificate
  • javax.servlet.request.cipher_suite
  • javax.servlet.request.ssl_session
  • javax.servlet.request.key_size

To get the client certificate or any SSL information from the broswer you have to use mod_header to add the SSL information to header. To do that add in httpd.conf of Apache HTTPD the following:

RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s"
RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s"
RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s"

EAP5: Then you need a valve in Tomcat to extract the information from the request Headers. Add: <className="SSLValve"/> to the <Engine/> part of the server.xml

Note: The Fedora version of Java6 does not have EC ciphers

Note: There is a known issue with mod_proxy_ssl + NIO + the Cisco PIX hardware firewall, the workaround is to use JBoss or TC Native and avoid NIO

mod_cluster

Encrypting the connection between httpd and JBoss Web using mod_cluster

If using SSL between mod_cluster and JBoss, take note of SSL Proxy connect failed and mod_cluster returns "Bad Gateway" HTTP ErrorCode 502. If load drops and connections idle, they can go into a bad state from SSL handshake timeouts to cause 502s. This will be fixed in a later release but can be worked around by disabling connection keepalive and reuse between Apache/JBoss and/or increasing JBoss's HTTP connectionTimeout.

The relevant pieces of the configuration for SSL configuration with mod_cluster are as follows:

mod-cluster.conf:

LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so
    
#Be a client to another server and use ssl to connect to it 
SSLProxyEngine On
SSLProxyVerify require
SSLProxyCACertificateFile conf/cacert.pem
SSLProxyMachineCertificateFile conf/proxy.pem
            
Listen 127.0.0.1:6666
<VirtualHost 127.0.0.1:6666>    
    # Be a server for mod_cluster in JBoss
    SSLEngine on
    SSLCipherSuite AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL
    SSLCertificateFile conf/server.crt
    SSLCertificateKeyFile conf/server.key
    SSLCACertificateFile conf/server-ca.crt
    # If just testing can comment out the below (not secure) 
    SSLVerifyClient require
    SSLVerifyDepth  10 

    <Directory />
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Directory>
    
    KeepAliveTimeout 60
    MaxKeepAliveRequests 0
    
    ManagerBalancerName mycluster

    AdvertiseFrequency 5
</VirtualHost>

<Location /mod_cluster-manager>
    SetHandler mod_cluster-manager
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>

In $JBOSS\_HOME/server/$PROFILE/deploy/mod_cluster.sar/META-INF/mod-cluster-jboss-beans.xml modify the ModClusterServiced being used, either ModClusterService or HAModClusterService:

<bean name="ModClusterService" class="org.jboss.modcluster.ModClusterService" mode="On Demand">
...
    <property name="ssl">true</property>
    <property name="sslKeyStorePass">test</property>
    <property name="sslKeyStore">/home/smendenh/sandbox/CERTS/Client/test.p12</property>
    <property name="sslKeyStoreType">pkcs12</property>
    <property name="sslTrustStore">/home/smendenh/sandbox/CERTS/ca.p12</property>
    <property name="sslTrustStoreType">pkcs12</property>
    <property name="sslTrustStorePassword">test</property>
...
</beans>

$JBOSS_HOME/server/$PROFILE/deploy/$JBOSSWEB/server.xml:

<Server>
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <Listener className="org.apache.catalina.core.JasperListener" />
    <Listener className="org.jboss.web.tomcat.service.deployers.MicrocontainerIntegrationLifecycleListener" delegateBeanName="ModClusterService" />
    
    <Service name="jboss.web">
    
    <!-- Currently for mod_cluster to only use 8443 for communication port 8080 and 8009 must be commented out -->
    <!-- 
       <Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" connectionTimeout="20000" redirectPort="8443" />
    -->
    <!--
       <Connector protocol="AJP/1.3" port="8009" address="${jboss.bind.address}" redirectPort="8443" />
    -->
    
       <Connector port="8443" 
               protocol="HTTP/1.1" 
               SSLEnabled="true"
               truststoreFile="/etc/pki/java/cacerts"
               truststorePass="changeit"
               truststoreType="JKS"
               keystoreType="PKCS12" 
               keystoreFile="/home/smendenh/sandbox/CERTS/Client/test.p12"
               keystorePass="test"
               maxThreads="150" 
               scheme="https" 
               secure="true"
               clientAuth="true" 
               sslProtocol="TLS" />
    
       <Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">
          <Realm className="org.jboss.web.tomcat.security.JBossWebRealm"
             certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping"
             allRolesMode="authOnly"
             />
          <Host name="localhost"> 
             <Valve className="org.jboss.web.tomcat.service.jca.CachedConnectionValve"
                 cachedConnectionManagerObjectName="jboss.jca:service=CachedConnectionManager"
                 transactionManagerObjectName="jboss:service=TransactionManager" />
          </Host>
       </Engine>
    </Service>
</Server>
Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.