You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JMX Agent服务端程序内部配置SSL属性启动报SSL握手错误求助

JMX服务端内置SSL配置握手错误解决方案

问题根因

你遇到的Unsupported or unrecognized SSL message错误核心原因是手动创建的RMI Registry默认使用明文Socket,没有绑定SSL配置,仅给JMX Connector Server配置SSL Server Socket Factory不会生效:客户端发送SSL请求到RMI Registry时,Registry返回明文响应,SSL层无法识别报文格式就会抛出该错误。

必要调整步骤

1. 修正RMI Registry创建逻辑

替换默认的明文Registry创建逻辑,手动指定和JMX服务匹配的SSL Socket工厂,开启双向认证:

// 构造SSL Socket工厂,复用系统属性配置的keystore/truststore,开启客户端认证
SslRMIServerSocketFactory serverSockFactory = new SslRMIServerSocketFactory(
    null,
    null,
    true // 对应原配置的com.sun.management.jmxremote.ssl.need.client.auth=true
);
SslRMIClientSocketFactory clientSockFactory = new SslRMIClientSocketFactory();

// 创建带SSL配置的RMI Registry
LocateRegistry.createRegistry(
    port,
    clientSockFactory,
    serverSockFactory
);

2. 同步JMX Connector环境配置

给JMX Connector的环境变量补充完整的Socket工厂配置,避免依赖全局系统属性的优先级问题:

env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverSockFactory);
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSockFactory);
// 直接在环境变量中配置认证规则,优先级高于全局系统属性
env.put("com.sun.management.jmxremote.ssl", "true");
env.put("com.sun.management.jmxremote.ssl.need.client.auth", "true");
env.put("com.sun.management.jmxremote.authenticate", "false");

3. 调整系统属性设置时机

所有System.setProperty配置keystore、truststore、TLS协议的代码,必须放在SSL Socket工厂实例化之前执行,否则SSL上下文初始化时会读取不到配置。

4. 清理无效配置

你代码中重复定义了两次boolean pwd_auth = false;,删除多余的定义即可;手动创建JMX Connector的场景下,com.sun.management.jmxremote.port、com.sun.management.jmxremote.rmi.port两个属性不需要设置,无实际作用。

完整可运行的服务端代码示例

boolean pwd_auth = false;
boolean ssl_auth = true;
String strPort = "9999";
int port = 9999;
Map<String,Object> env = new HashMap<>();

// 第一步:先设置所有SSL相关系统属性,必须在SocketFactory实例化前执行
System.setProperty("javax.net.ssl.keyStore", Config.keyStoreFile);
System.setProperty("javax.net.ssl.keyStorePassword", Config.keyStorePwd );
System.setProperty("javax.net.ssl.trustStore" , Config.trustStoreFile );
System.setProperty("javax.net.ssl.trustStorePassword" , Config.trustStorePwd);
System.setProperty("jdk.tls.server.protocols", Config.protocol);

// 第二步:构造SSL Socket工厂
SslRMIServerSocketFactory serverSockFactory = new SslRMIServerSocketFactory(
    null,
    null,
    ssl_auth
);
SslRMIClientSocketFactory clientSockFactory = new SslRMIClientSocketFactory();

// 第三步:创建带SSL的RMI Registry
LocateRegistry.createRegistry(
    port,
    clientSockFactory,
    serverSockFactory
);

// 第四步:配置JMX Connector环境参数
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverSockFactory);
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSockFactory);
env.put("com.sun.management.jmxremote.ssl", String.valueOf(ssl_auth));
env.put("com.sun.management.jmxremote.ssl.need.client.auth", String.valueOf(ssl_auth));
env.put("com.sun.management.jmxremote.authenticate", String.valueOf(pwd_auth));

// 第五步:启动JMX Connector Server
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
String strUrl = "service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi";
JMXServiceURL url = new JMXServiceURL(strUrl);
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
cs.start();

// 注册MBean
Hello mbean = new Hello();
ObjectName name = new ObjectName(Config.oname);
mbs.registerMBean(mbean, name);

内容的提问来源于stack exchange,提问作者shibendra chakraborty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:18:04