Файлы свойств (конфигурации) SSL в агентах JMX и командной строке клиента JMX приводят к сбою клиента JMX с ошибкой "... Ошибка построения пути PKIX - PullRequest
0 голосов
/ 15 февраля 2020

Уже много таких вопросов по SO с ошибкой «... PKIX path path fail ...», но ни один из них не решил мою проблему. Я пытался в течение многих часов безуспешно. Проблема, с которой я сталкиваюсь, заключается в том, что клиент JMX выдает ошибку, когда информация о конфигурации SSL (хранилище ключей и его пароль) помещается в файлы свойств (файлы конфигурации), а имена файлов указываются в командной строке Java, используемой для клиента JMX и его сервера JMX ( агент) программы. Клиент работает нормально, если я напрямую предоставляю хранилище ключей и пароль в его командной строке. Использование файлов конфигурации очень ясно в соответствии с документацией JDK (management.properties), но, увы, у меня это не работает. Возможно, я что-то упустил.

Вот описание проблемы.

У меня есть простой агент JMX с методом приветствия, который вызывается клиентской программой JMX. Я включил SSL с хранилищем ключей и trustore, созданным с помощью самоподписанного сертификата.

Рабочий сценарий:

Агент (сервер) JMX вызывается с включенным SSL, хранилище ключей и его пароль следующим образом:

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 вызывается следующим образом:

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

Клиент подключается к серверу и успешно выполняет методы приветствия. Однако команды предоставляют пароли хранилищ ключей и доверенных сертификатов. Поэтому я хотел использовать файл конфигурации SSL, чтобы пароли не появлялись в командной строке Java.

Сценарий сбоя:

Файл конфигурации SSL сервера JMX (jmx_server_ssl.cfg):

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

Файл конфигурации SSL клиента JMX (jmx_client_ssl.cfg):

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

Запустил серверную программу следующим образом:

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

, и она работает как положено.

Вызванная клиентская программа выглядит следующим образом:

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

Этот вызов завершается с ошибкой:

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)

Причина: javax. net .ssl.SSLHandshakeException: sun. security.validator.ValidatorException: сбой построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификации для запрошенной цели в sun.security.ssl.Alerts.getSSLException (Alerts. java: 192) в sun.security.ssl.SSLSocketImpl.fatal (SSLSocketImpl. java: 1946) в sun.security.ssl.Handshaker.fatalSE (Handshaker. java: 316) в sun.security.ssl.Handshaker.fatalSE (Handshaker. java: 310) в sun.security.ssl.ClientHandshaker.serverCertificate (ClientHandshaker. java: 1639) в sun.security.ssl.ClientHandshaker.processMessage (ClientHandshaker. java: 223) в sun.security.ssl. Handshaker.processL oop (Handshaker. java: 1037) в sun.security.ssl.Handshaker.process_record (Handshaker. java: 965) в sun.security.ssl.SSLSocketImpl.readRecord (SSLSocketImpl. java 1064 запись (AppOutputStream. java: 123) в java .io.BufferedOutputStream.flushBuffer (BufferedOutputStream. java: 82) в java .io.BufferedOutputStream.flu sh (BufferedOutputStream. java: 140 ) в java .io.DataOutputStream.flu sh (DataOutputStream. java: 123) в sun.rmi.transport.tcp.TCPChannel.createConnection (TCPChannel. java: 229) ... еще 10 причин by: sun.security.validator.ValidatorException: построение пути PKIX ошибка: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификации для запрошенной цели в sun.security.validator.PKIXValidator.doBuild (PKIXValidator. java: 397) в sun.security.validator.PKIXValidator.engine. (PKIXValidator. java: 302) на sun.security.validator.Validator.validate (Validator. java: 262) на sun.security.ssl.X509TrustManagerImpl.validate (X509TrustManagerImpl. java: 330) на солнце. security.ssl.X509TrustManagerImpl.checkTrusted (X509TrustManagerImpl. java: 237) в sun.security.ssl.X509TrustManagerImpl. checkServerTrusted (X509TrustManagerImpl. java: 132) в sun.security.ssl.ClientHandshaker.serverCertificate (ClientHandshaker. java: 1621) ... еще 21 причина: sun.security.provider.certpath.SunCertPathBell действительный путь сертификации к запрошенной цели в sun.security.provider.certpath.SunCertPathBuilder.build (SunCertPathBuilder. java: 141) в sun.security.provider.certpath.SunCertPathBuilder.engineBuild (SunCertPathBuilder: * 126 * at 10) *. 1079 * .security.cert.CertPathBuilder.build (CertPathBuilder. java: 280) в sun.security.validator.PKIXValidator.doBuild (PKIXValidator. java: 392) ... еще 27

Вопрос Вот почему происходит сбой, когда информация о конфигурации SSL (хранилище ключей и пароли) хранится в файлах и передается имена файлов в качестве аргументов в команду Java?

К вашему сведению, я намеренно отключил аутентификацию по паролю, чтобы уменьшить мою проблему с минимальными настройками .

Примечание: - Пока я пишу эту проблему, я обнаружил, что клиент, если он вызван Информация о конфигурации ssl в командной строке работает с сервером, вызываемым из файла конфигурации. Но это не совсем идеально для моих требований.

...