3. 证书与密钥管理
在 Elasticsearch 集群中启用 TLS 之前,必须先解决一个前置问题:谁来签发证书、证书里写什么身份、私钥放在哪里、各组件如何信任同一套根证书。Elasticsearch 自带的 elasticsearch-certutil 工具正是为这一流程设计的,它把 OpenSSL 中繁琐的 CA 创建、CSR 生成、签名和打包步骤收敛成几条命令,同时生成符合 Elastic 各组件(Elasticsearch、Kibana、Logstash、Beats)要求的证书结构。
本节围绕一条完整链路展开:先用 certutil ca 建立私有 CA,再用 certutil cert 为节点和客户端签发证书,最后把证书、私钥和 CA 证书落到配置目录并写入 elasticsearch.yml。理解这条链路的关键,是分清“谁签发、谁持有、谁信任”三个角色。
一、证书体系中的三个角色
Elasticsearch 的 TLS 信任模型是标准的私有 PKI 模型,包含三类材料:
- CA 证书与 CA 私钥:由
elasticsearch-certutil ca生成,是整个信任链的根。CA 证书(elastic-stack-ca.p12)需要分发给所有节点和客户端用于验证对端;CA 私钥只用于签发,必须离线保管,绝不能复制到节点上。 - 节点证书:由
elasticsearch-certutil cert用 CA 签发,每个 Elasticsearch 节点一份,包含节点私钥、节点证书和 CA 证书。节点证书的 SAN(Subject Alternative Name)必须覆盖该节点被访问时使用的所有主机名和 IP。 - 客户端证书:同样由 CA 签发,用于 Kibana、Logstash、Beats 或 REST 客户端向 Elasticsearch 证明身份。当集群开启
xpack.security.authc的证书认证时,客户端证书的 CN 会被映射为用户名。
三者关系可以用下面的信任链示意:CA 是唯一的签发者,节点证书和客户端证书都由它签发,所有实体都持有同一份 CA 证书作为信任锚。
二、生成 CA
第一步是创建 CA。在任意一台安装了 Elasticsearch 的机器上执行:
cd /usr/share/elasticsearch
bin/elasticsearch-certutil ca \
--out config/certs/elastic-stack-ca.p12 \
--pass ""
参数说明:--out 指定输出的 PKCS#12 文件路径;--pass 是 CA 私钥的保护口令,示例中留空表示不加密,生产环境应设置强口令。执行后会生成 elastic-stack-ca.p12,其中同时包含 CA 证书和 CA 私钥。这个文件是整套信任体系的根,建议立即备份到安全位置,之后签发证书时反复使用。
elastic-stack-ca.p12 不应长期留在 Elasticsearch 节点上,签发完成后应转移到受控的离线存储。三、生成节点证书
节点证书需要为每个节点单独签发,且 SAN 必须准确。推荐先用一个实例描述文件批量生成,避免逐台手写命令出错。创建 instance.yml:
instances:
- name: node1
ip: ["10.0.0.11"]
dns: ["node1.es.local", "localhost"]
- name: node2
ip: ["10.0.0.12"]
dns: ["node2.es.local", "localhost"]
- name: node3
ip: ["10.0.0.13"]
dns: ["node3.es.local", "localhost"]
然后执行:
bin/elasticsearch-certutil cert \
--ca config/certs/elastic-stack-ca.p12 \
--ca-pass "" \
--in instance.yml \
--out config/certs/nodes.zip \
--pass ""
命令会读取 CA、按 instance.yml 中的 name/ip/dns 生成每个节点的证书,并打包为 nodes.zip。解压后得到 node1/node1.p12、node2/node2.p12、node3/node3.p12,每个文件都包含该节点的私钥、节点证书和 CA 证书。把对应文件分发到各节点的 config/certs/ 目录即可。
这里有一个容易出错的点:如果节点间通信使用主机名,SAN 里就必须有该主机名;如果使用 IP,SAN 里就必须有该 IP。TLS 握手时客户端会校验对端证书的 SAN 是否匹配自己连接的目标地址,不匹配会直接报 No subject alternative names matching IP address 或 No name matching ... found。
四、生成客户端证书
客户端证书用于 Kibana、Logstash、Beats 等组件。以 Kibana 为例:
bin/elasticsearch-certutil cert \
--ca config/certs/elastic-stack-ca.p12 \
--ca-pass "" \
--name kibana \
--dns kibana.es.local \
--ip 10.0.0.21 \
--out config/certs/kibana.p12 \
--pass ""
与节点证书不同,客户端证书通常用 --name 直接指定 CN。这个 CN 在 Elasticsearch 开启证书认证后会被映射为用户名,因此命名应遵循可识别的规范,例如 kibana、logstash_shipper。若客户端需要访问多个地址,同样用 --dns 和 --ip 补充 SAN。
五、写入 TLS 配置
证书就位后,在 elasticsearch.yml 中配置传输层和 HTTP 层 TLS。传输层用于节点间通信,HTTP 层用于对外 REST 接口:
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/node1.p12
xpack.security.transport.ssl.truststore.path: certs/node1.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/node1.p12
xpack.security.http.ssl.truststore.path: certs/node1.p12
由于节点证书的 p12 文件中已经包含 CA 证书,truststore.path 可以直接指向同一个文件。如果私钥设置了口令,还需要把口令写入 Elasticsearch keystore:
bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
bin/elasticsearch-keystore add xpack.security.http.ssl.truststore.secure_password
六、验证与常见问题
配置完成后重启节点,用以下方式确认 TLS 是否生效:
curl --cacert config/certs/elastic-stack-ca.p12 \
--cert config/certs/kibana.p12:kibana \
https://node1.es.local:9200/_cluster/health?pretty
若返回集群健康信息,说明 HTTP 层 TLS 与客户端证书认证均已工作。常见失败及判断依据:
| 现象 | 原因 | 处理 |
|---|---|---|
| No subject alternative names matching IP address | 证书 SAN 未包含连接使用的 IP | 重新签发证书并补充 --ip |
| unable to find valid certification path | 对端不信任签发该证书的 CA | 确认 truststore 中包含正确的 CA 证书 |
| Keystore was tampered with, or password was incorrect | p12 口令错误或未写入 keystore | 检查 elasticsearch-keystore 中的 secure_password |
| 节点无法加入集群 | 传输层证书 CN/SAN 与节点配置不一致 | 核对 node.name 与证书 SAN |
certutil 生成的证书有效期为 3 年。建议在证书到期前 3 个月规划轮换,轮换时先更新 CA 信任库、再逐节点替换证书,避免集群同时失去信任锚。把上述流程串起来看,elasticsearch-certutil 的价值在于用统一命令生成结构一致的 p12 文件,使节点、客户端和 CA 之间的信任关系清晰可控。真正需要人工判断的只有三件事:SAN 是否覆盖实际访问地址、CN 是否符合认证映射预期、私钥口令是否安全地进入 keystore。这三点确认无误,TLS 配置基本就能一次通过。