1

我正在尝试让 JMX 在带有 SSL 的 Tomcat 7.0.23 下工作。服务器位于 AWS,这意味着所有主机都经过 NAT,我需要使用 JmxRemoteLifecycleListener 显式设置 JMX 使用的两个端口。我一直在阅读有关该主题的大量内容,但无法使所有部分正常工作。

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

  <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" 
        rmiRegistryPortPlatform="1099" rmiServerPortPlatform="1098" />

当我使用以下设置启动 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=<public IP of server> 
-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=<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 仅包含通过以下方式创建的单个证书:

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

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

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>

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

$ 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
---

我已经通过导出密钥和验证证书链验证了我的本地密钥库和信任库已正确设置(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”的证书。那是对的吗?

4

2 回答 2

2

您正在端口1099上启动RMI 注册表。为了让RMI Registry使用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 相关选项。

于 2013-10-01T13:24:39.463 回答
1

我希望 tomcat 能够使用 jmx 和 ssl 并遵循 Bruce 的设置。如果有人遇到同样的问题:使用来自 Bruce 的 openssl 和 keytool 命令,我遇到了客户端 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 中,我按照布鲁斯的建议添加了侦听器。

因为客户端身份验证设置为 false,所以我不在 tomcat jmx 配置中添加信任库。相反,我添加了 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

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

<user_name>    readwrite

您的密码文件如下所示:

<user_name>    <your_password>

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

编辑:

在 SSL 上也有一些问题,由以下人员设置:

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

导致客户抛出:

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

添加客户端身份验证:

-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。

于 2016-09-07T15:29:16.447 回答