这是我的 Kafka 服务器的一部分。属性配置:
listeners=SSL://192.168.78.131:9092
ssl.keystore.location=/home/linuxea/encr/server.keystore.jks
ssl.keystore.password=linuxea
ssl.key.password=linuxea
security.inter.broker.protocol=SSL
抛出 SSL 异常:当我启动服务器时
[2018-04-18 02:05:32,229] ERROR [Controller id=0, targetBrokerId=0] Connection to node 0 failed authentication due to: SSL handshake failed (org.apache.kafka.clients.NetworkClient)\
[2018-04-18 02:05:32,245] ERROR [KafkaServer id=0] Connection to node 0 failed authentication due to: SSL handshake failed (org.apache.kafka.clients.NetworkClient)
[2018-04-18 02:05:32,246] WARN SSL handshake failed (kafka.utils.CoreUtils$)
org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1529)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214)
at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186)
at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469)
at org.apache.kafka.common.network.SslTransportLayer.handshakeWrap(SslTransportLayer.java:434)
at org.apache.kafka.common.network.SslTransportLayer.doHandshake(SslTransportLayer.java:299)
at org.apache.kafka.common.network.SslTransportLayer.handshake(SslTransportLayer.java:253)
at org.apache.kafka.common.network.KafkaChannel.prepare(KafkaChannel.java:79)
at org.apache.kafka.common.network.Selector.pollSelectionKeys(Selector.java:486)
at org.apache.kafka.common.network.Selector.poll(Selector.java:424)
at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:460)
at org.apache.kafka.clients.NetworkClientUtils.awaitReady(NetworkClientUtils.java:73)
at kafka.server.KafkaServer.doControlledShutdown$1(KafkaServer.scala:485)
at kafka.server.KafkaServer.kafka$server$KafkaServer$$controlledShutdown(KafkaServer.scala:534)
at kafka.server.KafkaServer$$anonfun$shutdown$1.apply$mcV$sp(KafkaServer.scala:556)
at kafka.utils.CoreUtils$.swallow(CoreUtils.scala:85)
at kafka.server.KafkaServer.shutdown(KafkaServer.scala:556)
at kafka.server.KafkaServerStartable.shutdown(KafkaServerStartable.scala:48)
at kafka.Kafka$$anon$1.run(Kafka.scala:89)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:330)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:992)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:989)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1467)
at org.apache.kafka.common.network.SslTransportLayer.runDelegatedTasks(SslTransportLayer.java:388)
at org.apache.kafka.common.network.SslTransportLayer.handshakeUnwrap(SslTransportLayer.java:468)
at org.apache.kafka.common.network.SslTransportLayer.doHandshake(SslTransportLayer.java:326)
... 13 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:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:281)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1601)
... 22 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)
... 28 more
我什至没有尝试启动客户端。其实我对kafka的安全性不太了解,只是按照kafka文档进行配置。 下一步我应该做什么?
真诚的感谢!
根据您设置的属性,服务器将以单向 SSL 模式启动,要启用双向 SSL,您必须添加
ssl.client.auth=required
在最新版本的kafka服务器中,启用了主机名验证以防止中间人攻击,并默认设置为HTTPS。 您可以通过设置禁用主机名验证:
ssl.endpoint.identification.algorithm=
如果您只有一名经纪人,请尝试删除
security.inter.broker.protocol=SSL
只需将上面的字符串设置为空可能就能解决问题
您使用 SSL 进行经纪商间通信。当经纪人相互联系并交谈时,他们就充当客户。
当代理连接并握手时,客户端(=正在打开连接的代理)需要验证服务器(=正在接受连接的代理)的身份。您遇到的例外基本上是说这在您的案例中失败了。
这必须使用信任库来完成。您需要创建一个信任库,其中应包含用于签署代理证书的 CA 的公钥或所有代理证书的公钥(如果您使用自签名证书)。然后在代理配置文件中指定
ssl.truststore.location
和 ssl.truststore.password
选项。这应该有帮助。
您需要指定以下设置来保护 Kafka 集群
listeners=PLAINTEXT://:9092,SSl://:9093
ssl.client.auth=required
ssl.keystore.location=/path/to/server.keystore
ssl.keystore.password=<Key store password>
ssl.key.password = <private key password>
ssl.truststore.location=/path/to/truststore.keystore
ssl.truststore.password=<trust store password>
security.inter.broker.protocol=SSL
服务器证书应位于信任存储区中。
对于仍在 macOS 上寻找解决方案的人来说,这对我有用。将 [服务器名称] 和 [服务器端口] 替换为您自己的。
打开终端并运行这两个命令。
openssl x509 -in <(openssl s_client -connect [server-name]:[server-port] -prexit 2>/dev/null) -out ~/[server-name].crt
sudo keytool -importcert -file ~/[server-name].crt -alias [server-name] -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
然后重新启动您的应用程序即可看到证书错误消失
我需要从 truststore.jks 导出证书并将证书导入到我的 JAVA_HOME cacerts 中。
# To check the content of the keystore:
keytool -list -v -keystore <your_keystore>.jks
#Export certificate into .cer file
keytool -exportcert -alias <your_alias> -keystore <your_keystore>.jks -file <whatever_you_want_to_call_it>.cer
# Install certificate into Java JDK CA Certificate key store path
# to avoid giving certificate path in the client program.
keytool -import -alias <your_alias> -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file <whatever_you_called_it_above>.cer
# List certificates stored in JDK Key store which you have just now imported into JDK Security path.
keytool -list -keystore "%JAVA_HOME%\jre\lib\security\cacerts
就我而言,在服务器的信任库中安装客户端的 CA 证书解决了问题。
设置:
- 涉及两个 CA,CA-1 和 CA-2
- CA-1 签署的服务器证书
- CA-1 的证书安装在 1. 服务器的密钥库、2. 服务器的信任库、3. 客户端的信任库中
- CA-2 签署客户证书
- CA-2 的证书安装在客户端的密钥库中
- CA-2的证书安装在服务器的信任库中(这解决了问题,Kafka服务器在这一步后重新启动)