You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kafka Python SSL配置报错:主机名不匹配,证书无效求助

问题分析与解决方案

核心问题

出现Hostname mismatch错误的根本原因:

  1. Kafka服务器证书的主机名(CN/SAN)未包含客户端连接时使用的kafka-1主机名
  2. Kafka内部通信监听器配置冲突
  3. Python客户端误用了CA证书而非专属客户端证书

具体修正步骤

1. 修正Kafka配置

修改docker-compose-kafka.env文件:

  • 移除KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181(与docker-compose中zookeeper:32181的配置冲突,以docker-compose设置为准)
  • 将KAFKA_INTER_BROKER_LISTENER_NAME=EXTERNAL改为KAFKA_INTER_BROKER_LISTENER_NAME=INTERNAL(内部broker通信使用PLAINTEXT协议的INTERNAL监听器,避免不必要的SSL握手问题)
  • (可选)将KAFKA_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM=改为KAFKA_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM=HTTPS,确保主机名验证机制生效

确认docker-compose.yml监听器逻辑:

当前KAFKA_ADVERTISED_LISTENERS配置合理,对应两种访问场景:

  • INTERNAL://kafka-1:29092:Docker网络内的PLAINTEXT协议访问
  • EXTERNAL://localhost:9092:宿主机外部的SSL协议访问
    若需要Docker内客户端也用SSL访问,可新增SSL监听端口:
KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka-1:29092,EXTERNAL://localhost:9092,INTERNAL_SSL://kafka-1:9093
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:SSL,INTERNAL_SSL:SSL

后续py-app客户端可连接kafka-1:9093

2. 重新生成包含正确主机名的Kafka服务器证书

服务器证书需同时支持kafka-1和localhost两个主机名,覆盖Docker内部与外部访问场景:

  1. 创建证书配置文件server-cert.cnf:
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
CN = kafka-1

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = kafka-1
DNS.2 = localhost
  1. 重新生成服务器密钥库与证书请求:
# 删除旧密钥库(若存在)
rm kafka.server.keystore.jks

# 生成服务器密钥库
keytool -keystore kafka.server.keystore.jks -alias kafka-1 -keyalg RSA -validity 365 -genkey -storepass 123456 -keypass 123456 -dname "CN=kafka-1, OU=Dev, O=Example, L=City, ST=State, C=CN"

# 生成带SAN扩展的证书请求
keytool -keystore kafka.server.keystore.jks -alias kafka-1 -certreq -file cert-file -storepass 123456 -keypass 123456 -ext SAN=dns:kafka-1,dns:localhost
  1. 用CA签名证书请求:
openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days 365 -CAcreateserial -passin pass:123456 -extfile server-cert.cnf -extensions v3_req
  1. 导入CA证书与签名后的证书到服务器密钥库:
keytool -keystore kafka.server.keystore.jks -alias CARoot -importcert -file ca-cert -storepass 123456 -noprompt
keytool -keystore kafka.server.keystore.jks -alias kafka-1 -importcert -file cert-signed -storepass 123456 -noprompt
  1. 重新导出CA的PEM文件(若需要):
keytool -exportcert -alias CARoot -keystore kafka.server.keystore.jks -rfc -file CARoot.pem -storepass 123456

3. 生成Python客户端双向认证证书

因Kafka配置了KAFKA_SSL_CLIENT_AUTH=required,客户端必须提供专属证书:

  1. 生成客户端密钥库:
keytool -keystore kafka.client.keystore.jks -alias kafka-client -keyalg RSA -validity 365 -genkey -storepass 123456 -keypass 123456 -dname "CN=kafka-client, OU=Dev, O=Example, L=City, ST=State, C=CN"
  1. 生成客户端证书请求并签名:
keytool -keystore kafka.client.keystore.jks -alias kafka-client -certreq -file client-cert-file -storepass 123456 -keypass 123456
openssl x509 -req -CA ca-cert -CAkey ca-key -in client-cert-file -out client-cert-signed -days 365 -CAcreateserial -passin pass:123456
  1. 导入CA证书与签名后的客户端证书到客户端密钥库:
keytool -keystore kafka.client.keystore.jks -alias CARoot -importcert -file ca-cert -storepass 123456 -noprompt
keytool -keystore kafka.client.keystore.jks -alias kafka-client -importcert -file client-cert-signed -storepass 123456 -noprompt
  1. 导出客户端证书与密钥为PEM格式(适配Python Kafka库要求):
# 导出客户端证书
keytool -exportcert -alias kafka-client -keystore kafka.client.keystore.jks -rfc -file client-cert.pem -storepass 123456

# 导出客户端密钥并转换为PEM
keytool -importkeystore -srckeystore kafka.client.keystore.jks -srcalias kafka-client -destkeystore client-key.p12 -deststoretype PKCS12 -srcstorepass 123456 -deststorepass 123456
openssl pkcs12 -in client-key.p12 -nocerts -out client-key.pem -passin pass:123456 -passout pass:123456

4. 修正Python客户端代码

替换为正确的客户端证书文件:

from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers='kafka-1:9092',
                          security_protocol='SSL',
                          ssl_check_hostname=True,
                          ssl_cafile='/ssl2/py2/ca-cert',
                          ssl_certfile='/ssl2/py2/client-cert.pem',
                          ssl_keyfile='/ssl2/py2/client-key.pem',
                          ssl_password='123456')

producer.send("example", bytes('Hello Kafka!123','utf-8'))
producer.flush()

5. 重启服务

清理旧容器并重新启动:

docker-compose down -v
docker-compose up -d

内容的提问来源于stack exchange,提问作者bgr11n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:59:55