Thursday, June 03, 2010

Another Tomcat Post :: SSL

Yeah, I'm about tired of Tomcat, too. But this is new and improved Tomcat: Now with OpenSSL. And we know how much I like OpenSSL.

Okay, simple stuff, first. When you install the mod_ssl RPM, it creates a dummy cert. Lets nuke it and create our own:
cd /etc/pki/tls
mv private/localhost.key private/localhost.key.rpm
mv certs/localhost.crt certs/localhost.crt.rpm
openssl genrsa 2048 -out custom.key
openssl req -new -nodes -subj /O=doug \
  -key custom.key -out custom.csr
And the CSR get sent to the non-existant CA... So, fudge it:
openssl x509 -noout -text -signkey custom.key \
  -in custom.csr -out custom.pem
Distribute:
cd private; mv ./custom.key .
ln -s custom.key private.key; cd ..
cd certs; mv ../custom.{csr,pem} .
ln -s custom.pem custom.crt
ln -s custom.pem localhost.crt
service httpd reload
And, yes, memorize *all* that crap.

Test httpd:
echo | openssl s_client -connect localhost:443 | \
  grep subj

Getting Tomcat to work with SSL reminds me of the chorus from an "Offspring" song, Stuff Is Messed Up.

Tomcat requires our cert be converted from x509 to pkcs12. This is not difficult, but there are two critically important issues with the following command. The assigned name must be 100% unique across all files in the working directory. As such, make sure you do this next section in an empty directory.

The second issue is that you will be prompted for a password. It must be more than six characters, even though it will accept smaller, including NULL. Would it surprise you to hear that ultimately your password is going to be coded on the system in clear text? The default clear text password is "changeit".
openssl pkcs12 -export -name unique \
  -in /etc/pki/tls/certs/custom.crt \
  -inkey /etc/pki/tls/private/custom.key \
  -out custom.p12
Ready for another puzzle? Tomcat needs another component called a keystore. Beware: This command assumes your goal is to compile all the pkcs12 files in the working directory. Wait-- Don't assume I said something that I didn't: the command does not source *.p12, it evaluates all the files in the directory and if a file is a pkcs12 file, it compiles it. That's why we're in a nearly empty directory.

And remember the password we entered a moment ago? The keystore's password must match. Oh... and the Tomcat SSL documentation is wrong.
keytool -genkeypair -keystore custom.jks \
  -alias unique -dname O=doug
Notice that there is no -in and what was a pkcs12 name is now the jks alias.

*** Updated 6/16/2010 ***
I have since learned the steps above do not work as I thought. The correct next step is not genkeypair, but instead:
keytool -importkeystore -v -srcstoretype pkcs12 \
  -srckeystore custom.p12 -destkeystore custom.jks

Almost home... Tell Tomcat where to find the keystore, cert, and key by adding the following to the server.xml, just above the line that contains "sslProtocol":
maxThreads="???" scheme="https" secre="true"
keystore="conf/custom.jks" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS" />
Before you save the file, make sure the stanza you just edited is not commented out by a set of <!-- --> symbols.

Symlink the original key and cert back to Tomcat's conf directory. Restart (reload) Tomcat. Test:
echo | openssl s_client -connect localhost:8443 | \
  grep subj

What a mess, but at least it works.

No comments:

Post a Comment