应用内 TLS 校验失败
同一台机器上命令行能正常访问 HTTPS,应用却报证书校验失败,通常是两套信任库不一致:Python 常用 certifi 自带的包,Node 用系统信任库或 NODE_EXTRA_CA_CERTS 追加,Java 有自己的 trustStore,Go 读取系统证书池。运维更新了系统 CA 包,这些运行时可能仍在使用自己的副本。排查第一步是确认应用实际加载的信任库路径,再核对证书链与域名是否匹配。
基本信息
| Python | ssl.get_default_verify_paths() 查看;可用 REQUESTS_CA_BUNDLE 或 SSL_CERT_FILE 指定 |
|---|---|
| Node.js | NODE_EXTRA_CA_CERTS 追加企业根证书,或依赖系统信任库 |
| Java | -Djavax.net.ssl.trustStore 指向应用专属库,用 keytool 导入 |
| Go | 默认读取系统证书池,容器内要看镜像是否安装了 ca-certificates |
| 容器镜像 | 精简镜像常缺少 CA 包,需要安装或挂载 |
典型使用场景
- 系统 CA 更新后应用仍报错:先怀疑运行时自带信任库
- 内网自签证书或企业根证书接入,需要分发到每个运行时
- 容器精简镜像导致的线上偶发校验失败
- 排查「命令行能连、服务不能连」的经典差异
- 把 CA 分发纳入镜像构建与配置管理,避免逐台修补
定位与修复
定位与修复
python -c 'import ssl; print(ssl.get_default_verify_paths())'
python -c 'import certifi; print(certifi.where())'
java -XshowSettings:properties -version 2>&1 | grep -i trustStore
NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corp-root.pem node app.js # 追加企业根
ls /etc/ssl/certs | wc -l # 容器内确认 CA 包是否安装各运行时信任库
| 运行时 | 信任库来源 | 指定方式 |
|---|---|---|
| Python | ssl 默认路径或 certifi | REQUESTS_CA_BUNDLE / SSL_CERT_FILE |
| Node.js | 系统信任库 | NODE_EXTRA_CA_CERTS 追加 |
| Java | 自带 cacerts 或专属库 | -Djavax.net.ssl.trustStore |
| Go | 系统证书池 | 安装或挂载 ca-certificates |
| 容器镜像 | 镜像内 CA 包 | 构建时安装或运行时挂载 |
修复方向是补齐信任锚或修正证书链,而不是关闭校验。代码里加 verify=False 或 InsecureSkipVerify 会让业务暴露在中间人风险中;确需临时过渡必须限定范围与期限,并登记整改责任。
排查顺序建议:先在应用进程里打印实际使用的信任库路径,再用同一运行时发一个最小请求复现问题;确认信任库正确后,再检查证书链是否完整、域名与 SAN 是否匹配。把「信任库问题」和「链与名称问题」分开验证,通常两三轮就能定位。