Node.js连接自签证书Elasticsearch时证书验证失败问题
解决Node.js Elasticsearch客户端无法连接自签证书集群的问题
核心原因分析
你遇到的ConnectionError: unable to verify the first certificate错误,本质是Node.js的TLS验证逻辑与curl存在差异:curl指定完整客户端证书时会跳过部分链验证,而Node.js客户端仅依赖CA证书做信任验证,若证书的Subject Alternative Names (SAN) 不匹配连接域名,或CA证书加载异常,就会触发验证失败。
分步解决方案
1. 检查证书的SAN配置(最常见原因)
确保生成证书时,instances.yml中每个ES节点的dns字段包含你客户端连接用的域名(my-cluster-domain.com),如果用IP连接也要添加对应IP。示例配置:
instances: - name: es01 dns: [es01, localhost, my-cluster-domain.com] ip: [127.0.0.1, 你的集群公网/内网IP] # 其他ES节点、Kibana配置同理
如果之前生成证书时未添加该域名,需重新执行elasticsearch-certutil生成证书,替换集群中的证书文件后重启ES。
2. 修正Node.js客户端的TLS配置
- 优先使用绝对路径加载CA证书,避免相对路径导致的文件读取异常
- 确保CA证书以字符串格式传入(
fs.readFileSync指定'utf8'编码) - 若SAN配置正确,建议开启
rejectUnauthorized: true保证安全性
修正后的代码:
const path = require('path'); const { Client } = require('@elastic/elasticsearch'); const fs = require('fs'); const client = new Client({ node: config.elastic.node, auth: { username: "elastic", password: config.elastic.password }, tls: { ca: fs.readFileSync(path.resolve(__dirname, "./share/es/certs/ca.crt"), 'utf8'), rejectUnauthorized: true } });
3. 验证证书链完整性
用openssl工具检查证书链是否有效:
openssl verify -CAfile /path/to/ca.crt /path/to/es01.crt
若输出es01.crt: OK,说明证书链正常;若报错,需重新生成证书,确保所有节点证书由同一CA签名。
4. 解决浏览器“证书有效但不安全”的提示
浏览器不信任自签CA,只需将ca.crt导入浏览器的受信任根证书颁发机构列表即可消除该提示。
补充说明:为何curl能正常连接?
你的curl命令同时指定了--cert和--key(客户端证书),此时curl会使用完整的客户端证书链完成验证,跳过了单纯依赖CA的域名匹配检查。实际上,若你的ES未配置双向TLS(即不需要客户端提供证书),curl只需指定--cacert即可正常连接:
curl -X GET "https://elastic:$ES_PASSWORD@my-cluster-domain.com:9201" --cacert $CACERT
内容的提问来源于stack exchange,提问作者matthaeus
相关产品推荐
相关产品推荐

