证书分为 TCP 和 HTTP 两类,默认在之前的配置文件中都有体现,例如:
# HTTP 证书
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
# TCP 证书
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
其中 TCP 证书又包括两个分别是 keystore 和 truststore 主要是对应的别名部分不同,正常我们用同一个文件即可,也就是说一个文件里面包含多个 key,既包括 keystore 也包括 truststore。
在配置之前我们首先生成 CA,然后基于该 CA 再创建 TCP 证书和 HTTP 证书,虽然这里是同一个 CA,但是要注意两套证书并不会相互影响,完全可以单独生成并使用。
我们首先生成 CA,在其中一个节点执行就可以,步骤如下:
# 选择 1 个节点执行 如果下面没有强调我们的工作目录都是 /opt/elasticsearch-ca
mkdir /opt/elasticsearch-ca
cd /opt/elasticsearch-ca
# 生成 CA
elasticsearch-certutil ca --pem
执行后默认会在 Elasticsearch 的安装目录下生成 elastic-stack-ca.zip 文件,我们这里使用 RPM 方式安装生成的位置就是 /usr/share/elasticsearch
下面:
mv /usr/share/elasticsearch/elastic-stack-ca.zip .
unzip elastic-stack-ca.zip
chown -R elasticsearch:elasticsearch ca
解压后会出现 ca
目录,下面分别有 ca.crt
和 ca.key
两个文件,其中 ca.key
是私钥,ca.crt
是被私钥签名过的证书,证书的默认有效期是 3 年,我们可以使用 openssl 命令查看:
openssl x509 -in ca/ca.crt -noout -dates
需要将上面证书的内容发送到 Elasticsearch 集群中所有的节点,后续要用到,分发完然后即可开始配置更新 Elasticsearch 的证书。
绝大部分情况下 TCP 证书不需要更新,当前章节仅给出详细可执行的步骤,以备万一,因此如果 Elasticsearch 集群原有证书正常,当前章节可直接跳过,只根据需要更新 HTTP 证书即可。
首先要查看当前证书的密码,每个节点密码都不同:
elasticsearch-keystore list
下面 3 个分别表示 HTTP 证书、TCP keystore、TCP truststore 这 3 类证书的密码,默认情况下后两个 TCP 证书是指向同一个文件,所以密码是相同的,查看密码可以执行:
elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
每个机器查看密码都采用相同的命令,具体 TCP 证书的位置是:/etc/elasticsearch/certs/transport.p12
,可以查看其中的内容:
/usr/share/elasticsearch/jdk/bin/keytool -keystore /etc/elasticsearch/certs/transport.p12 -list
这里使用了 Elasticsearch 内置 JDK 的 keytool 工具,也可以使用系统默认 JDK 的 keytool 命令,执行后输入上面查询到的密码,可以看到具体的指纹,目前是 3 项,分别对应 keystore 和 truststore 的。
为了方便滚动升级,我们在每个节点上将新生成的 CA 内容添加到目前存在的证书中:
# 注意每个节点都需要执行
/usr/share/elasticsearch/jdk/bin/keytool -importcert -trustcacerts -noprompt -keystore /etc/elasticsearch/certs/transport.p12 -storepass <password> -alias transport-new-ca -file ca/ca.crt
执行后可以再次查看内容:
/usr/share/elasticsearch/jdk/bin/keytool -keystore /etc/elasticsearch/certs/transport.p12 -list
这样是保证切换证书时,节点可以被信任。
然后开始为每个节点生成新的证书:
# 每个节点都执行生成新的证书
elasticsearch-certutil cert --ca-cert /opt/elasticsearch-ca/ca/ca.crt --ca-key /opt/elasticsearch-ca/ca/ca.key
最后注意输入密码,为了简单方便管理每个节点生成相同的密码即可,证书默认会生成到 /usr/share/elasticsearch/elastic-certificates.p12
,然后我们需要放到证书目录下:
# 所有节点都需要操作
chown elasticsearch:elasticsearch /usr/share/elasticsearch/elastic-certificates.p12
mv /usr/share/elasticsearch/elastic-certificates.p12 /etc/elasticsearch/certs
然后我们开始执行滚动重启,在每个节点上轮流执行下面的步骤:
首先修改配置文件指向新的证书:
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
# 只修改这里一项配置即可
keystore.path: certs/elastic-certificates.p12
# 这一项务必保持原样
truststore.path: certs/transport.p12
修改完成之后保存配置,然后将最新设置的密码添加到密码库中,否则 Elasticsearch 将无法解密证书:
elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
添加完成后,重启 Elasticsearch 服务:
systemctl restart elasticsearch.service
重启成功后,就使用新的证书运行了,然后对其他节点都按照上面操作配置就完成了证书替换。
替换后可以将原有证书 transport.p12
的旧条目删除掉,例如:
keytool -delete -noprompt -alias <alias name> -keystore /etc/elasticsearch/certs/transport.p12 -storepass <password>
但是其实不建议这么做,因为 truststore 的密码仍然每个节点都不一样,所以之后可能会容易混淆,所以我们需要开启第二轮的滚动配置,使 truststore 也指向我们新的 elastic-certificates.p12
,首先在所有节点将刚才添加到 transport.p12 的 CA 再添加一次:
# 所有节点都要执行
/usr/share/elasticsearch/jdk/bin/keytool -importcert -trustcacerts -noprompt -keystore /etc/elasticsearch/certs/elastic-certificates.p12 -storepass <password> -alias trust-ca -file ca/ca.crt
执行后 elastic-certificates.p12
中就包含了我们的 truststore 的签名,这个时候只需要每个机器修改配置然后滚动重启:
修改配置文件如下:
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/elastic-certificates.p12
# 修改为新的 p12 证书路径
truststore.path: certs/elastic-certificates.p12
修改后需要将我们新的密码设置进去:
elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
完成之后需要重启 Elasticsearch 服务:
systemctl restart elasticsearch.service
每个节点都依次执行一遍,所有证书就都更换完毕了,另外 transport.p12
这个证书已经没用了,直接删除掉就行了。
最后也可以访问页面或者使用 curl
查看最新的证书情况:
curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://ecs16:9200/_ssl/certificates?pretty"
生成 HTTP 证书同样需要利用最前面生成的 CA,每个节点都需要依次执行并滚动重启,首先执行如下命令:
# 每个机器都需要单独生成
elasticsearch-certutil http
执行之后是交互式的命令:
询问是否生成 CSR?输入 N 并且确认
询问是否使用已存在的 CA?输入 Y 并且确认
然后输入 CA 的路径,当前是 /opt/elasticsearch-ca/ca/ca.crt
然后输入私钥的路径,当前是 /opt/elasticsearch-ca/ca/ca.key
然后继续询问证书的过期时间,默认是 5 年,根据需要输入即可
然后询问是否根据节点自动创建,这里输入 N 并确认。
然后继续询问输入当前节点的 DNS 名称,这个一定输入实际的主机名,否则将无法用主机名访问:
然后询问输入访问节点的 IP,输入当前 Elasticsearch 监听的 IP,并确认:
最后询问是否更改配置只需要输入 N 确认,最后输入密码,可以和 TCP 证书的保持一致,最后确认会询问输出目录:
默认是在 /usr/share/elasticsearch/elasticsearch-ssl-http.zip
,我们移动到当前目录并解压:
mv /usr/share/elasticsearch/elasticsearch-ssl-http.zip /opt/elasticsearch-ca
unzip elasticsearch-ssl-http.zip
解压后会生成 elasticsearch
目录和 kibana
目录,其中 elasticsearch
目录中就是生成的 HTTP 证书,然后我们修改权限并替换原有的 HTTP 证书文件:
# 修改权限
chown elasticsearch:elasticsearch elasticsearch/http.p12
# 替换证书
mv elasticsearch/http.p12 /etc/elasticsearch/certs
# 替换公钥证书
cp ca/ca.crt /etc/elasticsearch/certs/http_ca.crt
替换后 Elasticsearch 会自动加载,但是由于密码问题目前会报错,因此需要执行命令覆盖之前的密码:
elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
由于配置文件中的 HTTP 证书名称和当前生成的名称一样所以不需要修改配置文件,重启 Elasticsearch 服务即可:
systemctl restart elasticsearch.service
然后每个节点都按照上面的步骤操作一遍就完成了证书的更新,注意每个节点要正确设置主机和 IP 地址,然后可以访问验证 Elasticsearch API 查看证书情况:
curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://ecs16:9200/_ssl/certificates?pretty"
这样就完成了集群 HTTP 证书的更新。
Reference: