以下内容均已完成测试,按照教程搭建你会得到一个双向ssl认证的kafka broker,并能通过ip以及域名访问,笔者能力有限如果文章内容存在问题烦请各位指出。
参考文档
安装路径:/opt/kafka_2.12-2.6.0
wget https://archive.apache.org/dist/kafka/2.6.0/kafka-2.6.0-src.tgz
tar -xzf kafka_2.12-2.6.0.tgz
cd kafka_2.12-2.6.0
# 启动zookeeper 服务
bin/zookeeper-server-start.sh config/zookeeper.properties
# 启动kafka broker 服务
bin/kafka-server-start.sh config/server.properties
# 创建topic,用于后续测试
bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092
至此kafka 已经安装并启动成功,以下围绕service.properties配置双向ssl展开
kafka官方文档
kafka官方文档-译文
keytool官方文档
openssl官方文档
注🚩:
构造密钥目录
mkdir /var/private/ssl -p
cd /var/private/ssl
-dname 选项请按照实际情况修改,应十分注意cn的内容,这会直接影响证书是否可用
-validity 为有效期
-keyalg 表示选项指定生成密钥对或私钥时使用的算法,默认为DSA,使用默认选项会出现jks转成pem私钥解析失败的问题
keytool -genkey -dname "cn=mykafkassl.com, ou=qihoo, o=qihoo, c=CN" -keystore server.keystore.jks -alias localhost -validity 36500 -storetype PKCS12 -keypass -storepass -keyalg RSAkeytool -genkey -dname "cn=mykafkassl.com, ou=qihoo, o=qihoo, c=CN" -keystore client.keystore.jks -alias localhost -validity 36500 -storetype PKCS12 -keypass -storepass -keyalg RSA
生成CA的私钥、CA的证书
提示内容请根据实际情况填写,COMMON NAME 部分建议与步骤一保持一致
-days选项表示有效期
openssl req -new -x509 -keyout ca-key -out ca-cert -days 36500
导出证书以便于后续签名
# server
keytool -keystore server.keystore.jks -alias localhost -certreq -file server.crt -keypass -storepass # client
keytool -keystore client.keystore.jks -alias localhost -certreq -file client.crt -keypass -storepass
使用步骤2生成的CA给刚导出的证书签名
openssl.cnf 用于构造SAN,需要根据实际情况修改[alt_names]
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = MN
localityName = Locality Name (eg, city)
localityName_default = Minneapolis
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Domain Control Validated
commonName = Internet Widgits Ltd
commonName_max = 64[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names[alt_names]
DNS.1 = mykafkassl.com
IP.1 =
将openssl.cnf 拷贝到服务器上
# server
openssl x509 -req -CA ca-cert -CAkey ca-key -in server.crt -out server-crt.signed -days 36500 -CAcreateserial -extfile openssl.cnf -extensions v3_req# client
openssl x509 -req -CA ca-cert -CAkey ca-key -in client.crt -out client-crt.signed -days 36500 -CAcreateserial -extfile openssl.cnf -extensions v3_req
# server
keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert -keypass -storepass
keytool -keystore server.keystore.jks -alias localhost -import -file server-crt.signed -keypass -storepass # client
keytool -keystore client.keystore.jks -alias CARoot -import -file ca-cert -keypass -storepass
keytool -keystore client.keystore.jks -alias localhost -import -file client-crt.signed -keypass -storepass
# server
keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert -keypass -storepass # client
keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert -keypass -storepass
vim /opt/kafka_2.12-2.6.0/config/server.properties
security.inter.broker.protocol=SSLlisteners=SSL://0.0.0.0:9093advertised.listeners=SSL://:9093ssl.keystore.location=/var/private/ssl/server.keystore.jks
ssl.keystore.password=Q!hooS0c
ssl.key.password=Q!hooS0cssl.truststore.location=/var/private/ssl/server.truststore.jks
ssl.truststore.password=Q!hooS0c
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1ssl.client.auth=required
ssl.endpoint.identification.algorithm=
生成client-ssl.properties客户端配置
vim /opt/kafka_2.12-2.6.0/config/client-ssl.properties
client-ssl.properties
security.protocol=SSL
ssl.truststore.location=/var/private/ssl/client.truststore.jks
ssl.truststore.password=Q!hooS0cssl.keystore.location=/var/private/ssl/client.keystore.jks
ssl.keystore.password=Q!hooS0c
ssl.key.password=Q!hooS0c
启动客户端,并输入一些测试数据,如果没有报错则表明ssl配置成功
bin/kafka-console-producer.sh --broker-list :9093 --topic quickstart-events --producer.config config/client-ssl.properties
bin/kafka-console-consumer.sh --bootstrap-server :9093 --topic quickstart-events --consumer.config config/client-ssl.properties
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTsx9w4K-1677863718067)(/uploads/58fcebe11ae36ec898636069d3ef180e/image.png)]
kafka broker配置了PLAINTEXT和SSL两个端口,客户端通过PLAINTEXT连接没有经过SSL
由于是自签名,这种情况属正常现象
请不要盲目参考网络上教程提高max_size,应该仔细检查server.properties 配置
在步骤1中的域名配置错误,在客户端校验时发现主机名与证书的COMMON NAME不一致,故断开连接。
当然 握手失败的的原因远远不止这一种,推荐使用抓包工具(如wireshark、tcpdump)抓包排查握手失败发生在哪一步从而确定错误原因、使用openssl自带的s_client、s_server并开启debug模式,定位错误原因。
common name可以配置成一个虚拟的域名,然后再客户端和服务器中修改hosts。也可以配置SAN,在扩展项中输入ip