Kafka Encryption
TLS encryption protects data in transit between Kafka clients and brokers, and between brokers themselves.
Encryption Overview
Section titled “Encryption Overview”TLS Configuration
Section titled “TLS Configuration”Broker Configuration
Section titled “Broker Configuration”# SSL listenerlisteners=SSL://0.0.0.0:9093advertised.listeners=SSL://kafka1.example.com:9093
# Inter-broker encryptionsecurity.inter.broker.protocol=SSL
# Keystore (broker identity)ssl.keystore.location=/etc/kafka/ssl/kafka.keystore.jksssl.keystore.password=keystore-passwordssl.key.password=key-passwordssl.keystore.type=JKS
# Truststore (trusted CAs)ssl.truststore.location=/etc/kafka/ssl/kafka.truststore.jksssl.truststore.password=truststore-passwordssl.truststore.type=JKS
# Require client certificates (mTLS)ssl.client.auth=required
# Protocol versionsssl.enabled.protocols=TLSv1.3,TLSv1.2
# Cipher suites (TLS 1.3)ssl.cipher.suites=TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256Client Configuration
Section titled “Client Configuration”security.protocol=SSL
# Truststore (to verify broker)ssl.truststore.location=/etc/kafka/ssl/client.truststore.jksssl.truststore.password=truststore-password
# Keystore (client identity for mTLS)ssl.keystore.location=/etc/kafka/ssl/client.keystore.jksssl.keystore.password=keystore-passwordssl.key.password=key-password
# Protocol versionsssl.enabled.protocols=TLSv1.3,TLSv1.2Certificate Generation
Section titled “Certificate Generation”Create Certificate Authority
Section titled “Create Certificate Authority”# Generate CA private key and certificateopenssl req -new -x509 \ -keyout ca-key.pem \ -out ca-cert.pem \ -days 365 \ -subj "/CN=Kafka-CA/O=Organization/C=US" \ -nodes
# Create truststore with CA certificatekeytool -keystore kafka.truststore.jks \ -alias CARoot \ -import \ -file ca-cert.pem \ -storepass changeit \ -nopromptGenerate Broker Certificates
Section titled “Generate Broker Certificates”#!/bin/bashBROKER_HOST=$1VALIDITY=365STOREPASS=changeit
# Generate keystore with key pairkeytool -keystore ${BROKER_HOST}.keystore.jks \ -alias ${BROKER_HOST} \ -validity ${VALIDITY} \ -genkey \ -keyalg RSA \ -keysize 2048 \ -storepass ${STOREPASS} \ -keypass ${STOREPASS} \ -dname "CN=${BROKER_HOST},O=Organization,C=US" \ -ext "SAN=DNS:${BROKER_HOST},DNS:localhost"
# Create certificate signing requestkeytool -keystore ${BROKER_HOST}.keystore.jks \ -alias ${BROKER_HOST} \ -certreq \ -file ${BROKER_HOST}.csr \ -storepass ${STOREPASS}
# Sign certificate with CAopenssl x509 -req \ -CA ca-cert.pem \ -CAkey ca-key.pem \ -in ${BROKER_HOST}.csr \ -out ${BROKER_HOST}-signed.crt \ -days ${VALIDITY} \ -CAcreateserial \ -extfile <(printf "subjectAltName=DNS:${BROKER_HOST},DNS:localhost")
# Import CA certificate into keystorekeytool -keystore ${BROKER_HOST}.keystore.jks \ -alias CARoot \ -import \ -file ca-cert.pem \ -storepass ${STOREPASS} \ -noprompt
# Import signed certificate into keystorekeytool -keystore ${BROKER_HOST}.keystore.jks \ -alias ${BROKER_HOST} \ -import \ -file ${BROKER_HOST}-signed.crt \ -storepass ${STOREPASS}Generate Client Certificates
Section titled “Generate Client Certificates”#!/bin/bashCLIENT_NAME=$1VALIDITY=365STOREPASS=changeit
# Generate keystorekeytool -keystore ${CLIENT_NAME}.keystore.jks \ -alias ${CLIENT_NAME} \ -validity ${VALIDITY} \ -genkey \ -keyalg RSA \ -keysize 2048 \ -storepass ${STOREPASS} \ -keypass ${STOREPASS} \ -dname "CN=${CLIENT_NAME},O=Organization,C=US"
# Create CSRkeytool -keystore ${CLIENT_NAME}.keystore.jks \ -alias ${CLIENT_NAME} \ -certreq \ -file ${CLIENT_NAME}.csr \ -storepass ${STOREPASS}
# Sign with CAopenssl x509 -req \ -CA ca-cert.pem \ -CAkey ca-key.pem \ -in ${CLIENT_NAME}.csr \ -out ${CLIENT_NAME}-signed.crt \ -days ${VALIDITY} \ -CAcreateserial
# Import CA certkeytool -keystore ${CLIENT_NAME}.keystore.jks \ -alias CARoot \ -import \ -file ca-cert.pem \ -storepass ${STOREPASS} \ -noprompt
# Import signed certkeytool -keystore ${CLIENT_NAME}.keystore.jks \ -alias ${CLIENT_NAME} \ -import \ -file ${CLIENT_NAME}-signed.crt \ -storepass ${STOREPASS}
# Create truststore for clientcp kafka.truststore.jks ${CLIENT_NAME}.truststore.jksPEM Format (Alternative)
Section titled “PEM Format (Alternative)”For environments preferring PEM over JKS format.
Broker Configuration with PEM
Section titled “Broker Configuration with PEM”# PEM format certificatesssl.keystore.type=PEMssl.keystore.certificate.chain=/etc/kafka/ssl/kafka-chain.pemssl.keystore.key=/etc/kafka/ssl/kafka-key.pem
ssl.truststore.type=PEMssl.truststore.certificates=/etc/kafka/ssl/ca-cert.pemConvert JKS to PEM
Section titled “Convert JKS to PEM”# Export private keykeytool -importkeystore \ -srckeystore kafka.keystore.jks \ -destkeystore kafka.p12 \ -deststoretype PKCS12 \ -srcstorepass changeit \ -deststorepass changeit
openssl pkcs12 \ -in kafka.p12 \ -nocerts \ -nodes \ -out kafka-key.pem \ -passin pass:changeit
# Export certificate chainopenssl pkcs12 \ -in kafka.p12 \ -nokeys \ -out kafka-chain.pem \ -passin pass:changeitMultiple Listeners
Section titled “Multiple Listeners”Configure different security protocols per listener.
# Multiple listeners with different protocolslisteners=PLAINTEXT://0.0.0.0:9092,SSL://0.0.0.0:9093,SASL_SSL://0.0.0.0:9094advertised.listeners=PLAINTEXT://kafka1:9092,SSL://kafka1:9093,SASL_SSL://kafka1:9094
# Map listener names to protocolslistener.security.protocol.map=PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_SSL:SASL_SSL
# Inter-broker uses SSLinter.broker.listener.name=SSLsecurity.inter.broker.protocol=SSLTLS Versions and Cipher Suites
Section titled “TLS Versions and Cipher Suites”Recommended Configuration
Section titled “Recommended Configuration”| Setting | Recommended Value |
|---|---|
ssl.enabled.protocols | TLSv1.3,TLSv1.2 |
ssl.protocol | TLSv1.3 |
TLS 1.3 Cipher Suites
Section titled “TLS 1.3 Cipher Suites”ssl.cipher.suites=TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256TLS 1.2 Cipher Suites (if TLS 1.3 not available)
Section titled “TLS 1.2 Cipher Suites (if TLS 1.3 not available)”ssl.cipher.suites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256Deprecated Protocols
TLS 1.0 and TLS 1.1 must not be used in production. These protocols have known vulnerabilities.
Hostname Verification
Section titled “Hostname Verification”Enable Verification
Section titled “Enable Verification”# Broker (for inter-broker)ssl.endpoint.identification.algorithm=HTTPS
# Clientssl.endpoint.identification.algorithm=HTTPSCertificate SAN Requirements
Section titled “Certificate SAN Requirements”When hostname verification is enabled, certificates must include Subject Alternative Names (SANs) matching the broker hostnames.
# Generate cert with SANkeytool -keystore kafka.keystore.jks \ -alias kafka \ -genkey \ -keyalg RSA \ -dname "CN=kafka.example.com" \ -ext "SAN=DNS:kafka1.example.com,DNS:kafka2.example.com,DNS:kafka3.example.com"Certificate Rotation
Section titled “Certificate Rotation”Zero-Downtime Rotation
Section titled “Zero-Downtime Rotation”- Add new CA to truststores (before old CA expires):
# Add new CA to existing truststorekeytool -keystore kafka.truststore.jks \ -alias NewCARoot \ -import \ -file new-ca-cert.pem \ -storepass changeit \ -noprompt-
Deploy updated truststores to all brokers and clients
-
Generate new certificates signed by new CA
-
Update keystores with new certificates
-
Remove old CA from truststores after transition period
Dynamic Configuration Update
Section titled “Dynamic Configuration Update”Kafka 2.7+ supports dynamic SSL configuration updates without restart.
# Update broker SSL config dynamicallykafka-configs.sh --bootstrap-server kafka:9093 \ --entity-type brokers \ --entity-name 1 \ --alter \ --add-config 'ssl.keystore.location=/etc/kafka/ssl/new-kafka.keystore.jks'Client Code Examples
Section titled “Client Code Examples”Java Producer with TLS
Section titled “Java Producer with TLS”Properties props = new Properties();props.put("bootstrap.servers", "kafka:9093");props.put("security.protocol", "SSL");props.put("ssl.truststore.location", "/path/to/truststore.jks");props.put("ssl.truststore.password", "truststore-password");props.put("ssl.keystore.location", "/path/to/keystore.jks");props.put("ssl.keystore.password", "keystore-password");props.put("ssl.key.password", "key-password");props.put("ssl.endpoint.identification.algorithm", "HTTPS");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);Python Consumer with TLS
Section titled “Python Consumer with TLS”from kafka import KafkaConsumer
consumer = KafkaConsumer( 'my-topic', bootstrap_servers=['kafka:9093'], security_protocol='SSL', ssl_cafile='/path/to/ca-cert.pem', ssl_certfile='/path/to/client-cert.pem', ssl_keyfile='/path/to/client-key.pem', ssl_check_hostname=True)Troubleshooting
Section titled “Troubleshooting”Common Errors
Section titled “Common Errors”| Error | Cause | Solution |
|---|---|---|
SSL handshake failed | Certificate mismatch | Verify truststore contains CA |
No subject alternative names | Missing SAN | Regenerate cert with SAN extension |
Certificate expired | Expired certificate | Rotate certificates |
Unable to find valid certification path | Missing CA in truststore | Import CA to truststore |
Debug SSL
Section titled “Debug SSL”# Enable SSL debug loggingexport KAFKA_OPTS="-Djavax.net.debug=ssl:handshake"
# Test SSL connectionopenssl s_client -connect kafka:9093 -CAfile ca-cert.pemVerify Certificate
Section titled “Verify Certificate”# View keystore contentskeytool -list -v -keystore kafka.keystore.jks -storepass changeit
# Check certificate expirationkeytool -list -v -keystore kafka.keystore.jks -storepass changeit | grep "Valid from"
# Verify certificate chainopenssl verify -CAfile ca-cert.pem kafka-signed.crtRelated Documentation
Section titled “Related Documentation”- Security Overview - Security concepts
- Authentication - Authentication mechanisms
- Authorization - ACL configuration