Pages

Thursday, January 21, 2010

Setting up SSL with Tomcat

Many installations use a proxy server to front apache or tomcat for the content.  Recently an audit recommended that we use ssl to encrypt this internal traffic from the front end to the content server. Since it was a bit of black magic for me to find all the right settings, I'm going to do the work and show you the easy way.

I will use a self signed cert to do this.  Since the servers are on our internal network I'm not looking for the cert to validate the identity of the server I'm connecting with.  Instead I want the cert to facilitate SSL encryption of the connection from the front end server to the content server.

Making a self signed cert is easy if you know the right incantation for the keytool. I am using the following command:

# generating a new self signed cert for tomcat
keytool -genkey -keyalg RSA -alias tomcat -keystore keystore -storepass p455w0rd -validity 7300

This command tells the keytool to generate a key using the RSA algorithm and call the cert tomcat and the keystore file 'keystore' with a keystore password of 'p45Sw0rd' and make it expire 7300 days from now.

We run it and it generates a file called keystore.  Now we can get the keystore file to list itself with the following command:

# listing the contents of the keystore
keytool -list -v -keystore keystore


This will prompt for a password but you don't have to enter it because it will list it for you anyway (with a big warning about verification).

server1:511# keytool -list -v -keystore keystore
Enter keystore password:

*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: tomcat
Creation date: Jan 20, 2010
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Michael Holly, OU=Software Dev, O=Pentaco, L=St. Louis, ST=MO, C=US
Issuer: CN=Michael Holly, OU=Software Dev, O=Pentaco, L=St. Louis, ST=MO, C=US
Serial number: 4b5743b5
Valid from: Wed Jan 20 16:29:09 CST 2010 until: Tue Jan 15 16:29:09 CST 2030
Certificate fingerprints:
         MD5:  7B:40:9B:B8:4C:52:AD:FA:D6:B3:59:81:25:88:4B:AD
         SHA1: 05:9E:03:4F:81:F6:5C:FA:DD:2F:DD:A2:A5:97:E9:D3:EE:13:DF:29
         Signature algorithm name: SHA1withRSA
         Version: 3 

Now that we have our cert let's put it in a location outside the Tomcat tree.  I'm going to drop it in a directory called /opt/tomcat_ssl. Using a location like this makes for a simpler upgrade for Tomcat as all we have to do install the new tomcat and move the server.xml over to the new install.

So now we have our keystore file in /opt/tomcat_ssl and we are ready to config tomcat to use it.

What we want to do it modify the server.xml to understand where the keystore is, what it's password is and any other parameters to control the encryption.  This is done by modifying the connector that tomcat is listening on.

<connector
           port="8443" minSpareThreads="5" maxSpareThreads="75"
           enableLookups="true" disableUploadTimeout="true"
           acceptCount="100" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="/opt/tomcat_ssl/keystore" keystorePass="p455w0rd"
           clientAuth="false" sslProtocol="TLS"
           ciphers="SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_
RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3D
ES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA" />

The other thing to note here is we usually want to specify the allowed ciphers as some are weaker than others and should not be allowed. Here is the list of medium to high strength ciphers

SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA

Note that if you are configuring an Apache server these ciphers are specified in a different manner. These values are specific to Tomcat only.

Restart Tomcat and you should be good to go.  To see if it is working hit the page, and then rename /opt/tomcat_ssl/keystore to /opt/tomcat_ssl/keystore.bak.  This should invalidate the setup. Restart Tomcat. When you hit the page again you will probably get a 502 Internal Server Error, depending how your front end server is configured.  Rename keystore back to the original and restart. You should be back in business. Enjoy!

No comments:

Post a Comment