SSL property(configuration) files on a JMX agent and JMX client command lines make the JMX client fail with error "… PKIX path building failed

若如初见. 提交于 2020-03-05 00:27:20

问题


There are already many such questions on SO with error "...PKIX path building failed...", but none of them addressed my problem. I tried for many hours without success. Problem I am facing is JMX client throws error when SSL configuration information(keystore and its password) is put in property files (configuration files) and the file names are supplied on Java command line used for the JMX client and its JMX server(agent) programs. The client works fine if I directly supply the keystore and password on its command line. Usage of configuration files is very clear as per JDK documentation (management.properties) but, alas, it does not work for me. Probably I am missing something.

Here is the problem description.

I have a simple JMX agent with a hello method that is called by JMX client program. I have enabled SSL with keystore and trustore created with a self signed certificate.

Working scenario:

The JMX agent(server) is invoked with SSL enabled, keystore and its password as following:

java -Dcom.sun.management.jmxremote.port=9999 \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=true \
    -Dcom.sun.management.jmxremote.registry.ssl=false \
    -Dcom.sun.management.jmxremote.ssl.need.client.auth=false \
    -Djavax.net.ssl.keyStore=${PROJ_HOME}/keystore.jks \
    -Djavax.net.ssl.keyStorePassword=keystore123 \
    com.example.server.JMXServer

JMX client is invoked as following:

 java  -Djavax.net.ssl.trustStore=${PROJ_HOME}/truststore.jks \
-Djavax.net.ssl.trustStorePassword=truststore123 \
com.example.client.JMXClient

The client connects to the server and executes a hello methods successfully. However, the commands expose keystore and truststore passwords. Therefore I wanted to use SSL configuration file to make passwords not appear on Java command lines.

Failing scenario:

JMX server SSL configuration file (jmx_server_ssl.cfg):

javax.net.ssl.keyStore=/mnt/vol3/projects/eclipse_ws_monitor/TestJMXSSLCfg/keystore.jks
javax.net.ssl.keyStorePassword=keystore123

JMX client SSL configuration file (jmx_client_ssl.cfg):

javax.net.ssl.trustStore=/mnt/vol3/projects/eclipse_ws_monitor/TestJMXSSLCfg/truststore.jks 
javax.net.ssl.trustStorePassword=truststore123e

Invoked the server program as following:

java -Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.authenticate=false \
    -Dcom.sun.management.jmxremote.ssl=true \
-Dcom.sun.management.jmxremote.registry.ssl=false \
-Dcom.sun.management.jmxremote.ssl.need.client.auth=false \
-Dcom.sun.management.jmxremote.ssl.config.file=${PROJ_HOME}/jmx_server_ssl.cfg \
com.example.server.JMXServer

and it works as expected.

Invoked client program as following:

java  -Dcom.sun.management.jmxremote.ssl.config.file=jmx_client_ssl.cfg \
    com.example.client.JMXClient

This invocation fails with the following error:

java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:307)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.newClient(Unknown Source)
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2430)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:308)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:229)
at com.example.client.JMXClient.main(JMXClient.java:18)

Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037) at sun.security.ssl.Handshaker.process_record(Handshaker.java:965) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:750) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at java.io.DataOutputStream.flush(DataOutputStream.java:123) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:229) ... 10 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302) at sun.security.validator.Validator.validate(Validator.java:262) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:330) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:237) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621) ... 21 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392) ... 27 more

Question is why this fails when SSL configuration information (keystore and passwords) is kept in files and passed the file names as arguments to Java command?

FYI, I disabled password authentication purposefully to reduce my problem with minimum setup.

Note:- While I am writing this issue, I have found that client if invoked with ssl configuration information on command line works with server invoked with configuration file. But this is less than perfect for my requirements.

来源:https://stackoverflow.com/questions/60239005/ssl-propertyconfiguration-files-on-a-jmx-agent-and-jmx-client-command-lines-ma

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!