问题
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