Configuring multiple SSL certificates for a single Tomcat connector

Sometimes you may want the same Tomcat instance to respond to requests for more than just one hostname. For HTTP this can easily be accomplished, by mapping those hostnames to the same IP address, using the tools provided by your registrar. Supporting HTTPS for multiple hosts is more involved since the SSL certificates need to be deployed and made available to Tomcat.

To get around the requirement to use a JavaKeyStore for certificate management, the native APR connector needs to be used. The Apache Tomcat Native Library is an optional component for use with Apache Tomcat that allows Tomcat to use certain native resources for better performance, a nice side-effect.

Debian-Linux and Ubuntu

On Debian-Linux and Ubuntu, the required library can easily be installed and configured like so:

apt-get install libtcnative-1

The library will be created/installed and can then be found here: /usr/lib/x86_64-linux-gnu/libtcnative-1.so

To make Tomcat aware of the library, add this line to $CATALINA_HOME/bin/setenv.sh (if the file doesn’t exist, create it and make it executable)

CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/usr/lib/x86_64-linux-gnu"

Mac OS

On Mac OS you may want to use the HomeBrew package manager and install the library like so:

brew install libtcnative

and use this line in setenv.sh

CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/usr/local/opt/tomcat-native/lib"

Tomcat

For simplicity, I assume you have the chained certificates and keys stored in Tomcat’s config directory: $CATALINA_HOME/conf. (E.g.: host_name1.pem, host_name1.key, host_name2.pem, host_name2.key.)

Server.xml

Finally, modify the $CATALINA_HOME/conf/server.xml to something like this, before restarting Tomcat:

<?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="443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" minSpareThreads="25" SSLEnabled="true" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2" scheme="https" secure="true" enableLookups="false" disableUploadTimeout="true" acceptCount="400" URIEncoding="UTF-8" defaultSSLHostConfigName="home_name1.domain_name1.com" SSLCertificateFile="${catalina.base}/conf/home_name1.pem" SSLCertificateKeyFile="${catalina.base}/conf/home_name1.key">
            <SSLHostConfig hostName="home_name1.domain_name1.com" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA" certificateFile="${catalina.base}/conf/home_name1.pem" certificateKeyFile="${catalina.base}/conf/home_name1.key">
              </SSLHostConfig>
            <SSLHostConfig hostName="home_name2.domain_name2.com" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA" certificateFile="${catalina.base}/conf/home_name2.pem" certificateKeyFile="${catalina.base}/conf/home_name2.key">
               </SSLHostConfig>
        </Connector>
        <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>

 

3 Replies to “Configuring multiple SSL certificates for a single Tomcat connector”

  1. Hi,

    Why duplicate your configuration?

    SSLCertificateFile=”” SSLCertificateKeyFile=””

    vs

    certificateFile=”…” certificateKeyFile=”…”

  2. I really appreciate this post. It was a good starting point for me. However, your configuration is maximally complex and unnecessary. For example, why would the average user need to specify all of the cipher types? Additionally, the recommended format in the docs is also simpler (e.g. the Certificate tag.)

  3. How about Windows?

Leave a Reply