前言
之前我已经部署了 elasticsearch 8.2
版本和 kibana 8.2
版本,并且设置了账号密码,没成想两年过去了,证书居然过期了,突然线上报错如下:
java.util.concurrent.ExecutionException: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
...
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:913)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:299)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:287)
...
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at sun.security.ssl.Alert.createSSLException(Alert.java:131)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:324)
at sun.security.ssl.TransportContext.fatal(TransportContext.java:267)
...
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:386)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:279)
at sun.security.validator.Validator.validate(Validator.java:271)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:278)
...
Caused by: java.security.cert.CertPathValidatorException: validity check failed
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:220)
...
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu Aug 01 11:17:49 CST 2024
at sun.security.x509.CertificateValidity.valid(CertificateValidity.java:277)
at sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:677)
at sun.security.provider.certpath.BasicChecker.verifyValidity(BasicChecker.java:190)
...
其实看最后一个报错就知道了,是有一个证书过期了,其实就是 http.p12
过期了,因为到期时间是 2024 年 8 月 1 号
,所以我们要做的就是更新我们的证书。正常情况我们可以在 kibana
的控制台查看我们的证书,命令如下:
GET _ssl/certificates
然后我们可以看到我们现有的所有证书列表,关键的信息我已经用星号隐去了,这个是我最新的列表,可以看出来过期时间都是还要好几年,如果你的证书快到期就可以按照本教程来更新证书了:
[
{
"path" : "certs/http_240809.p12",
"format" : "PKCS12",
"alias" : "ca",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : false,
"expiry" : "2027-08-09T11:54:53.000Z"
},
{
"path" : "certs/http_240809.p12",
"format" : "PKCS12",
"alias" : "http",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : false,
"expiry" : "2027-08-09T11:54:53.000Z"
},
{
"path" : "certs/http_240809.p12",
"format" : "PKCS12",
"alias" : "http",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : true,
"expiry" : "2029-08-09T12:03:22.000Z"
},
{
"path" : "certs/transport.p12",
"format" : "PKCS12",
"alias" : "transport",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : false,
"expiry" : "2121-07-09T03:17:43.000Z"
},
{
"path" : "certs/transport.p12",
"format" : "PKCS12",
"alias" : "transport",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : true,
"expiry" : "2121-07-09T03:17:45.000Z"
},
{
"path" : "certs/transport.p12",
"format" : "PKCS12",
"alias" : "transport_ca",
"subject_dn" : "***",
"serial_number" : "***",
"has_private_key" : false,
"expiry" : "2121-07-09T03:17:43.000Z"
}
]
情况说明
- 安装了
elasticsearch
和kibana 8.2
,并且设置了账号和密码 - 证书
http.p12
过期
生成新的 ca
使用下面的命令生成一个新的 ca 证书
./bin/elasticsearch-certutil ca --pem --out new-ca.zip
解压之后里面只有两个文件 ca/ca.crt
、ca/ca.key
,将 ca
整个文件都移动到 /home/es_kibana_test/elasticsearch-8.2.0/config/
目录下面即可。
生成新的 http.p12
使用下面的命令会生成一个 elasticsearch-ssl-http.zip
:
./bin/elasticsearch-certutil http
和命令行交互过程,需要仔细核对每一步的输入,如果觉得有错误可以取消重新执行上面的命令:
Generate a CSR? [y/N]n
Use an existing CA? [y/N]y (这里我们使用了已有的CA证书)
CA Path:ca/ca.crt (填写证书路径,我这里填的是相对路径,也可以绝对路径)
CA Key: ca/ca.key (填写证书路径,我这里填的是相对路径,也可以绝对路径)
For how long should your certificate be valid? [5y] 5y(设置证书有效期,我填了 5 年)
Generate a certificate per node? [y/N]n (这里我们为所有节点使用统一的证书,可以根据实际需求设置)
Enter all the hostnames that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step. (填写集群内所有节点服务器的hostname)
Enter all the IP addresses that you need, one per line. When you are done, press <ENTER> once more to move on to the next step. (填写集群内所有节点服务器的IP地址)
Do you wish to change any of these options? [y/N]n
If you wish to use a blank password, simply press <enter> at the prompt below. Provide a password for the "http.p12" file: [<ENTER> for none](输入需要设置的密码)
Repeat password to confirm: (重复密码以确认)
What filename should be used for the output zip file? [/home/es_kibana_test/elasticsearch-8.2.0/elasticsearch-ssl-http.zip] (设置输出文件路径及名称,默认即可,按【Enter】键继续)
Zip file written to /home/es_kibana_test/elasticsearch-8.2.0/elasticsearch-ssl-http.zip
更新 elasticsearch 证书配置
得到的 elasticsearch-ssl-http.zip
,解压后得到两个文件夹 elasticsearch
和 kibana
,我们将 elasticsearch/http.p12
文件复制并改名为 http_0812.p12
到 /home/es_kibana_test/elasticsearch-8.2.0/config/certs/
目录下面,然后修改 config/elasticsearch.yml
文件,基本的配置不用去管,将里面的之前的过期的证书:
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
修改为:
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http_0812.p12
keystore.password: "上面生成证书的步骤中间你输入的密码"
保存文件之后保证 elasticsearch
下面的所有文件都是同样的用户,然后重启服务,如果重启之后验证
如果报错:
org.elasticsearch.ElasticsearchSecurityException: failed to load SSL configuration [xpack.security.http.ssl] - cannot specify both [keystore.secure_password] and [keystore.password]
说明有一个 keystore.secure_password
之前配置过,使用命令查询现有的密码列表:
./bin/elasticsearch-keystore list
控制台打印:
keystore.seed
xpack.security.http.ssl.keystore.secure_password
xpack.security.transport.ssl.keystore.secure_password
xpack.security.transport.ssl.truststore.secure_password
我们看到有一个 xpack.security.http.ssl.keystore.secure_password
然后使用下面的命令删掉即可:
./bin/elasticsearch-keystore remove xpack.security.http.ssl.keystore.secure_password
然后重启即可,如果没有异常就可以使用。我们可以用下面的命令检查是否正常运行,如果有结果就说明正常了:
curl --cacert /home/es_kibana_test/elasticsearch-8.2.0/config/ca/ca.crt -H "Content-Type:application/json" -X POST "https://12:9400/spatial_semantic/_search" -d '{"query":{"match_all":{}}}' -u 账号:密码
如果是 java
服务调用 elasticsearch
的 api
可以将 /home/es_kibana_test/elasticsearch-8.2.0/config/ca/ca.crt
放入 resources 中调用即可。
更新 kibana 配置
将 /home/es_kibana_test/elasticsearch-8.2.0/kibana/elasticsearch-ca.pem
移动到 /home/es_kibana_test/kibana-8.2.0/config
目录下面,然后修改 kibana.yml
文件,将原来的:
elasticsearch.ssl.certificateAuthorities: [/home/es_kibana_test/kibana-8.2.0/data/ca_1659427874790.crt]
改为:
elasticsearch.ssl.certificateAuthorities: [ "config/elasticsearch-ca.pem" ]
重启 kibana
即可,只要能正常访问就说恢复正常了。