使用SSL和自签名证书使JMX在Tomcat 7下运行

我正在尝试使用SSL在Tomcat 7.0.23下运行JMX。 服务器位于AWS中,这意味着所有主机都是NAT,我需要使用JmxRemoteLifecycleListener来显式设置JMX使用的两个端口。 我一直在做很多关于这个主题的阅读,但我不能让所有的部分正确地协同工作。

没有SSL,我可以让JMX正常工作。 我已经为我的Tomcat版本下载了catalina-jmx-remote.jar的版本,并将其安装在我的tomcat / lib目录中。 我的server.xml包含:

 

当我使用以下设置启动Tomcat时,我可以使用不安全的会话进行连接:

 -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= -Dcom.sun.management.jmxremote.ssl=false 

但是,如果我将这些更改为以下,那么我无法建立SSL连接:

 -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= -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= -Djavax.net.ssl.trustStore=/path/to/truststore.dat -Djavax.net.ssl.trustStorePassword= 

keystore.dat只包含一个通过以下方式创建的证书:

 openssl x509 -outform der -in cert.pem -out cert.der keytool -import -alias tomcat -keystore keystore.dat -file cert.der -storepass  

truststore.dat包含java cacerts的完整副本以及我自签名证书的CA证书:

 cp $JAVA_HOME/jre/lib/security/cacerts truststore.dat keytool -storepasswd -storepass changeit -new  -keystore truststore.dat keytool -import -trustcacerts -file mycacert.pem -alias myalias -keystore truststore.dat -storepass  

启动Tomcat后,我尝试通过jconsole连接,但无法建立连接。 我尝试使用opensslvalidationSSL,但看起来Tomcat没有使用证书:

 $ openssl s_client -connect :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 --- 

我已通过导出密钥并validation证书链来validation我的本地密钥库和信任库是否已正确设置(combined.pem是来自truststore.dat的所有CA证书,cert.pem是来自keystore.dat的证书):

 $ openssl verify -verbose -purpose sslserver -CAfile combined.pem cert.pem cert.pem: OK 

所以现在我完全失去了。 证书和CA证书看起来正确。 未加密的JMX连接有效。 但我似乎无法获得使用SSL的连接。 我在这里想念的是什么?

我不知道这只是一个红鲱鱼,但我没有看到任何方法来指定JMX使用的keyStore中的证书。 我读到的一些内容暗示它只使用带有别名“tomcat”的证书。 那是对的吗?

您正在端口1099上启动RMI注册表 。 为了使RMI注册表能够使用SSL,您需要传递一个额外的-Dcom.sun.management.jmxremote.registry.ssl=true参数。

编辑:你使用jconsole -J-Djavax.net.ssl.trustStore=truststore -J-Djavax.net.ssl.trustStorePassword=trustword -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password启动JConsole? 它需要知道商店的位置和相应的密码。

对于VisualVM,您可以安装VisualVM-Security插件,该插件将在“选项”对话框中添加新选项卡,允许您在UI中自定义SSL相关选项。

我希望tomcat能够使用jmx和ssl并跟随Bruce设置。 如果有人遇到同样的问题:使用openssl和keytool命令形成Bruce我遇到客户端ssl错误:

 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

不知道为什么,但一方面的指纹在开始时长了5个字符。

我使用以下方法重新创建了密钥库:

 keytool -genkeypair -alias tomcat -keyalg RSA -keystore keystore.jks -dname cn=test,ou=test,dc=example,dc=com 

在tomcat sever.xml中,我添加了侦听器,正如Bruce建议的那样。

因为客户端身份validation设置为false,所以我不在tomcat jmx配置中添加truststore。 相反,我添加了registry.ssl:

 [...] -Djavax.net.ssl.keyStorePassword=your_keystore_pass -Dcom.sun.management.jmxremote.registry.ssl=true 

然后在客户端,如JB建议我为visualvm下载ssl插件并纵横交叉密钥库,导致:

 visualvm -J-Djavax.net.ssl.trustStore=keystore.jks -J-Djavax.net.ssl.trustStorePassword=your_keystore_pass 

添加身份validation时,请确保您的jmx访问文件如下所示:

  readwrite 

和您的密码文件如下所示:

   

这解决了我的ssl jmx设置,用于使用visualm vm进行测试。

编辑:

有关于通过SSL使用注册表的一些问题,请设置:

 -Dcom.sun.management.jmxremote.registry.ssl=true 

领导客户投掷:

 Root exception is java.rmi.ConnectIOException: non-JRMP server at remote endpoint 

添加客户端身份validation:

 -Dcom.sun.management.jmxremote.ssl.need.client.auth=true -Djavax.net.ssl.trustStore=truststore.jks -Djavax.net.ssl.trustStorePassword=your_trust_store_pass 

解决了jmx及其注册表以使用ssl。