bigywater.tech
ZooKeeper · 75

TLS 客户端连接

给 ZooKeeper 加 TLS 要配哪些东西?哪些错误配置会让加固失效?这篇用本机生成的 CA 与证书,从配置、信任、主机名校验、明文端口四个方面验证,最后量一下 TLS 的延迟代价。

明文端口要关
开了 TLS 端口但不去掉 clientPort,明文照样能连
主机名校验
证书 SAN 不匹配时握手失败
3.01 vs 3.03 ms
TLS 与明文的同步写 p50

明文与 TLS 端口并存

实测 · 本机执行输出
  明文客户端连 TLS 端口 7301 → KeeperErrorCode = ConnectionLoss for / | Exiting JVM with code 1
  TLS 客户端(信任 CA)连 7301 →  [zookeeper]
  TLS 客户端(不信任这个 CA,用 JVM 默认信任库)连 7301 → Unexpected throwable | io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: (certificate_unknown) PKIX path building failed: sun.security.provide
  同一个服务端的明文端口 7300 仍然可用 → [zookeeper] (这就是「开了 TLS 还留着明文端口」的风险)

配置:secureClientPort、serverCnxnFactory=…NettyServerCnxnFactory、ssl.keyStore.location / password / type、ssl.trustStore.*;客户端用 zookeeper.client.secure=true 与 ClientCnxnSocketNetty。证书由本机 openssl 生成,有效期 30 天,仅用于实验。

主机名校验

实测 · 本机执行输出
  SAN 匹配 →  [zookeeper]
  换成 CN=wrong.example.com、没有 SAN 的服务端证书 → Unexpected throwable | io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: (certificate_unknown) No name matching localhost found
  客户端关掉主机名校验(zookeeper.ssl.hostnameVerification=false)→ [zookeeper] (能连上,但失去了防冒充的保护)

强制 TLS

实测 · 本机执行输出
  明文客户端连 7305 → KeeperErrorCode = ConnectionLoss for / | Exiting JVM with code 1
  TLS 客户端连 7305 → [zookeeper]

Python 客户端与延迟

实测 · 本机执行输出
  明文 p50 3.03 ms;TLS p50 3.01 ms

分步演示

TLS 客户端
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。单机;本机 openssl 生成的 CA 与证书;官方 CLI 作 Java 客户端,kazoo 作 Python 客户端
    • 没有验证:证书过期 / 吊销(CRL / OCSP)、TLS 协议版本与密码套件选择、集群里的 TLS(节点间见第 78 篇)、证书热更新(ZooKeeper 的 ssl.*.reload 之类)
    京ICP备2026067502号-1京公网安备11010502063487号