Encrypting the Keystore Password in a Tomcat Connector
Author: Anil Saldhana
Objective:
The user is interested in setting up SSL with Tomcat. Hence he needs a secure connector. An issue that is commonly seen is that the keystore/trustore password is passed as an attribute in the connector element in the tomcat server.xml (This is bad as it compromises the keystore).
Availability:
At JBoss, we have had this functionality available since a long long time (maybe few years) but was never documented as below, until there was a formal JIRA request in this area. http://jira.jboss.com/jira/browse/JBAS-3369
Prerequisite Reading:
http://wiki.jboss.org/wiki/Wiki.jsp?page=JaasSecurityDomain
You have to have a decent understanding of the JaasSecurityDomain that supports keystores, truststores and password based encryption. If it does not make a lot of sense, then just follow the steps highlighted below.
Steps to follow:
Add a connector setting in server.xml in default/deploy/jbossweb-tomcat5x.sar (in jBoss 4.3, the file to edit is deploy/jboss-web.deployer/server.xml)
<!-- SSL/TLS Connector with encrypted keystore password configuration --> <Connector port="9943" address="${jboss.bind.address}" maxThreads="100" minSpareThreads="5" maxSpareThreads="15" scheme="https" secure="true" clientAuth="true" sslProtocol = "TLS" securityDomain="java:/jaas/encrypt-keystore-password" SSLImplementation="org.jboss.net.ssl.JBossImplementation" ></Connector>
You may want to change the port from 9943 to maybe 8443.
Provide the definition for the JaasSecurityDomain in a security-service.xml in the deploy directory with:
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=PBESecurityDomain"> <constructor> <arg type="java.lang.String" value="encrypt-keystore-password"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/keystore.password</attribute> <attribute name="Salt">welcometojboss</attribute> <attribute name="IterationCount">13</attribute> </mbean>
The Salt and IterationCount are the variables that define the strength of your encrypted password. So you
can vary it from what is shown (Just remember to use the changed value which generating the encrypted password).
NOTE: The Salt must be at least 8 characters long.
Your keystore is the localhost.keystore which will be in your conf directory. The keystore.password is your encrypted password that will reside in the conf directory and will be generated in the next step.
Go to the conf directory of your jboss server instance (eg: default/conf)
java -cp ../lib/jbosssx.jar org.jboss.security.plugins.FilePassword welcometojboss 13 unit-tests-server keystore.password
Run this on a single line. In the above example, "welcometojboss" is the salt and 13 is the iteration count.
"unit-tests-server" is the password to the keystore (that you are protecting). keystore.password is the file
in which the encrypted password will be stored.
Update the tomcat service mbean to depend on your JaasSecurityDomain MBean because tomcat connector has to start after
jboss.security:service=PBESecurityDomain
.
Go to deploy/jbossweb-tomcat5x.sar/META-INF Open jboss-service.xml and add the following depends tag towards the end ... <depends>jboss.security:service=PBESecurityDomain</depends> </mbean> </server>
NOTE: if your keystore type is pkcs12, then your JaasSecurityDomain definition looks like
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=PBESecurityDomain"> <constructor> <arg type="java.lang.String" value="encrypt-keystore-password"></arg> </constructor> <attribute name="KeyStoreType">pkcs12</attribute> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/keystore.password</attribute> <attribute name="Salt">welcometojboss</attribute> <attribute name="IterationCount">13</attribute> </mbean>
Related Wiki Pages
http://wiki.jboss.org/wiki/Wiki.jsp?page=EncryptingDataSourcePasswords
Medium security usecase
A user does not want to encrypt the keystore password but wants to externalize it (outside of server.xml)
and/or wants to make use of a predefined JaasSecurityDomain. Here are the steps for that.
Update server.xml to add a connector
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=SecurityDomain"> <constructor> <arg type="java.lang.String" value="jbosstest-ssl"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">unit-tests-server</attribute> </mbean>
Add a depends tag to the tomcat service.
Go to deploy/jbossweb-tomcat5x.sar/META-INF Open jboss-service.xml and add the following depends tag towards the end ... <depends>jboss.security:service=SecurityDomain</depends> </mbean> </server>
Define the JaasSecurityDomain MBean in a -service.xml file
(Eg: security-service.xml in the deploy directory)
<mbean code="org.jboss.security.plugins.JaasSecurityDomain" name="jboss.security:service=SecurityDomain"> <constructor> <arg type="java.lang.String" value="jbosstest-ssl"></arg> </constructor> <attribute name="KeyStoreURL">resource:localhost.keystore</attribute> <attribute name="KeyStorePass">unit-tests-server</attribute> </mbean>
Troubleshooting
File Permission issue reading the keystore (or FileNotFoundException)
Remember the keystore file should be writable by the id that is running JBoss instance.
Comments