Linuxea
Linuxea

Reputation: 329

Kafka server SSL configuration exception

this is one part of my Kafka server.properties configurations:

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

throw an SSL exception: when I start up the server

[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

I even not to try to start the client.Actually, I don't know too much about security of kafka, I just configure according to the kafka document. What should I do next step ?

thanks sincerely!

Upvotes: 12

Views: 73801

Answers (6)

balatamilmani
balatamilmani

Reputation: 141

In my case, I got this error on the Client's side. Installing Client's CA Certificate in the Server's truststore solved the problem.

Setup:

  • There are two CAs involved, CA-1 and CA-2
  • CA-1 signed Server's Certificate
  • CA-1's Certificate is installed in 1. Server's keystore, 2. Server's truststore, 3. Client's truststore
  • CA-2 signed Client's Certificate
  • CA-2's Certificate is installed in Client's keystore
  • CA-2's Certificate is installed in Server's truststore (this solved the problem, the Kafka Server restarted after this step)

Upvotes: 0

Dorjee Dhondup
Dorjee Dhondup

Reputation: 649

For anyone still looking for a solution on macOS, this worked for me. Replace [server-name] and [server-port] with your own.

Open up Terminal and run these two commands.

Download the provided certificate from the remote server

openssl x509 -in <(openssl s_client -connect [server-name]:[server-port] -prexit 2>/dev/null) -out ~/[server-name].crt

Import cert to Java keystore

sudo keytool -importcert -file ~/[server-name].crt -alias [server-name] -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

Then restart your application to see the cert errors go away

Upvotes: 2

Brandon Laux
Brandon Laux

Reputation: 1

I needed to export the cert from the truststore.jks and import the cert into my 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

Upvotes: 0

Abhijeet Padwal
Abhijeet Padwal

Reputation: 193

With the properties you have set, the server is going to start in one way SSL mode, to enable two way SSL you have to add ssl.client.auth=required

In latest version of kafka server the Hostname validation is enabled in order to prevent man in the middle attacks, and set to HTTPS by default. You can disable hostname validation by setting:

ssl.endpoint.identification.algorithm=

If you have only one broker then try removing security.inter.broker.protocol=SSL just setting the above string empty will probably solve the problem

Upvotes: 11

asolanki
asolanki

Reputation: 1373

You need to specify the below setting to secure Kafka cluster

 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

The server certificate should be in the trust store.

Upvotes: 2

Jakub
Jakub

Reputation: 4006

You use SSL for inter-broker communication. When the brokers connect and talk to each other they act as clients.

When the brokers connect and do the handshake, the client (= the broker which is opening connection) needs to verify the identity of the server (= the broker which is accepting the connection). The exception you have is basically saying that this failed in your case.

This has to be done using a truststore. You need to create a truststore which should contain either the public key of the CA you used to sign the broker certificates or the public keys of all broker certificates in case you used self-signed certificates. And then specify ssl.truststore.location and ssl.truststore.password options in your broker config file. That should help.

Upvotes: 8

Related Questions