'docker-compose zookeeper kafka - ERROR cnxn.saslServer is null: cnxn object did not initialize its saslServer properly

I am trying to use docker-compose to spin up zk/kafka.

docker-compose.yml

version: '2'
services:
  zookeeper-1:
    image: confluentinc/cp-zookeeper:6.1.4
    environment:
      ZOOKEEPER_SERVER_ID: 1
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 10
      ZOOKEEPER_SYNC_LIMIT: 5
      ZOOKEEPER_DATADIR_AUTOCREATE: "false"
      ZOOKEEPER_MAX_CLIENT_CNXNS: 60
      ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT: 12
      ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL: 168
      ZOOKEEPER_ADMIN_ENABLE_SERVER: "false"
      ZOOKEEPER_SERVER_1: zookeeper-1:12881:13881
      ZOOKEEPER_AUTH_PROVIDER_1: org.apache.zookeeper.server.auth.SASLAuthenticationProvider
      ZOOKEEPER_REQUIRE_CLIENT_AUTH_SCHEME: sasl
      ZOOKEEPER_JAAS_LOGIN_RENEW: 3600000
      ZOOKEEPER_SECURE_CLIENT_PORT: 12181
      ZOOKEEPER_AUTH_PROVIDER_X509: org.apache.zookeeper.server.auth.X509AuthenticationProvider
      ZOOKEEPER_SERVER_CNXN_FACTORY: org.apache.zookeeper.server.NettyServerCnxnFactory
      ZOOKEEPER_SSL_PROTOCOL: TLSv1.2      
      ZOOKEEPER_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/truststore.jks
      ZOOKEEPER_SSL_TRUSTSTORE_PASSWORD: password
      ZOOKEEPER_SSL_KEYSTORE_LOCATION: /etc/kafka/secrets/zookeeper.server1.keystore.jks
      ZOOKEEPER_SSL_KEYSTORE_PASSWORD: password
      ZOOKEEPER_SSL_CLIENT_AUTH: none

      KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/secrets/zookeeper_jaas.conf"
    ports:
      - 12181:12181
    volumes:
      - /var/ssl:/etc/kafka/secrets

  kafka-1:
    image: confluentinc/cp-kafka:latest
    depends_on:
      - zookeeper-1
    ports:
      - 29092:9092
    volumes:
      - /var/ssl:/etc/kafka/secrets
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_LISTENERS: SASL_SSL://kafka-1:9092
      KAFKA_NUM_PARTITIONS: 4
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 2
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 2
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:12181
      KAFKA_ZOOKEEPER_CLIENT_CNXN_SOCKET: org.apache.zookeeper.ClientCnxnSocketNetty
      KAFKA_ZOOKEEPER_SSL_CLIENT_ENABLE: "true"
      KAFKA_ZOOKEEPER_SSL_PROTOCOL: TLSv1.2
      KAFKA_ZOOKEEPER_SSL_TRUSTSTORE_LOCATION: /etc/kafka/secrets/truststore.jks
      KAFKA_ZOOKEEPER_SSL_TRUSTSTORE_PASSWORD: password
      KAFKA_ZOOKEEPER_SET_ACL: "false"
      KAFKA_SECURITY_INTER_BROKER_PROTOCOL: SASL_SSL
      KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
      KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
      KAFKA_SSL_CLIENT_AUTH: none
      KAFKA_SSL_KEYSTORE_FILENAME: kafka.server1.keystore.jks
      KAFKA_SSL_KEYSTORE_CREDENTIALS: keystore_credentials
      KAFKA_SSL_KEY_CREDENTIALS: keystore_credentials
      KAFKA_SSL_TRUSTSTORE_FILENAME: truststore.jks
      KAFKA_SSL_TRUSTSTORE_CREDENTIALS: keystore_credentials
      KAFKA_SSL_ENABLED_PROTOCOLS: TLSv1.2
      
      KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/secrets/kafka_server_jaas.conf"

SSL/TLS

#!/usr/bin/env bash

export DIR=/var/ssl
export PASSWORD=password
export DNS=localhost

echo subjectAltName=DNS:$DNS,DNS:zookeeper-1,DNS:kafka-1 > openssl.cnf

openssl req -x509 -new -sha256 -newkey rsa:2048 -keyout CA.key -days 7300 -out CA.crt -subj "/CN=$DNS" -passout pass:$PASSWORD
keytool -keystore truststore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

openssl req -new -sha256 -newkey rsa:2048 -keyout zookeeper.server${instance}.key -subj "/CN=$DNS" -out zookeeper.server${instance}.csr -passout pass:$PASSWORD
openssl x509 -req -extfile openssl.cnf -in zookeeper.server${instance}.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out zookeeper.server${instance}.crt -days 7300 -sha256 -passin pass:$PASSWORD
openssl pkcs12 -export -in zookeeper.server${instance}.crt -inkey zookeeper.server${instance}.key -out zookeeper.server${instance}.p12 -name zookeeper.server${instance} -CAfile CA.crt -caname CA -passin pass:$PASSWORD -passout pass:$PASSWORD
keytool -importkeystore -deststorepass $PASSWORD -destkeypass $PASSWORD -destkeystore zookeeper.server${instance}.keystore.jks -srckeystore zookeeper.server${instance}.p12 -srcstoretype pkcs12 -srcstorepass $PASSWORD -alias zookeeper.server${instance}
keytool -keystore zookeeper.server${instance}.keystore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

openssl req -new -sha256 -newkey rsa:2048 -keyout kafka.server${instance}.key -subj "/CN=$DNS" -out kafka.server${instance}.csr -passout pass:$PASSWORD
openssl x509 -req -extfile openssl.cnf -in kafka.server${instance}.csr -CA CA.crt -CAkey CA.key -CAcreateserial -out kafka.server${instance}.crt -days 7300 -sha256 -passin pass:$PASSWORD
openssl pkcs12 -export -in kafka.server${instance}.crt -inkey kafka.server${instance}.key -out kafka.server${instance}.p12 -name kafka.server${instance} -CAfile CA.crt -caname CA -passin pass:$PASSWORD -passout pass:$PASSWORD
keytool -importkeystore -deststorepass $PASSWORD -destkeypass $PASSWORD -destkeystore kafka.server${instance}.keystore.jks -srckeystore kafka.server${instance}.p12 -srcstoretype pkcs12 -srcstorepass $PASSWORD -alias kafka.server${instance}
keytool -keystore kafka.server${instance}.keystore.jks -alias CA -importcert -file CA.crt -storepass $PASSWORD -noprompt

echo -n password > /var/ssl/keystore_credentials

kafka_server_jaas.conf

KafkaServer {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="kafka_broker_admin"
    password="password"
    user_kafka_broker_admin="password"
    user_zookeeper="password"
};

Client {
    org.apache.kafka.common.security.plain.PlainLoginModule required
    username="zookeeper"
    password="password";
};

zookeeper_jaas.conf

Server {
    org.apache.zookeeper.server.auth.DigestLoginModule required
    user_zookeeper="password";
};

Command

docker-compose up -d

ERROR

zookeeper-1_1 | [2022-01-17 12:30:34,845] INFO binding to port 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,886] INFO bound to port 2181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,893] INFO zookeeper.snapshotSizeFactor = 0.33 (org.apache.zookeeper.server.ZKDatabase)
zookeeper-1_1 | [2022-01-17 12:30:34,894] INFO Snapshotting: 0x0 to /var/lib/zookeeper/data/version-2/snapshot.0 (org.apache.zookeeper.server.persistence.FileTxnSnapLog)
zookeeper-1_1 | [2022-01-17 12:30:34,895] INFO Snapshotting: 0x0 to /var/lib/zookeeper/data/version-2/snapshot.0
(org.apache.zookeeper.server.persistence.FileTxnSnapLog) zookeeper-1_1 | [2022-01-17 12:30:34,901] INFO PrepRequestProcessor (sid:0) started, reconfigEnabled=false (org.apache.zookeeper.server.PrepRequestProcessor)
zookeeper-1_1 | [2022-01-17 12:30:34,903] INFO zookeeper.client.portUnification=false (org.apache.zookeeper.server.NettyServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,938] INFO Using org.apache.zookeeper.server.NettyServerCnxnFactory as server connection factory (org.apache.zookeeper.server.ServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,938] INFO binding to port 0.0.0.0/0.0.0.0:12181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,940] INFO bound to port 12181 (org.apache.zookeeper.server.NettyServerCnxnFactory)
zookeeper-1_1 | [2022-01-17 12:30:34,941] INFO Using checkIntervalMs=60000 maxPerMinute=10000 (org.apache.zookeeper.server.ContainerManager)
zookeeper-1_1 | [2022-01-17 12:30:38,480] INFO Creating new log file: log.1 (org.apache.zookeeper.server.persistence.FileTxnLog)
zookeeper-1_1 | [2022-01-17 12:30:38,493] ERROR cnxn.saslServer is null: cnxn object did not initialize its saslServer properly. (org.apache.zookeeper.server.ZooKeeperServer)

What am i configuring or doing wrong? Thanks.



Solution 1:[1]

After clarifying your needs, I found three things to fix:

  1. The value /etc/kafka/secrets/zookeeper.server1.keystore.jks should be /etc/kafka/secrets/zookeeper.server.keystore.jks as the TLS/SSL script generates that names.
  2. Same for the zookeeper keystore
  3. When starting it request an extra file named keystore_credentials. Just create it with password inside (your jks password)

I still have an issue but seems further the error you got:

io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: no cipher suites in common 

which seems more related to your SSL script

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1