0

So I have been trying to setup kafka broker and zookeeper on a single node with kerberos enabled.

Most of it is based on this tutorial : https://qiita.com/visualskyrim/items/8f48ff107232f0befa5a

System : Ubuntu 18.04 Setup : A zoopeeker instance and a kafka broker process in one EC2 box, A KDC in another EC2 box. Both on the same security group with open ports on UDP 88.

Here is what I have done so far.

  1. Downloaded the kafka broker from here : https://kafka.apache.org/downloads
  2. Created a KDC and correctly generated keytab (verified via kinit -t). Then defined krb5_config file and host entries to the kdc in /etc/hosts file.
  3. Created two jaas configs

cat zookeeper_jaas.conf

Server {
  com.sun.security.auth.module.Krb5LoginModule required debug=true
  useKeyTab=true
  keyTab="/etc/kafka/zookeeper.keytab"
  storeKey=true
  useTicketCache=false
  principal="zookeeper";
};

cat kafka_jaas.conf

cat /etc/kafka/kafka_jaas.conf
KafkaServer {
  com.sun.security.auth.module.Krb5LoginModule required debug=true
  useKeyTab=true
  useTicketCache=false
  storeKey=true
  keyTab="/etc/kafka/kafka.keytab"
  principal="kafka";
};

Client {
  com.sun.security.auth.module.Krb5LoginModule required debug=true
  useKeyTab=true
  storeKey=true
  useTicketCache=false
  keyTab="/etc/kafka/kafka.keytab"
  principal="kafka";
};
  1. Added some lines in the kafka broker config.

The config/zookeeper file has these extra lines added

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000
kerberos.removeHostFromPrincipal=true
kerberos.removeRealmFromPrincipal=true

and config/server.properties (config file for broker) has these extra lines added

listeners=SASL_PLAINTEXT://kafka.com:9092
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.enabled.mechanism=GSSAPI
sasl.kerberos.service.name=kafka

In one screen session, I do

5. export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf -Dsun.security.krb5.debug=true"

and then run

bin/zookeeper-server-start.sh config/zookeeper.properties

And this correctly runs, and zookeeper starts up.

In another screen session I do

6. export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/etc/kafka/kafka_jaas.conf -Dsun.security.krb5.debug=true"

and then run

bin/kafka-server-start.sh config/server.properties

But this one fails, with this exception

[2020-02-27 22:56:04,724] ERROR SASL authentication failed using login context 'Client' with 
exception: {} (org.apache.zookeeper.client.ZooKeeperSaslClient)
javax.security.sasl.SaslException: Error in authenticating with a Zookeeper Quorum member: 
the quorum member's saslToken is null.
        at org.apache.zookeeper.client.ZooKeeperSaslClient.createSaslToken(ZooKeeperSaslClient.java:279)
    at org.apache.zookeeper.client.ZooKeeperSaslClient.respondToServer(ZooKeeperSaslClient.java:242)
    at org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:805)
    at org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:94)
    at org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:366)
    at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1141)
[2020-02-27 22:56:04,726] ERROR [ZooKeeperClient Kafka server] Auth failed. 
(kafka.zookeeper.ZooKeeperClient)
[2020-02-27 22:56:04,842] ERROR Fatal error during KafkaServer startup. Prepare to shutdown 
(kafka.server.KafkaServer)
org.apache.zookeeper.KeeperException$AuthFailedException: KeeperErrorCode = AuthFailed for 
/consumers
    at org.apache.zookeeper.KeeperException.create(KeeperException.java:126)
    at org.apache.zookeeper.KeeperException.create(KeeperException.java:54)
    at kafka.zookeeper.AsyncResponse.maybeThrow(ZooKeeperClient.scala:560)
    at kafka.zk.KafkaZkClient.createRecursive(KafkaZkClient.scala:1610)
    at kafka.zk.KafkaZkClient.makeSurePersistentPathExists(KafkaZkClient.scala:1532)
    at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1(KafkaZkClient.scala:1524)
    at kafka.zk.KafkaZkClient.$anonfun$createTopLevelPaths$1$adapted(KafkaZkClient.scala:1524)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at kafka.zk.KafkaZkClient.createTopLevelPaths(KafkaZkClient.scala:1524)
    at kafka.server.KafkaServer.initZkClient(KafkaServer.scala:388)
    at kafka.server.KafkaServer.startup(KafkaServer.scala:207)
    at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:38)
    at kafka.Kafka$.main(Kafka.scala:84)
    at kafka.Kafka.main(Kafka.scala)

I also enabled the kerberos debug logs

This was the credentials log for kerberos

DEBUG: ----Credentials----
client: kafka@VISUALSKYRIM
server: zookeeper/localhost@VISUALSKYRIM
ticket: sname: zookeeper/localhost@VISUALSKYRIM
endTime: 1582881662000
----Credentials end----

This implies the Client jaas config is somehow an issue and the issue arises from this Line of Code : https://github.com/apache/zookeeper/blob/master/zookeeper-server/src/main/java/org/apache/zookeeper/client/ZooKeeperSaslClient.java#L310, but I cannot for the life of me figure out why. I cross referenced it with confluent docs and https://docs.confluent.io/2.0.0/kafka/sasl.html and it seems I am doing the right thing. So what gives?

Can anyone help me out with this? Thanks.

Arunav Sanyal
  • 1,708
  • 1
  • 16
  • 36

2 Answers2

0

Well turns out kafka implicitly believes zookeeper's principal is

zookeeper/localhost

In order to make progress I

  1. Created zookeeper/localhost principal in KDC.
  2. Created a keytab for this called zookeeper-server.keyta
  3. Updated the zookeeper jaas config to be

    Server { com.sun.security.auth.module.Krb5LoginModule required debug=true useKeyTab=true keyTab="/etc/kafka/zookeeper-server.keytab" storeKey=true useTicketCache=false principal="zookeeper/localhost"; };

Which now no longer shows this error.

The kafka producer seems to be picking up the SPNs based on my /etc/hosts config

# Replace there keberos KDC server IP with the appropriate IP addresses
172.31.40.220 kerberos.com
127.0.0.1 localhost
Arunav Sanyal
  • 1,708
  • 1
  • 16
  • 36
0

Maybe try to look at KAFKA_HOME/config/server.properties and change default localhost to your-host in zookeeper.connect=localhost:2181

as principal cname was not the same as sname. example:

cname zk/myhost@REALM.MY
sname zookeeper/localhost@REALM.MY

I also ended up using EXTRA_ARGS option -Dzookeeper.sasl.client.username=zk as stated in docs.

Worked for me. Seems like code 1, 2 which should take care of this is ignoring it and uses this property instead.

michalxo
  • 91
  • 1
  • 3