git over HTTPS with libcurl-gnutls (Debian, Ubuntu)Git
错误信息
fatal: unable to access 'https://git.example.com/team/app.git/': SSL: certificate subject name (www.example.com) does not match target hostname 'git.example.com'
也可能输出为
- SSL: certificate subject name (www.example.com) does not match target host name 'git.example.com'
括号和引号中的名称分别来自你的证书和远程仓库 URL。libcurl 7.x 打印“target host name”,libcurl 8.x 打印“target hostname”。基于 OpenSSL 构建的 git(Git for Windows、Alpine)打印的是“SSL: no alternative certificate subject name matches target hostname '…'”。
含义
Git 服务器的证书是受信任的,但它签发给的名称与远程仓库 URL 中的主机不同。libcurl-gnutls 在括号中引用证书的主体名称,在末尾给出 git 所连接的主机。凭证没有发送出去:连接在发出任何 HTTP 请求之前就终止了。
原因
证书中没有列出 Git 主机的名称
常见Git 服务器换了新名称(用 git.example.com 代替 gitlab.example.com),或者增加了第二个名称,却没有重新签发证书。
远程仓库 URL 使用了别名或 IP 地址
常见用内部别名、IP 地址或旧主机名克隆的仓库,会把那个 URL 一直保留在配置文件 .git/config 中,即使证书早已为规范名称签发。
Git 服务器前面的代理发送了它的默认证书
偶见如果反向代理或 Ingress 没有为请求的名称配置规则,就会出示另一个虚拟主机的证书。
修复方法
- 1.
将远程仓库 URL 与证书比对
打印远程仓库 URL 以及证书的主体和 SAN 列表;不匹配之处通常一目了然。
bash git remote get-url origin echo | openssl s_client -connect git.example.com:443 -servername git.example.com 2>/dev/null \ | openssl x509 -noout -subject -ext subjectAltName - 2.
让远程仓库指向证书覆盖的名称
git remote set-url 会修改仓库配置中保存的 URL,无需重新克隆。
bash # Use the name the certificate was issued for git remote set-url origin https://gitlab.example.com/team/app.git - 3.
服务器所有者:为对外公布的名称签发证书
让证书的 SAN 列表与 Git 服务器对外提供的克隆 URL(GitLab 的 external_url、Gitea 的 ROOT_URL)一致,这样用户复制的 URL 就能通过验证。
text # GitLab Omnibus: the external URL decides the certificate name and the clone URLs external_url "https://git.example.com" # then: sudo gitlab-ctl reconfigure
相关错误
curl: (60) SSL: no alternative certificate subject name matches target hostname…curl (OpenSSL backend)fatal: unable to access 'https://git.example.com/team/app.git/': server verific…git over HTTPS with libcurl-gnutls (Debian, Ubuntu)The certificate's owner does not match hostname 'api.example.com'GNU Wget (GnuTLS build); the alias is the OpenSSL build's wording