bigywater.tech
ZooKeeper · 77

SASL/Kerberos 认证

ZooKeeper 的 SASL 认证有两种常用机制:DIGEST-MD5 和 Kerberos。这篇都真的跑一遍:先用不需要 KDC 的 DIGEST-MD5,再用 brew 的 krb5 在本机搭一个 KDC,用 keytab 做 Kerberos 登录,最后验证 sasl ACL。

fips-mode
3.9 默认拒绝 DIGEST-MD5,必须在两端加 -Dzookeeper.fips-mode=false
sasl:bob / sasl:zkclient@ZK.TEST
SASL 与 Kerberos 的 ACL id
enforce.auth
用 -Dzookeeper.enforce.auth.enabled / schemes 强制必须认证

DIGEST-MD5

实测 · 本机执行输出
  不带 JAAS 的客户端 whoami → Auth scheme: User | ip: 127.0.0.1
  JAAS 里是 bob 的客户端 whoami → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Auth scheme: User | sasl: bob | ip: 127.0.0.1
  口令错误的客户端 whoami → WatchedEvent state:AuthFailed type:None path:null zxid: -1 | Auth scheme: User | SASL authentication failed using login context 'Client'.

DIGEST-MD5 的用户名口令写在服务端 JAAS 文件里(user_bob="bobsecret"),这只适合实验。

sasl ACL

实测 · 本机执行输出
  bob 创建 /bobs → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Created /bobs
  bob 读 → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | data
  alice 读 → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Insufficient permission : /bobs | Exiting JVM with code 1
  匿名读 → Insufficient permission : /bobs | Exiting JVM with code 1

强制认证

实测 · 本机执行输出
  匿名 ls / → KeeperErrorCode = Session closed because client failed to authenticate for / | Exiting JVM with code 1
  bob ls / → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | [zookeeper]

Kerberos

实测 · 本机执行输出
  zkclient(Kerberos 登录)whoami → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Auth scheme: User | ip: 127.0.0.1 | sasl: zkclient@ZK.TEST
  zkclient 创建 /krbnode(ACL = sasl:zkclient@ZK.TEST)→ WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Created /krbnode
  otheruser(也是合法的 Kerberos 用户)读 → WatchedEvent state:SaslAuthenticated type:None path:null zxid: -1 | Insufficient permission : /krbnode | Exiting JVM with code 1
  没有凭据的客户端读 → Insufficient permission : /krbnode | Exiting JVM with code 1

KDC 只绑定本机端口 7650,realm 与密钥都是临时生成的;客户端登录用 keytab(useTicketCache=false),所以不会读写你系统的 Kerberos 票据缓存。

分步演示

SASL 与 Kerberos
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。单机;DIGEST-MD5 与 Kerberos 各一个节点;Kerberos 用 brew 的 krb5(KDC 本机 7650),客户端是官方 CLI + JAAS
    • 没有验证:跨主机的 Kerberos(DNS / 反向解析 / 时钟偏差)、票据续期、kerberos.removeHostFromPrincipal 等简化选项、集群节点间的 Kerberos(quorum.auth)、sasl.superUser
    京ICP备2026067502号-1京公网安备11010502063487号