bigywater.tech
Elasticsearch · 164

TLS 节点间通信

本机真实用elasticsearch-certutil生成CA和节点证书搭建一个2节点集群并开启transport层TLS,验证同一张CA证书下的节点真实能成功组网且跨节点写入正常复制;随后用一张完全不同CA签发的冒牌证书配出第三个节点想加入这个集群,原集群的node数量真实卡死在2没有变化,冒牌节点自己的日志里精确记录了SSLHandshakeException和两边CA证书指纹的真实差异,揭示transport TLS让信任链不匹配的节点在握手阶段就被真实挡住,根本没有机会进入后续的集群发现流程。

同一张CA签发证书配2个节点
真实成功组网,跨节点写入正常复制
不同CA的冒牌证书配第三个节点
原集群node数量真实卡死在2
查冒牌节点日志
真实精确记录SSLHandshakeException与两边CA指纹

做的事:本机真实用elasticsearch-certutil生成一份真实的CA和节点证书,搭一个2节点集群,transport层真实开启TLS

代码真实生成CA: ./bin/elasticsearch-certutil ca --silent --out ca.p12 --pass "" 真实用这张CA签发节点证书: ./bin/elasticsearch-certutil cert --silent --ca ca.p12 --out node.p12 --pass "" 真实两个节点都配置: xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.keystore.path: certs/node.p12 xpack.security.transport.ssl.truststore.path: certs/node.p12

验证:两个节点真实成功组网,集群真实变green,写入数据真实能跨节点复制

实测 · 本机真实2节点Elasticsearch 8.15.0集群执行输出
集群健康: status="green", number_of_nodes:2

tls_test 0 p STARTED tls-node-2
tls_test 0 r STARTED tls-node-1

真实写入一条文档: {"result":"created","_shards":{"total":2,"successful":2}}
  ← 真实两份拷贝都写成功了,说明跨节点通信在TLS加密下完全正常工作

真实生成一张完全不同的、不相关的CA签发的证书,拿它配出第三个节点,想真实把它加进这个已经建好的集群

代码真实生成一张全新、独立的CA和证书: ./bin/elasticsearch-certutil ca --silent --out rogue-ca.p12 ./bin/elasticsearch-certutil cert --silent --ca rogue-ca.p12 --out rogue-node.p12 真实用这张冒牌证书配出tls-node-3,discovery.seed_hosts指向原来的2个节点

验证:这个冒牌节点真实连都连不进来——原集群的node数量真实卡死在2没有变化

实测 · 本机执行输出
真实启动tls-node-3,等待10秒后查原集群:
→ GET /_cluster/health → number_of_nodes: 2   ← 真实没有变成3

真实查冒牌节点自己的日志,看它连接失败的真实具体原因

代码真实检查tls-node-3的console日志

验证:冒牌节点自己的日志里真实精确记录了SSLHandshakeException: PKIX path validation failed,连信任的CA证书指纹和冒牌CA指纹都被真实原样打印了出来

实测 · 本机执行输出
[WARN][o.e.c.s.DiagnosticTrustManager] [tls-node-3]
  failed to establish trust with server at [...]
  the certificate is issued by [CN=Elastic Certificate Tool Autogenerated CA]
  the certificate is signed by (... fingerprint
    [5775c31f59d1ff9e6f3831b7abba8900685dcc94]) which is self-issued
  the [...] certificate is not trusted in this ssl context (...)
  this ssl context does trust a certificate with subject
    [CN=Elastic Certificate Tool Autogenerated CA]
    but the trusted certificate has fingerprint
    [edf7c2077d724b8e4930eb6874a7fa1e2d110051]   ← 真实跟对方的指纹完全不同

[WARN][o.e.t.TcpTransport] [tls-node-3] exception caught on transport layer
  ...closing connection
  javax.net.ssl.SSLHandshakeException: PKIX path validation failed:
    Path does not chain with any of the trust anchors
这组真实日志把TLS双向信任的判定过程摆得非常清楚:冒牌节点真实尝试连接原集群的两个节点时,对方真实出示了自己的证书,冒牌节点真实拿这份证书去跟自己本地信任的CA证书比对,发现签发这份证书的CA(真实的那个Elastic Certificate Tool Autogenerated CA,指纹5775c3...)跟自己真实信任的CA(指纹edf7c2...)完全是两个不同的实体,证书链真实对不上,连接在TLS握手阶段就被真实直接拒绝、关闭,根本没有机会走到后续任何的集群发现或者数据交换流程。这正是transport TLS真实想达到的效果:哪怕冒牌节点真实知道正确的IP和端口,没有真实被信任的CA签发的证书,就真实连握手这第一步都过不去,更不用说真实冒充成员节点去窃取或者篡改集群内部流转的数据。

分步演示:从同一CA证书下的真实成功组网,到冒牌证书在TLS握手阶段的真实失败

每一步都是本文在真实独立搭建的Elasticsearch 8.15.0节点上跑出来的原始结果,测完即销毁。

同一张CA签发的证书让节点真实能互信组网,不同CA的冒牌证书在握手阶段就真实被挡住
这一步新验证的transport TLS场景

    本文用到的工具

    • 真实独立搭建的Elasticsearch 8.15.0节点(开启transport TLS,测完即销毁)
    • 真实的 elasticsearch-certutil 生成CA和节点证书
    京ICP备2026067502号-1京公网安备11010502063487号