乐趣区

VisualVm利用SSL连接JMX的方法

原文地址
在前一篇文章里提到在生产环境下应该使用 SSL 来创建 JMX 连接,本文就来讲一下具体怎么做。
前导知识
先了解一下 Java 客户端程序在创建 SSL 连接的一些相关的事情:

Java client 程序在做 SSL 连接的时候,会拉取 server 的证书,利用 truststore 去验证这个证书,如果不存在 or 证书过期 or 不是由可信 CA 签发,就意味着服务端不被信任,就不能连接。
如果在程序启动时没有特别指定使用哪个 truststore(通过 System Property javax.net.ssl.trustStore 指定),那么就会使用 $JAVA_HOME/jre/lib/security/cacerts。如果指定了,就会使用指定的 truststore + cacerts 来验证。
cacerts 存放了 JDK 信任的 CA 证书(含有 public key),它里面预先已经存放了已知的权威 CA 证书。你可以通过 keytool -list -keystore – $JAVA_HOME/jre/lib/security/cacerts 看到(让你输密码的时候直接回车就行了)

以上过程被称为 server authentication,也就是说 client 验证 server 是否可信,server authentication 是最常见的,https 就是这种模式。
不过在用 SSL 连接 JMX 的时候,还要做 client authentication,即 server 验证 client 是否可信。原理和上面提到的一样,只不过变成 server 用自己的 truststore 里验证 client 的证书是否可信。
第一步:制作 keystore 和 truststore
上面提到的证书主要保存了一个 public key,SSL 是一个非对称加密协议,因此还有一个对应的 private key,在 java 里 private key 和 private key 存放在 keystore 里。
下面我们来制作 visualvm(client)和 java app(server)的 keystore 和 truststore。
先讲大致流程,然后再给出命令:

生成 visualvm 的 keystore,导出 cert,把 cert 导入到 java-app 的 truststore 里
生成 java-app 的 keystore,导出 cert,把 cert 导入到 visualvm 的 truststore 里

具体命令:

生成 visualvm 的 keystore
keytool -genkeypair \
-alias visualvm \
-keyalg RSA \
-validity 365 \
-storetype pkcs12 \
-keystore visualvm.keystore \
-storepass <visualvm keystore 的密码 > \
-keypass < 同 visualvm keystore 的密码 > \
-dname “CN=< 姓名 >, OU=< 组织下属单位 >, O=< 组织名称 >, L=< 城市 >, S=< 省份 >, C=< 国家 2 字母 >”

导出 visualvm 的 cert
keytool -exportcert \
-alias visualvm \
-storetype pkcs12 \
-keystore visualvm.keystore \
-file visualvm.cer \
-storepass <visualvm keystore 的密码 >

把 visualvm 的 cert 导入到 java-app 的 truststore 里,实际上就是生成了一个 truststore
keytool -importcert \
-alias visualvm \
-file visualvm.cer \
-keystore java-app.truststore \
-storepass <java-app truststore 的密码 > \
-noprompt

生成 java-app 的 keystore
keytool -genkeypair \
-alias java-app \
-keyalg RSA \
-validity 365 \
-storetype pkcs12 \
-keystore java-app.keystore \
-storepass <java-app keystore 的密码 > \
-keypass < 同 java-app keystore 的密码 > \
-dname “CN=< 姓名 >, OU=< 组织下属单位 >, O=< 组织名称 >, L=< 城市 >, S=< 省份 >, C=< 国家 2 字母 >”

导出 java-app 的 cert
keytool -exportcert \
-alias java-app \
-storetype pkcs12 \
-keystore java-app.keystore \
-file java-app.cer \
-storepass <java-app keystore 的密码 >

把 java-app 的 cert 导入到 visualvm 的 truststore 里
keytool -importcert
-alias java-app \
-file java-app.cer \
-keystore visualvm.truststore \
-storepass <visualvm truststore 的密码 > \
-noprompt

所以最终得到的文件是这么几个:

visualvm.keystore,包含 visualvm 的 public key 和 private key
visualvm.truststore,包含 java-app cert
java-app.keystore,包含 java-app 的 public key 和 private key
java-app.truststore,包含 visualvm cert

第二步:启动 Tomcat
我们还是用 Tomcat 做实验,给 CATALINA_OPTS 添加几个参数像下面这样,因为参数比较多,所以我们在 $TOMCAT/bin 下添加一个 setenv.sh 的文件(记得加上可执行权限):
CATALINA_OPTS=”-Dcom.sun.management.jmxremote”
CATALINA_OPTS=”$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false”
CATALINA_OPTS=”$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=1100″
CATALINA_OPTS=”$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=true”
CATALINA_OPTS=”$CATALINA_OPTS -Djava.rmi.server.hostname=<host or ip>”
CATALINA_OPTS=”$CATALINA_OPTS -Djavax.net.ssl.keyStore=<path to java-app.keystore>”
CATALINA_OPTS=”$CATALINA_OPTS -Djavax.net.ssl.keyStorePassword=<java-app.keystore 的密码 >”
CATALINA_OPTS=”$CATALINA_OPTS -Djavax.net.ssl.trustStore=<path to java-app.truststore>”
CATALINA_OPTS=”$CATALINA_OPTS -Djavax.net.ssl.trustStorePassword=<java-app.truststore 的密码 >”
然后 $TOMCAT/bin/startup.sh
第三步:启动 visualvm
jvisualvm -J-Djavax.net.ssl.keyStore=<path to visualvm.keystore> \
-J-Djavax.net.ssl.keyStorePassword=<visualvm.keystore 的密码 > \
-J-Djavax.net.ssl.trustStore=<path to visualvm.truststore> \
-J-Djavax.net.ssl.trustStorePassword=<visualvm.truststore 的密码 >
你可以不加参数启动 jvisualvm,看看下一步创建 JMX 连接是否成功,如果配置正确应该是不会成功的。
第四步:创建 JMX 连接
加了上述参数启动 jvisualvm 后,和利用 VisualVm 和 JMX 远程监控 Java 进程里提到的步骤一样创建 JMX 连接,只不过在创建 JMX 连接的时候不要勾选【不要求 SSL 连接】(不过经实测,勾不勾选都能连接成功的)。
参考资料

Monitoring and Management Using JMX Technology – Using SSL
Customizing the Default Keystores and Truststores, Store Types, and Store Passwords

Customizing JSSE,这个表格列出了一些 SSL 相关的 System Properties
Creating a Keystore to Use with JSSE
keytool
Monitor Java with JMX

Java Secure Socket Extension (JSSE) Reference Guide,这是 Java 对于 SSL 支持的最全的参考文档

我的博客即将同步至腾讯云 + 社区,邀请大家一同入驻:https://cloud.tencent.com/dev…

退出移动版