3、Kafka SSL配置:Broker端SSL配置、客户端SSL配置、单向认证与双向认证

说到Kafka的安全配置,SSL这块是绕不过去的坎。很多团队一开始图省事,用明文端口跑着,直到某天运维发现某个消费者居然能随意消费所有Topic的数据——嗯,这时候才想起来要上加密和认证。

SSL配置说白了就两件事:传输加密和身份认证。传输加密保证数据在网络上不被窃听,身份认证保证连接进来的客户端确实是它声称的那个身份。我习惯把SSL配置拆成三个层面来讲:Broker端怎么配、客户端怎么配、以及单向认证和双向认证的区别。

核心要点:SSL配置的关键在于证书链的信任关系。单向认证只验证Broker身份,双向认证还要验证客户端身份。生产环境建议至少使用单向认证,敏感业务必须上双向认证。

Kafka SSL 配置知识体系 SSL 核心概念 Broker 端配置 客户端配置 认证模式选择 listeners / ssl.keystore.* ssl.truststore.* / ssl.client.auth security.protocol / ssl.truststore.* ssl.keystore.*(双向认证时) 单向认证:仅验证 Broker 双向认证:双方互相验证 💡 生产环境建议:至少单向认证 敏感业务必须上双向认证

3.1 Broker端SSL配置

Broker端配置SSL,核心就是告诉Kafka:你要监听SSL端口,并且把你的证书和私钥准备好。我见过不少新手在这步卡住,其实说白了就三个步骤。

3.1.1 生成Broker证书

首先得给Broker生成一个证书。你可以用自签名证书,也可以用CA签发的证书。测试环境自签名就够了,生产环境我建议用内部CA或者商业CA。

# 生成Broker的keystore,包含私钥和证书
keytool -keystore kafka.server.keystore.jks \
        -alias localhost \
        -validity 365 \
        -genkey -keyalg RSA \
        -storepass changeit \
        -keypass changeit \
        -dname "CN=kafka-broker-01, OU=Dev, O=MyCompany, L=Beijing, ST=Beijing, C=CN"

这里有个坑——CN字段的值。客户端连接时如果用了主机名验证,CN必须和Broker的主机名匹配。我曾经遇到过因为CN写成了IP地址,结果客户端死活连不上,折腾了半天才发现是主机名校验的问题。

3.1.2 配置server.properties

证书生成好之后,在server.properties里配置SSL监听器和证书路径。我个人习惯把SSL配置单独放在一个区域,方便维护。

# 监听器配置
listeners=PLAINTEXT://0.0.0.0:9092,SSL://0.0.0.0:9093
advertised.listeners=PLAINTEXT://kafka-broker-01:9092,SSL://kafka-broker-01:9093

# SSL基础配置
ssl.keystore.location=/etc/kafka/secrets/kafka.server.keystore.jks
ssl.keystore.password=changeit
ssl.key.password=changeit

# 信任证书配置(用于验证客户端证书)
ssl.truststore.location=/etc/kafka/secrets/kafka.server.truststore.jks
ssl.truststore.password=changeit

# 客户端认证模式:none(单向)/ requested(可选)/ required(双向)
ssl.client.auth=required

注意:ssl.client.auth参数决定了认证模式。设置为none就是单向认证,只验证Broker;设置为required就是双向认证,客户端也必须提供证书。生产环境如果开启双向认证,记得先确认所有客户端都配好了证书,否则连不上。

3.1.3 配置SSL协议和密码套件

嗯,这里要提一下安全性的细节。默认的SSL配置可能不够安全,我建议显式指定协议版本和密码套件。

# 只允许TLS 1.2和TLS 1.3
ssl.protocol=TLS
ssl.enabled.protocols=TLSv1.2,TLSv1.3

# 限制密码套件,禁用弱加密
ssl.cipher.suites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

你想想看,如果还开着TLS 1.0或者弱密码套件,那跟没加密有什么区别?我在一次安全审计中就吃过这个亏,被安全团队要求整改,后来就把密码套件白名单写死了。

3.2 客户端SSL配置

客户端配置相对简单一些,主要取决于你用单向认证还是双向认证。咱们先看单向认证的情况。

3.2.1 单向认证的客户端配置

单向认证下,客户端只需要验证Broker的证书。所以客户端只需要配置truststore,里面放CA证书或者Broker证书。

# 生成客户端的truststore,导入CA证书
keytool -keystore kafka.client.truststore.jks \
        -alias CARoot \
        -import -file ca-cert \
        -storepass changeit -noprompt

然后在客户端代码或者配置文件里这样配:

# 生产者/消费者配置
security.protocol=SSL
ssl.truststore.location=/path/to/kafka.client.truststore.jks
ssl.truststore.password=changeit

# 可选:关闭主机名验证(测试环境用)
# ssl.endpoint.identification.algorithm=

小技巧:ssl.endpoint.identification.algorithm这个参数默认是HTTPS,会验证Broker证书的CN是否匹配主机名。测试环境可以置空跳过验证,但生产环境千万别关——关了等于放弃了防中间人攻击的能力。

3.2.2 双向认证的客户端配置

双向认证下,客户端不仅要验证Broker,还要向Broker证明自己的身份。所以客户端需要配置keystore,把自己的证书发给Broker。

# 生成客户端的keystore
keytool -keystore kafka.client.keystore.jks \
        -alias client \
        -validity 365 \
        -genkey -keyalg RSA \
        -storepass changeit \
        -keypass changeit \
        -dname "CN=kafka-client-01, OU=Dev, O=MyCompany, L=Beijing, ST=Beijing, C=CN"

# 用CA签名客户端证书
keytool -keystore kafka.client.keystore.jks \
        -alias client \
        -certreq -file client-cert-req \
        -storepass changeit
# 然后用CA签名...(省略CA签名步骤)

# 导入CA证书和签名后的客户端证书
keytool -keystore kafka.client.keystore.jks \
        -alias CARoot \
        -import -file ca-cert \
        -storepass changeit -noprompt
keytool -keystore kafka.client.keystore.jks \
        -alias client \
        -import -file client-cert-signed \
        -storepass changeit -noprompt

客户端配置变成这样:

security.protocol=SSL
ssl.truststore.location=/path/to/kafka.client.truststore.jks
ssl.truststore.password=changeit
ssl.keystore.location=/path/to/kafka.client.keystore.jks
ssl.keystore.password=changeit
ssl.key.password=changeit

3.3 单向认证 vs 双向认证

这两种模式怎么选?我直接说结论:大部分场景单向认证就够了。为什么?因为传输加密已经保证了数据安全,单向认证保证了客户端连接的是真正的Broker。但如果你需要精确控制谁可以连接Kafka,那就得上双向认证。

对比维度 单向认证 双向认证
验证方向 客户端验证Broker 双方互相验证
客户端证书 不需要 需要
配置复杂度 低 高
证书管理成本 低(只需管理Broker证书) 高(每个客户端都要证书)
安全等级 中(防窃听、防伪造Broker) 高(防窃听、防伪造、防未授权客户端)
适用场景 内部网络、信任客户端环境 跨网络、多租户、敏感数据

我的建议:如果公司内部网络相对安全,单向认证配合ACL(后面章节会讲)就够用了。如果Kafka暴露在公网或者跨机房通信,或者有合规要求(比如金融、医疗),必须上双向认证。我曾经帮一个金融客户做架构,他们要求每个微服务都有独立的客户端证书,证书过期自动轮换——那套体系虽然维护成本高,但安全团队非常满意。

3.4 常见问题与避坑指南

SSL配置看着简单,实际踩坑的人不少。我整理了几个高频问题。

3.4.1 证书过期

证书过期是最常见的问题。Broker证书过期了,所有客户端都连不上。我建议在运维监控里加上证书过期告警,提前30天通知。

# 检查证书过期时间
keytool -list -v -keystore kafka.server.keystore.jks -storepass changeit | grep "Valid"

3.4.2 主机名验证失败

客户端报SSLHandshakeException: No name matching xxx found,十有八九是CN不匹配。要么改证书CN,要么在客户端关掉主机名验证(不推荐生产用)。

3.4.3 密码套件不兼容

Broker和客户端支持的密码套件对不上,也会握手失败。检查一下两端ssl.cipher.suites配置是否一致。

曾经踩过的坑:有一次我在升级Kafka集群时,把Broker的TLS版本从1.2改成了只支持1.3,结果老版本的Java客户端(JDK 8早期版本)不支持TLS 1.3,所有消费者都连不上了。从那以后,我每次改SSL配置都会先灰度一台Broker,确认客户端兼容性再全量推。

3.5 验证SSL配置是否生效

配置完了怎么验证?我一般用OpenSSL命令行工具快速测试。

# 测试SSL连接
openssl s_client -connect kafka-broker-01:9093 -tls1_2

# 如果能看到"BEGIN CERTIFICATE"和"Verify return code: 0 (ok)",说明SSL配置正确

也可以用Kafka自带的工具验证:

# 用控制台生产者测试SSL连接
kafka-console-producer.sh \
  --broker-list kafka-broker-01:9093 \
  --topic test-topic \
  --producer.config /path/to/ssl-client.properties

嗯,到这里SSL配置的核心内容就讲完了。记住一句话:证书是信任的基石,配置是安全的保障。别嫌麻烦,该配的配好,该监控的监控起来,后面才能睡得安稳。