跳到主要内容
ecdsa.com
git over HTTPS with libcurl + OpenSSL (Git for Windows default, macOS Homebrew, Alpine, RHEL)Git

错误信息

fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificate problem: unable to get local issuer certificate

也可能输出为

  • fatal: unable to access 'https://git.example.com/team/app.git/': SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)

消息中的 URL 是你的远程仓库地址。使用 libcurl 8.22(可能还有其他较新版本)时,原因写作“SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)”。Debian 和 Ubuntu 构建的 git 使用 GnuTLS,打印的则是“server verification failed: certificate signer not trusted”。

含义

git 的 HTTPS 传输层使用 libcurl,而基于 OpenSSL 的 libcurl 找不到签发 Git 服务器所发送最后一张证书的 CA。要么服务器没有发送中间证书,要么证书链终止于不在 git 所用证书包中的根证书(公司 CA、代理 CA)。在 Windows 上,这是典型症状,说明 Git for Windows 对照自己附带的 CA 文件检查证书,而不是对照 Windows 证书存储。

原因

修复方法

  1. 1.

    Windows:让 git 改用 Windows 证书存储

    设置 http.sslBackend schannel 后,Git for Windows 通过 Windows 本身进行验证,接受 Windows 信任的所有根证书,包括通过组策略部署的根证书。对企业网络来说,这才是干净的修复方法。

    bash
    # Git for Windows: verify with the Windows certificate store, where IT deploys company roots
    git config --global http.sslBackend schannel
    git config --global --get http.sslBackend
  2. 2.

    只为一个 Git 主机信任该 CA

    按 URL 限定作用范围的 http.<url>.sslCAInfo 只为该主机添加私有 CA;GIT_SSL_CAINFO 只作用于单条命令或单个作业。

    bash
    git config --global http."https://git.example.com/".sslCAInfo /etc/ssl/private-ca/corp-root-ca.pem
    # one command or CI job only
    GIT_SSL_CAINFO=/etc/ssl/private-ca/corp-root-ca.pem git clone https://git.example.com/team/app.git
  3. 3.

    把根证书安装到系统证书包

    在 Linux 上,libcurl 默认读取的就是系统证书包,因此把根证书添加到这里,可以同时修复 git、curl 和包管理器。

    bash
    # Alpine / Debian / Ubuntu
    cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && update-ca-certificates
    # RHEL / Fedora
    cp corp-root-ca.pem /etc/pki/ca-trust/source/anchors/ && update-ca-trust
  4. 4.

    查找替换了证书包的覆盖设置

    --show-origin 会显示哪个配置文件设置了 CA 路径。删除本应只作用于单个主机的全局覆盖设置。

    bash
    git config --show-origin --get-all http.sslCAInfo
    git config --show-origin --get-regexp 'http\..*\.sslcainfo'
    env | grep -E 'GIT_SSL_CAINFO|CURL_CA_BUNDLE|SSL_CERT_FILE'
  5. 5.

    临时诊断:只对一条命令跳过验证

    -c http.sslVerify=false 只能用来确认诊断结果,切勿写入全局配置:它会暴露凭证,并让传输路径上的任何人都能篡改你拉取的代码。

    bash
    # Diagnostic only, for one command
    git -c http.sslVerify=false ls-remote https://git.example.com/team/app.git

相关错误

浏览完整的签名错误库