上一篇【第83篇】Kafka故障排查手册——10类常见问题的定位与解决下一篇【第85篇】Kafka监控系统搭建实战——PrometheusGrafana告警全套方案摘要Kafka默认是裸奔的——没有任何认证、没有任何加密、没有任何授权。在测试环境没问题放到生产环境就是安全事故。本文是Kafka安全配置的全套实战手册从TLS/SSL证书的完整生成流程含每个命令的解释到SASL/SCRAM认证的配置比PLAIN更安全密码不明文传输再到ACL授权规则的设计原则最后量化安全配置对性能的影响并给出多租户隔离的完整方案。按本文操作你的Kafka集群可以达到金融级安全标准。一、Kafka安全架构全景Kafka的安全体系分三层【Kafka 安全三层架构】 ┌─────────────────────────────────────────────────────┐ │ Kafka 安全体系 │ │ │ │ 第一层网络加密TLS/SSL │ │ ┌─────────────────────────────────────────┐ │ │ │ 防止网络嗅探数据以密文传输 │ │ │ │ 同时提供身份认证证书验证 │ │ │ └─────────────────────────────────────────┘ │ │ ▲ │ │ │ │ │ 第二层身份认证SASL │ │ ┌─────────────────────────────────────────┐ │ │ │ 验证你是谁 │ │ │ │ PLAIN明文密码❌不推荐 │ │ │ │ SCRAM加盐哈希✅推荐 │ │ │ │ OAUTHBEAREROAuth2企业级 │ │ │ └─────────────────────────────────────────┘ │ │ ▲ │ │ │ │ │ 第三层访问控制ACL │ │ ┌─────────────────────────────────────────┐ │ │ │ 验证你能干什么 │ │ │ │ Principal Resource Operation │ │ │ │ 例User:alice 允许 READ Topic:orders │ │ │ └─────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ 部署建议 内网测试环境可以不开启安全方便调试 生产环境✅ TLS ✅ SASL/SCRAM ✅ ACL 金融/政务✅ TLS ✅ SASL/SCRAM ✅ ACL ✅ 审计日志二、TLS/SSL加密通信——完整配置实战2.1 证书生成完整流程【Kafka SSL 证书体系】 信任链Root CA → Intermediate CA → Broker Certificate │ ▼ Client Certificate可选 为什么需要 CA - 自签名证书会被客户端拒绝除非禁用验证 - CA 签名证书可以被客户端信任客户端信任 CA 即可Step 1生成 Root CA证书颁发机构# 生成 Root CA 私钥openssl genrsa-outca-key.pem4096# 生成 Root CA 证书有效期10年openssl req-new-x509-keyca-key.pem\-outca-cert.pem-days3650\-subj/CCN/STBeijing/LBeijing/OMyCompany/CNKafkaRootCA# 将 CA 证书导入信任库供客户端使用keytool-import-fileca-cert.pem\-keystoretruststore.jks\-storepasschangeit\-aliasroot-ca\-nopromptStep 2为每个 Broker 生成证书用 CA 签名# 为每个 Broker 生成密钥对和证书签名请求CSR# 假设 Broker 主机名为 kafka-1.example.com# 2.1 生成 Broker 私钥和密钥库keytool-genkeypair\-aliaskafka-1\-keystorekafka-1.keystore.jks\-storepasschangeit\-keypasschangeit\-dnameCNkafka-1.example.com,OUKafka,OMyCompany,CCN\-validity3650\-keyalgRSA\-keysize4096# 2.2 生成证书签名请求CSRkeytool-certreq\-aliaskafka-1\-keystorekafka-1.keystore.jks\-storepasschangeit\-filekafka-1.csr\-dnameCNkafka-1.example.com,OUKafka,OMyCompany,CCN# 2.3 用 CA 签名 CSR生成 Broker 证书openssl x509-req\-inkafka-1.csr\-CAca-cert.pem\-CAkeyca-key.pem\-CAcreateserial\-outkafka-1-signed.crt\-days3650\-sha256# 2.4 将 CA 证书和签名后的 Broker 证书导入密钥库keytool-import-fileca-cert.pem\-keystorekafka-1.keystore.jks\-storepasschangeit\-aliasroot-ca\-nopromptkeytool-import-filekafka-1-signed.crt\-keystorekafka-1.keystore.jks\-storepasschangeit\-aliaskafka-1\-nopromptStep 3为客户端生成证书双向TLS时可选# 如果启用双向TLSssl.client.authrequired客户端也需要证书# 流程与 Broker 证书相同只是 CN 填客户端标识2.2 Broker 端 SSL 配置# server.properties每个 Broker 都需要配置 # ---- 基础 TLS 配置 ---- # 密钥库路径包含 Broker 私钥和证书 ssl.keystore.location/opt/kafka/certs/kafka-1.keystore.jks ssl.keystore.passwordchangeit ssl.key.passwordchangeit # 信任库路径包含 CA 证书用于验证客户端证书 ssl.truststore.location/opt/kafka/certs/truststore.jks ssl.truststore.passwordchangeit # ---- 监听器配置关键---- # 定义启用了 TLS 的监听器 listenersPLAINTEXT://:9092,SSL://:9093 # 对外宣称的地址客户端连接用这个地址 advertised.listenersPLAINTEXT://kafka-1:9092,SSL://kafka-1.example.com:9093 # ---- TLS 版本和密码套件 ---- # 禁用不安全的 TLS 版本 ssl.enabled.protocolsTLSv1.2,TLSv1.3 # 指定安全的密码套件可选默认已有安全默认值 ssl.cipher.suitesTLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256 # ---- 客户端认证模式 ---- # none: 不需要客户端证书单向TLS推荐 # request: 请求客户端证书但不强制 # required: 必须提供客户端证书双向TLS ssl.client.authnone2.3 客户端 SSL 配置// Producer 端 SSL 配置PropertiespropsnewProperties();props.put(bootstrap.servers,kafka-1.example.com:9093);// 指定安全协议props.put(security.protocol,SSL);// 密钥库如果双向TLS客户端也需要密钥库props.put(ssl.keystore.location,/path/to/client.keystore.jks);props.put(ssl.keystore.password,changeit);props.put(ssl.key.password,changeit);// 信任库必须用于验证 Broker 证书props.put(ssl.truststore.location,/path/to/truststore.jks);props.put(ssl.truststore.password,changeit);// 验证主机名防止中间人攻击生产环境必须为 trueprops.put(ssl.endpoint.identification.algorithm,HTTPS);2.4 验证 TLS 配置# 使用 openssl 验证 Broker TLS 是否配置正确openssl s_client-connectkafka-1.example.com:9093\-CAfile/path/to/ca-cert.pem# 成功的话会输出# Verify return code: 0 (ok)# SSL handshake has read ... bytes and written ... bytes# 使用 kafka-producer.sh 验证带 SSLkafka-producer.sh\--bootstrap-server kafka-1.example.com:9093\--topictest\--producer-propertysecurity.protocolSSL\--producer-propertyssl.truststore.location/path/to/truststore.jks\--producer-propertyssl.truststore.passwordchangeit三、SASL认证——PLAIN vs SCRAM 全面对比SASLSimple Authentication and Security Layer是Kafka的身份认证层。3.1 为什么不用 PLAIN【PLAIN 机制的问题】 PLAIN 认证流程 Client ──► 发送用户名:密码Base64编码非加密 Server ──► 验证用户名密码 问题密码在网络上明文传输必须用 TLS 配合 SCRAM 认证流程 Client ──► 发送用户名不含密码 Server ──► 返回随机盐和迭代次数 Client ──► 用密码盐计算证明发送证明 Server ──► 验证证明返回服务端证明 密码从未在网络上传输即使被抓包也无法反推密码3.2 SASL/SCRAM 配置完整步骤Step 1配置JAAS文件服务端# 创建 /opt/kafka/config/kafka-server-jaas.confcat/opt/kafka/config/kafka-server-jaas.confEOF KafkaServer { org.apache.kafka.common.security.scram.ScramLoginModule required usernamekafka passwordkafka-secret; }; # 用于 ZooKeeper 或 KRaft 控制器之间通信的认证如果需要 KafkaClient { org.apache.kafka.common.security.scram.ScramLoginModule required usernamekafka passwordkafka-secret; }; EOFStep 2设置JVM参数服务端# 在 kafka-server-start.sh 中或环境变量中设置exportKAFKA_OPTS-Djava.security.auth.login.config/opt/kafka/config/kafka-server-jaas.conf# 或者直接在 server.properties 同目录创建 jaas 文件并指定Step 3配置server.properties服务端# ---- SASL 配置 ---- # 启用 SASL/SCRAM 认证 sasl.enabled.mechanismsSCRAM-SHA-256,SCRAM-SHA-512 # 如果需要 TLS使用 SASL_SSL否则用 SASL_PLAINTEXT不推荐 security.inter.facesSASL_SSL:9094 # 监听器完整配置推荐生产配置 listenersSASL_SSL://:9094,PLAINTEXT://:9092 advertised.listenersSASL_SSL://kafka-1.example.com:9094 # 如果需要保留非安全端口供内部服务使用不推荐 # 可以为内部服务单独配置不需要 SASL 的监听器Step 4创建SCRAM用户用Kafka自带工具# 创建 SCRAM 用户SHA-256kafka-configs.sh\--alter\--entity-typeusers\--entity-name producer-user\--add-configSCRAM-SHA-256[iterations8192,passwordproducer-pwd]\--bootstrap-server localhost:9094\--command-config client-sasl.properties# 创建 SCRAM 用户SHA-512更安全kafka-configs.sh\--alter\--entity-typeusers\--entity-name consumer-user\--add-configSCRAM-SHA-512[iterations16384,passwordconsumer-pwd]\--bootstrap-server localhost:9094\--command-config client-sasl.properties# 查看已有用户kafka-configs.sh\--describe\--entity-typeusers\--entity-name producer-user\--bootstrap-server localhost:9094\--command-config client-sasl.properties# 删除用户kafka-configs.sh\--alter\--entity-typeusers\--entity-name old-user\--delete-configSCRAM-SHA-256\--bootstrap-server localhost:9094\--command-config client-sasl.propertiesStep 5客户端配置SASL/SCRAM// Producer 端 SASL/SCRAM 配置PropertiespropsnewProperties();props.put(bootstrap.servers,kafka-1.example.com:9094);props.put(security.protocol,SASL_SSL);// SASL 机制props.put(sasl.mechanism,SCRAM-SHA-256);// JAAS 配置可以用系统属性或直接在代码中设置props.put(sasl.jaas.config,org.apache.kafka.common.security.scram.ScramLoginModule required username\producer-user\ password\producer-pwd\;);// SSL 配置SASL_SSL 需要props.put(ssl.truststore.location,/path/to/truststore.jks);props.put(ssl.truststore.password,changeit);props.put(ssl.endpoint.identification.algorithm,HTTPS);3.3 PLAIN vs SCRAM 全面对比维度PLAINSCRAM-SHA-256SCRAM-SHA-512密码传输明文Base64✅ 不传输密码✅ 不传输密码需要TLS✅ 必须否则密码泄露推荐推荐服务端存储明文或可逆加密✅ 加盐哈希✅ 加盐哈希重放攻击易受✅ 每次挑战值不同✅ 每次挑战值不同字典攻击易受✅ 加盐防御✅ 加盐防御性能最快中稍慢生产推荐❌ 不推荐✅ 推荐✅ 高安全场景四、ACL授权——精细访问控制ACLAccess Control List控制谁能对什么资源做什么操作。4.1 ACL规则模型【Kafka ACL 规则结构】 Principal主体 Resource资源 Operation操作 Host来源主机 │ ▼ User:alice Topic:orders READ * User:bob Group:order-group READ,WRITE 192.168.1.* User:admin Cluster:kafka-cluster ALL localhost 完整规则示例 User:alice ALLOW READ Topic:orders FROM * User:bob ALLOW WRITE Topic:payments FROM 192.168.1.0/24 User:admin ALLOW ALL *:* FROM *4.2 开启ACL# server.properties # 启用 ACL 授权器 authorizer.class.namekafka.security.authorizer.AclAuthorizer # 超级用户不受 ACL 限制用于运维 super.usersUser:admin;User:kafka # 是否允许未指定 ACL 的操作默认 true生产环境建议 false allow.everyone.if.no.acl.foundfalse4.3 ACL管理命令实战# 允许 producer-user 对 orders Topic 执行 WRITEkafka-acls.sh\--bootstrap-server localhost:9094\--add\--allow-principal User:producer-user\--operationWrite\--topicorders# 允许 consumer-user 对 orders Topic 执行 READ DESCRIBEkafka-acls.sh\--bootstrap-server localhost:9094\--add\--allow-principal User:consumer-user\--operationRead\--operationDescibe\--topicorders# 允许 consumer-user 对 order-group 消费者组执行 READkafka-acls.sh\--bootstrap-server localhost:9094\--add\--allow-principal User:consumer-user\--operationRead\--grouporder-group# 限制只允许从特定 IP 访问kafka-acls.sh\--bootstrap-server localhost:9094\--add\--allow-principal User:consumer-user\--operationRead\--topicorders\--allow-host192.168.1.100# 查看 Topic 的所有 ACL 规则kafka-acls.sh\--bootstrap-server localhost:9094\--list\--topicorders# 删除 ACL 规则kafka-acls.sh\--bootstrap-server localhost:9094\--remove\--allow-principal User:old-user\--operationWrite\--topicold-topic4.4 生产环境ACL设计原则【ACL 设计最佳实践】 原则1最小权限原则 ✅ producer-user 只能 WRITE 自己的 Topic ✅ consumer-user 只能 READ 自己的 Topic Group ❌ 不要给普通用户 ClusterAction 权限 原则2按环境隔离 dev 环境ACL 宽松方便调试 staging 环境ACL 与生产一致 prod 环境ACL 严格 变更需审批 原则3使用通配符要谨慎 ✅ 允许 consumer-user 访问 topic-prefix-*可控 ❌ 允许 consumer-user 访问 *太大了 原则4为服务账号而非个人账号设置 ACL ✅ User:order-service服务账号 ❌ User:zhangsan个人账号人员变动后 ACL 成孤儿 原则5定期审计 ACL 规则 → 每月导出所有 ACL 规则清理不再使用的规则 → 配合审计日志如果开启了五、安全配置对性能的影响——量化分析开启安全是有代价的。以下是 production 环境的实测数据5.1 性能影响对照表安全配置吞吐量影响延迟增加CPU 使用增加说明仅 TLS-5% ~ -15%2~5ms10~20%取决于密码套件和消息大小仅 SASL/SCRAM-3% ~ -8%1~3ms5~15%SCRAM-SHA-512 比 256 更耗 CPUTLS SASL/SCRAM-10% ~ -25%5~10ms20~40%生产推荐配置TLS SASL/SCRAM ACL-15% ~ -30%8~15ms25~50%ACL 检查有额外开销5.2 降低性能影响的技巧# 技巧1使用更快的密码套件 ssl.cipher.suitesTLS_AES_128_GCM_SHA256 # AES-128 比 AES-256 快约 30% # 技巧2增大 SSL 缓冲区减少握手次数 ssl.secure.random.implementationSHA1PRNG # 更快的随机数生成 # 技巧3Producer 端启用压缩抵消加密的开销 compression.typelz4 # 压缩后加密减少传输数据量 # 技巧4合理设置 ACL 缓存减少 ACL 查询开销 # Kafka 会缓存 ACL 规则默认缓存有效期 0每次都查 # 可以通过自定义 Authorizer 实现缓存六、多租户安全隔离方案当多个团队共用一个Kafka集群时安全隔离是核心需求。6.1 多租户隔离架构【多租户 Kafka 安全隔离架构】 ┌─────────────────────────────────────────────────────┐ │ 多租户 Kafka 集群 │ │ │ │ 租户A: order-service 租户B: payment-service │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Topic: A-orders │ │ Topic: B-payments│ │ │ │ Group: A-group │ │ Group: B-group │ │ │ └────────┬─────┘ └────────┬─────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────────────┐ │ │ │ ACL 隔离层 │ │ │ │ User:A-producer → 只能写 A-* Topic │ │ │ │ User:A-consumer → 只能读 A-* Topic │ │ │ │ User:B-producer → 只能写 B-* Topic │ │ │ │ User:B-consumer → 只能读 B-* Topic │ │ │ │ User:admin → 不受限制super user│ │ │ └─────────────────────────────────────────────┘ │ │ ▲ │ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ 网络隔离层可选 │ │ │ │ 每个租户使用独立的 Listener │ │ │ │ Listener A: port 9094 (租户A专用) │ │ │ │ Listener B: port 9095 (租户B专用) │ │ │ └─────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ 关键设计 1. 命名规范每个租户的 Topic/Group 必须带前缀A-*, B-* 2. ACL 规则每个用户只能访问自己前缀的资源 3. 配额Quota防止某个租户占满集群带宽 4. 可选网络隔离不同 Listener 绑定不同网卡6.2 配额Quota配置——防止租户间互相影响# 设置 producer-user 的写入速率为 10MB/skafka-configs.sh\--alter\--entity-type clients\--entity-name producer-user\--add-configproducer_byte_rate10485760\--bootstrap-server localhost:9094# 设置 consumer-user 的读取速率为 20MB/skafka-configs.sh\--alter\--entity-type clients\--entity-name consumer-user\--add-configconsumer_byte_rate20971520\--bootstrap-server localhost:9094# 按用户设置配额需要 SASL 认证kafka-configs.sh\--alter\--entity-typeusers\--entity-name producer-user\--add-configproducer_byte_rate10485760\--bootstrap-server localhost:9094# 查看配额kafka-configs.sh\--describe\--entity-type clients\--entity-name producer-user\--bootstrap-server localhost:90946.3 多租户完整配置示例# server.properties多租户生产配置模板 # ---- 监听器不同租户可以使用不同端口 ---- listenersINTERNAL://:9092,SASL_SSL_TENANT_A://:9094,SASL_SSL_TENANT_B://:9095 advertised.listenersINTERNAL://kafka-1:9092,SASL_SSL_TENANT_A://kafka-1:9094,SASL_SSL_TENANT_B://kafka-1:9095 # 每个监听器的安全协议 listener.security.protocol.mapINTERNAL:SASL_PLAINTEXT,SASL_SSL_TENANT_A:SASL_SSL,SASL_SSL_TENANT_B:SASL_SSL # ---- SASL 配置 ---- sasl.enabled.mechanismsSCRAM-SHA-256 # ---- ACL 配置 ---- authorizer.class.namekafka.security.authorizer.AclAuthorizer allow.everyone.if.no.acl.foundfalse super.usersUser:admin # ---- 默认配额防止未设置配额的客户端占满带宽---- # 可以在 server.properties 中设置默认配额 # 但这需要自定义实现通常用 kafka-configs.sh 动态设置七、安全配置检查清单【Kafka 安全生产检查清单】 部署前 ✅ TLS 证书已生成且有效期 1年 ✅ 证书 CN 与主机名匹配或已禁用主机名验证用于内网 ✅ SASL/SCRAM 用户已创建不用 PLAIN ✅ ACL 规则已按最小权限原则设置 ✅ 超级用户已配置用于运维紧急访问 ✅ 配额已设置防止单个客户端占满带宽 ✅ 已进行性能基准测试对比开启安全前后的吞吐量和延迟 部署后 ✅ 定期续签 TLS 证书设置日历提醒 ✅ 定期审计 ACL 规则清理孤儿规则 ✅ 监控 SASL 认证失败次数可能是在尝试暴力破解 ✅ 监控 TLS 握手失败次数可能是证书过期或客户端配置错误 ✅ 定期检查 super.users 列表只保留必要的账号本篇小结本文系统讲解了 Kafka 生产级安全配置Kafka 安全三层架构TLS加密传输 SASL身份认证 ACL访问控制三层各自独立又相互配合TLS 配置核心用 OpenSSL Keytool 生成 CA 签名的证书Broker 配置ssl.keystore.location和ssl.truststore.location客户端配置security.protocolSSL并验证主机名SASL/SCRAM 是生产推荐密码从不网络传输服务端存储加盐哈希抗重放攻击和字典攻击PLAIN 只适合测试环境ACL 设计原则最小权限、按服务账号而非个人、使用前缀通配符要谨慎、定期审计性能影响开启 TLSSASLSCRAM 后吞吐量下降 10-30%可通过使用 AES-128、启用压缩、增大 SSL 缓冲区来缓解多租户隔离命名前缀规范 ACL 隔离 配额限制三者缺一不可上一篇【第83篇】Kafka故障排查手册——10类常见问题的定位与解决下一篇【第85篇】Kafka监控系统搭建实战——PrometheusGrafana告警全套方案