Zane Blog

docker容器内ssl证书异常 x509

2025-08-02
docker
最后更新:2025-08-03
5分钟
820字

问题背景

使用cloudflare的zero trust连接本机的ollama。通过newapi进行转发请求的时候报错。

x509: certificate signed by unknown authority

问题现象

场景描述:

  • Go 语言编写的 API 转发程序 newapi
  • 部署在 Docker 容器中
  • 需要请求 HTTPS 服务 https://example.com

对比测试:

宿主机测试正常:

Terminal window
1
# 在宿主机执行
2
curl -v https://example.com/v1/models
3
# 输出:SSL certificate verify ok
4
# 成功返回数据

容器内程序报错:

1
{
2
"message": "tls: failed to verify certificate: x509: certificate signed by unknown authority",
3
"success": false
4
}

排查过程

第一步:检查容器环境

进入容器内部调查:

Terminal window
1
docker exec -it <容器名> /bin/sh

查看操作系统:

Terminal window
1
cat /etc/os-release
2
# 输出:Alpine Linux 3.22.1

检查证书库:

Terminal window
1
ls -l /etc/ssl/certs/
2
# 发现:证书目录存在且有内容

初步结论: 证书库并非空白,问题不在于缺少证书库。

第二步:尝试更新证书

Terminal window
1
# 更新证书包
2
apk update
3
apk upgrade ca-certificates
4
5
# 安装 curl 测试
6
apk add curl
7
curl -v https://example.com/v1/models

结果: 仍然报错 SSL certificate problem: unable to get local issuer certificate

结论: 最新的官方证书包也无法解决问题。

第三步:深入分析证书链

使用 OpenSSL 查看实际的证书链:

Terminal window
1
apk add openssl
2
openssl s_client -showcerts -connect example.com:443

关键发现:

1
Certificate chain
2
0 s:CN=example.com
3
i:C=US, O=CLOUDFLARE, INC.
4
1 s:C=US, O=CLOUDFLARE, INC.
5
i:C=US, O=SSL Corporation
6
2 s:C=US, O=SSL Corporation
7
i:C=GB, CN=AAA Certificate Services
8
9
Verify return code: 20 (unable to get local issuer certificate)

分析结果:

  • 证书链完整,由公共 CA 签发
  • 没有企业内部证书或代理干扰
  • 问题在于 Alpine 的证书库不包含根 CA AAA Certificate Services

根本原因

问题的根源是:Alpine Linux 容器镜像内置的 ca-certificates 包不包含验证目标网站所需的特定根 CA 证书。

这就像你有一串钥匙,但恰好缺少开这扇门的那一把。

完美解决方案

既然容器的证书库”先天不足”,最简单的方法就是让容器使用宿主机的完整证书库。

实施步骤

1. 停止现有容器:

Terminal window
1
docker stop <容器名>
2
docker rm <容器名>

2. 重新启动容器并挂载证书目录:

Terminal window
1
docker run -d \
2
--name <新容器名> \
3
-p <宿主端口>:<容器端口> \
4
-v /etc/ssl/certs:/etc/ssl/certs:ro \
5
<镜像名称>

关键参数解释

-v /etc/ssl/certs:/etc/ssl/certs:ro 这个参数的作用:

  • 将宿主机的 /etc/ssl/certs 目录挂载到容器的同名目录
  • :ro 表示只读挂载,确保安全性
  • 容器内的所有程序都会使用宿主机的证书库

扩展应用

这个解决方案不仅适用于本文的场景,还可以解决:

  • 企业内部 CA 证书信任问题
  • 自签名证书的验证问题
  • 各种语言和框架的 SSL 验证问题

总结

当遇到”主机正常,容器报错”的 SSL 证书问题时,记住这个万能解决方案:

Terminal window
1
-v /etc/ssl/certs:/etc/ssl/certs:ro

让容器与宿主机共享同一份证书信任库,大多数 SSL 证书验证问题都会迎刃而解。

故障排查检查清单

遇到类似问题时,按以下顺序排查:

  • 确认宿主机是否能正常访问
  • 检查容器内证书库是否存在
  • 使用 OpenSSL 分析证书链
  • 确认是否有代理或企业 CA 干扰
  • 应用证书目录挂载方案
本文标题:docker容器内ssl证书异常 x509
文章作者:Zane
发布时间:2025-08-02