Monday 30 September 2013

Getting JMX working under Tomcat 7 with SSL and a self-signed cert

Getting JMX working under Tomcat 7 with SSL and a self-signed cert

I'm trying to get JMX working under Tomcat 7.0.23 with SSL. The servers
are located in AWS, which means all the hosts are NATed, and I need to use
JmxRemoteLifecycleListener to explicitly set the two ports used by JMX.
I've been doing a lot of reading on the subject but I just can't get all
the pieces working together properly.
I can get JMX working fine without SSL. I have downloaded the version of
catalina-jmx-remote.jar for my version of Tomcat and installed it in my
tomcat/lib directory. My server.xml contains:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="1099" rmiServerPortPlatform="1098" />
When I launch Tomcat with the following settings I can connect with an
insecure session:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=/path/to/jmxremote.access
-Djava.rmi.server.hostname=<public IP of server>
-Dcom.sun.management.jmxremote.ssl=false
However if I change these to the following then I'm unable to establish an
SSL connection:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=/path/to/jmxremote.access
-Djava.rmi.server.hostname=<public IP of server>
-Dcom.sun.management.jmxremote.ssl=true
-Dcom.sun.management.jmxremote.ssl.need.client.auth=false
-Dcom.sun.management.jmxremote.authenticate=true
-Djavax.net.ssl.keyStore=/path/to/keystore.dat
-Djavax.net.ssl.keyStorePassword=<password>
-Djavax.net.ssl.trustStore=/path/to/truststore.dat
-Djavax.net.ssl.trustStorePassword=<password>
keystore.dat contains just a single certificate created via:
openssl x509 -outform der -in cert.pem -out cert.der
keytool -import -alias tomcat -keystore keystore.dat -file cert.der
-storepass <password>
truststore.dat contains a full copy of the java cacerts plus the CA cert
for my self-signed cert:
cp $JAVA_HOME/jre/lib/security/cacerts truststore.dat
keytool -storepasswd -storepass changeit -new <password> -keystore
truststore.dat
keytool -import -trustcacerts -file mycacert.pem -alias myalias -keystore
truststore.dat -storepass <password>
After launching Tomcat I've tried connecting via jconsole but it can't
establish a connection. I tried to verify SSL using openssl but it looks
like Tomcat isn't making use of the cert:
$ openssl s_client -connect <host>:1099
CONNECTED(00000003)
140735160957372:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake
failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 322 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
I've verified that my local keystore and truststore are set up properly by
exporting the keys and verifying the cert chain (combined.pem is all the
CA certs from truststore.dat and cert.pem is my cert from keystore.dat):
$ openssl verify -verbose -purpose sslserver -CAfile combined.pem cert.pem
cert.pem: OK
So now I'm at a complete loss. The cert and CA cert look correct.
Unencrypted JMX connections work. But I can't seem to get the connection
to use SSL. What am I missing here?
I don't know if this is just a red herring or not, but I don't see any way
to specify what cert in the keyStore is used by JMX. Some of what I read
implies that it just uses a cert with the alias "tomcat". Is that correct?

No comments:

Post a Comment