elasticsearch + kibana 8.2 更新证书

379 阅读4分钟

前言

之前我已经部署了 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"
  }
]

情况说明

  • 安装了 elasticsearchkibana 8.2 ,并且设置了账号和密码
  • 证书 http.p12 过期

生成新的 ca

使用下面的命令生成一个新的 ca 证书

./bin/elasticsearch-certutil ca --pem --out new-ca.zip

解压之后里面只有两个文件 ca/ca.crtca/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 ,解压后得到两个文件夹 elasticsearchkibana ,我们将 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 服务调用 elasticsearchapi 可以将 /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 即可,只要能正常访问就说恢复正常了。

参考