11.10.3 身份认证与加密通信配置
在ZooKeeper安全体系中,身份认证与加密通信是防止未授权访问与中间人攻击的核心环节。建议以“强认证 + 端到端加密 + 最小暴露面”为原则,统一规划生产环境的认证机制、密钥管理与通信链路的加固配置。
原理草图:SASL + TLS 认证与加密链路
认证机制选择与策略
- 优先使用SASL/Kerberos实现强身份认证,适用于多节点集群与跨业务访问场景。
- 轻量场景可使用digest认证,但需配合强口令策略与ACL最小权限原则。
- 客户端与服务端认证方式必须统一,避免混用导致访问异常与安全漏洞。
- 禁止匿名访问,关闭不必要的四字命令与明文管理接口。
安装与准备(示例环境)
- OS: RockyLinux 8
- ZK: 3.8.x
- KDC: MIT Kerberos
- 证书: 自建CA
1)Kerberos 安装与主体创建(示例)
# 安装KDC与管理工具
dnf -y install krb5-server krb5-workstation
# 初始化Realm(示例:OPS.COM)
kdb5_util create -s -r OPS.COM
# 启动KDC
systemctl enable --now krb5kdc kadmin
# 创建ZooKeeper服务主体与客户端主体
kadmin.local <<EOF
addprinc -randkey zookeeper/zk1.ops.com@OPS.COM
addprinc -randkey zookeeper/zk2.ops.com@OPS.COM
addprinc -randkey zookeeper/zk3.ops.com@OPS.COM
addprinc zkclient@OPS.COM
# 导出keytab
ktadd -k /etc/security/keytabs/zk1.keytab zookeeper/zk1.ops.com@OPS.COM
ktadd -k /etc/security/keytabs/zk2.keytab zookeeper/zk2.ops.com@OPS.COM
ktadd -k /etc/security/keytabs/zk3.keytab zookeeper/zk3.ops.com@OPS.COM
ktadd -k /etc/security/keytabs/zkclient.keytab zkclient@OPS.COM
EOF
# 权限收敛
chmod 600 /etc/security/keytabs/*.keytab
2)ZooKeeper 服务器端 SASL 配置
- conf/jaas.conf(每台节点独立设置principal与keytab)
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/zk1.keytab"
storeKey=true
useTicketCache=false
principal="zookeeper/zk1.ops.com@OPS.COM";
};
conf/zoo.cfg
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
requireClientAuthScheme=sasl
# 强制安全端口
secureClientPort=2281
# 关闭明文端口
clientPort=0
- 启动参数(确保加载JAAS)
export JVMFLAGS="-Djava.security.auth.login.config=/opt/zookeeper/conf/jaas.conf"
bin/zkServer.sh start
3)客户端 SASL 连接示例
- conf/jaas-client.conf
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/zkclient.keytab"
storeKey=true
useTicketCache=false
principal="zkclient@OPS.COM";
};
- 连接命令
export JVMFLAGS="-Djava.security.auth.login.config=/opt/zookeeper/conf/jaas-client.conf"
bin/zkCli.sh -server zk1.ops.com:2281
# 预期输出:Welcome to ZooKeeper! 之后可执行 ls /
4)TLS/SSL 加密通信配置(客户端与quorum)
- 生成CA与证书(示例OpenSSL)
# CA
openssl genrsa -out /etc/pki/ca/ca.key 4096
openssl req -x509 -new -nodes -key /etc/pki/ca/ca.key -sha256 -days 3650 \
-subj "/C=CN/O=OPS/OU=ZK/CN=OPS-CA" -out /etc/pki/ca/ca.crt
# 节点证书(以zk1为例)
openssl genrsa -out /etc/pki/zk1.key 2048
openssl req -new -key /etc/pki/zk1.key -subj "/C=CN/O=OPS/OU=ZK/CN=zk1.ops.com" \
-out /etc/pki/zk1.csr
openssl x509 -req -in /etc/pki/zk1.csr -CA /etc/pki/ca/ca.crt -CAkey /etc/pki/ca/ca.key \
-CAcreateserial -out /etc/pki/zk1.crt -days 825 -sha256
# 转为JKS
keytool -importcert -alias ops-ca -file /etc/pki/ca/ca.crt \
-keystore /opt/zookeeper/conf/truststore.jks -storepass changeit -noprompt
openssl pkcs12 -export -in /etc/pki/zk1.crt -inkey /etc/pki/zk1.key \
-out /tmp/zk1.p12 -name zk1 -password pass:changeit
keytool -importkeystore -deststorepass changeit -destkeystore /opt/zookeeper/conf/keystore.jks \
-srckeystore /tmp/zk1.p12 -srcstoretype PKCS12 -srcstorepass changeit
chmod 600 /opt/zookeeper/conf/keystore.jks /opt/zookeeper/conf/truststore.jks
conf/zoo.cfg(TLS相关)
# 客户端TLS
secureClientPort=2281
serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
ssl.keyStore.location=/opt/zookeeper/conf/keystore.jks
ssl.keyStore.password=changeit
ssl.trustStore.location=/opt/zookeeper/conf/truststore.jks
ssl.trustStore.password=changeit
ssl.enabledProtocols=TLSv1.2,TLSv1.3
# quorum TLS
sslQuorum=true
sslQuorum.clientAuth=need
ssl.quorum.keyStore.location=/opt/zookeeper/conf/keystore.jks
ssl.quorum.keyStore.password=changeit
ssl.quorum.trustStore.location=/opt/zookeeper/conf/truststore.jks
ssl.quorum.trustStore.password=changeit
5)验证与安全自测
# 验证服务端监听端口
ss -lntp | grep 2281
# TLS握手验证
echo ruok | openssl s_client -connect zk1.ops.com:2281 -CAfile /etc/pki/ca/ca.crt
# SASL验证(客户端登录后)
getAcl /
# 预期:看到sasl:zkclient的ACL
常见故障与排错(含命令)
- 现象:SASL authentication failed
- 排查:客户端是否加载JAAS、principal是否一致
bash
grep -i sasl /opt/zookeeper/logs/zookeeper.out
klist -k /etc/security/keytabs/zkclient.keytab
- 现象:Not in GSS Initiate 或 KrbException: Clock skew
- 排查:时间不同步
bash
chronyc sources -v
date
- 现象:javax.net.ssl.SSLHandshakeException
- 排查:证书不受信任或主机名不匹配
bash
keytool -list -keystore /opt/zookeeper/conf/truststore.jks
openssl x509 -in /etc/pki/zk1.crt -noout -subject -issuer
- 现象:客户端无法连接secureClientPort
- 排查:端口未开放或clientPort未关闭
bash
grep -E "secureClientPort|clientPort" /opt/zookeeper/conf/zoo.cfg
firewall-cmd --list-ports
配置片段汇总(最小可用示例)
# zoo.cfg 关键项
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
requireClientAuthScheme=sasl
secureClientPort=2281
clientPort=0
serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
ssl.keyStore.location=/opt/zookeeper/conf/keystore.jks
ssl.keyStore.password=changeit
ssl.trustStore.location=/opt/zookeeper/conf/truststore.jks
ssl.trustStore.password=changeit
sslQuorum=true
sslQuorum.clientAuth=need
练习题与操作实践
1. 使用digest认证为/app节点设置只读ACL,并验证匿名用户无法读取。
- 提示命令:
bash
addauth digest user:pass
setAcl /app digest:user:pass:cr
get /app
2. 将现有集群从明文2181迁移到TLS 2281,完成滚动重启并验证客户端可连接。
3. 模拟证书过期,观察SSLHandshakeException日志并完成证书轮换。
4. 通过klist与kadmin.local核对principal,解决一次SASL认证失败问题。
最佳实践摘要
- 禁止匿名访问与明文端口,统一启用SASL + TLS。
- Keytab/证书不随镜像分发,通过安全通道下发并严格权限控制。
- 强制TLS1.2+与禁用弱加密套件,密钥与证书定期轮换。
- ZooKeeper对外暴露需在内网/VPN内,配合防火墙与安全组限制源IP。