错误信息
curl: (77) error setting certificate file: /etc/pki/tls/certs/ca-bundle.crt
也可能输出为
- curl: (77) error setting certificate verify locations: CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: /etc/ssl/certs
curl 7.81 及更高版本打印“error setting certificate file: <path>”(如果是 CA 目录,则为“error setting certificate path”);curl 7.74 及更早版本打印的是“error setting certificate verify locations:”,后面跟着 CAfile 和 CApath 的值。路径就是你的配置中指定的那个。
curl (OpenSSL backend) — CURLE_SSL_CACERT_BADFILE
含义
curl 无法加载配置中指定的 CA 证书包,因此拒绝发起任何 HTTPS 请求。没有任何数据发送到服务器:失败发生在建立连接之前,即 curl 读取冒号后所列文件的时候。该路径来自 --cacert、CURL_CA_BUNDLE、SSL_CERT_FILE、.curlrc 文件,或编译进 curl 的默认值。
原因
路径来自其他发行版
常见为 RHEL 编写的脚本、Dockerfile 和 CI 模板会导出 CURL_CA_BUNDLE=/etc/pki/tls/certs/ca-bundle.crt;同样这一行放到 Debian、Ubuntu 或 Alpine 上,指向的证书文件并不存在(反过来,/etc/ssl/certs/ca-certificates.crt 也是如此)。
镜像中没有安装 CA 证书包
常见精简镜像常常不包含 ca-certificates 软件包,因此编译进 curl 的默认证书包路径指向的文件并不存在。
文件存在但无法读取
偶见只有 root 可读的证书包、升级后失效的符号链接,或复制失败后被截断的空文件,都会产生同样的消息。
相对路径基于另一个目录解析
偶见--cacert certs/ca.pem 在项目文件夹中可以正常工作,但当 cron 任务、systemd 单元或 CI 步骤从其他工作目录运行 curl 时就会失败。
修复方法
- 1.
找出路径的来源
检查环境变量和 ~/.curlrc 文件中是否有 CA 设置,并用 curl -V 查看 TLS 库:OpenSSL 构建版本会遵循 CURL_CA_BUNDLE 和 SSL_CERT_FILE,Schannel 和 Secure Transport 构建版本除非另行指定,否则使用系统证书存储。
bash env | grep -E 'CURL_CA_BUNDLE|SSL_CERT_FILE|SSL_CERT_DIR' grep -sE 'cacert|capath' ~/.curlrc curl -V | head -1 # which TLS library this curl uses - 2.
使用本发行版的证书包路径,或者不指定任何路径
大多数情况下,正确的做法是删除覆盖设置:这样 curl 会使用其软件包构建时设定的证书包路径。如果你需要自定义证书包,就指向这个系统上实际存在的文件。
bash # Debian, Ubuntu, Alpine: /etc/ssl/certs/ca-certificates.crt # RHEL, Fedora, Amazon Linux: /etc/pki/tls/certs/ca-bundle.crt # openSUSE: /etc/ssl/ca-bundle.pem unset CURL_CA_BUNDLE # let curl use the bundle it was built with ls -l /etc/ssl/certs/ca-certificates.crt - 3.
安装提供 CA 证书包的软件包
在精简镜像和基于 distroless 的镜像中,在构建时添加 ca-certificates,让默认的证书包路径确实存在。
bash apt-get install -y ca-certificates # Debian/Ubuntu apk add --no-cache ca-certificates # Alpine dnf install -y ca-certificates # RHEL/Fedora - 4.
让文件可读,并使用绝对路径
运行 curl 的账号需要对证书包有读取权限。使用绝对路径时,即使工作目录发生变化,也能继续正常工作。
bash ls -l /opt/certs/bundle.pem sudo chmod 0644 /opt/certs/bundle.pem curl --cacert "$(realpath /opt/certs/bundle.pem)" https://api.example.com/
相关错误
curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)cURL error 77: error setting certificate file: /etc/ssl/missing-ca.pemPHP ext-curl (Guzzle, Laravel HTTP client)Warning: Ignoring extra certs from `/etc/ssl/private-ca/corp-root-ca.pem`, load…Node.js start-up