在开发过程中,使用 curl 进行请求或 git 克隆远程仓库时,可能会经常遇见一些 https 证书相关的错误,我们整理了一些常见的错误以及解决方案的汇总,保持更新,也欢迎你在评论中提供其他更好的方案。
知识补充:SSL / TLS 是什么?
传输层安全协议(Transport Layer Security,缩写:TLS)及其前身 SSL( Secure Sockets Layer),是客户端(Web 浏览器)与服务器端(Web sever)之间 🔐 加密通信的安全标准协议,目的是为互联网通信提供安全及数据完整性保障,目前已经成为互联网保密通信的工业标准。
- SSL 最新的技术应用趋势及供应商(SSL certificate authority)的市场分布。
- SSL 证书在线检查工具:What's My Chain Cert? | SSL Certificate Checker - Diagnostic Tool | DigiCert.com
- 如果你想为 Server 站点构建免费的 SSL 证书,可以考虑使用 Let’s Encrypt :Let's Encrypt | Certbot
如何定位和分析错误信息
Tips: 设置 debug 模式有助于你追踪和定位具体问题真实原因所在(GIT_CURL_VERBOS 仅在 http/s 传输协议下有效)
# On Linux
export GIT_CURL_VERBOSE=1
export GIT_TRACE_PACKET=1
export GIT_TRACE=1
# On Window
set GIT_TRACE_PACKET=1
set GIT_TRACE=1
set GIT_CURL_VERBOSE=1
# 如果当前机器有安装 python,可以快速检查证书路径,辅助定位解决问题
python -c "import ssl; print(ssl.get_default_verify_paths())"
# 使用 openssl 检查站点的证书情况
openssl s_client -showcerts -connect
常见问题
问题:SSL certificate problem: unable to get local issuer certificate
原因:
如果使用自签名证书(self-signed certificate)无法被认证时,git 或者 curl 等客户端程序无法信任该 server 的证书,且在 Window 环境中,会因为环境配置的问题导致该类问题的出现。
解决方案:
遇到该类问题,临时的全局处理方案是去禁用证书验证, ⚠️ 要注意这种做法会有潜在的安全风险(可能引发中间人攻击 MitM attacks)。
# 使用 git 操作的全局处理措施
# http.sslBackend: Name of the SSL backend to use (e.g. "openssl" or "schannel").
# This option is ignored if cURL lacks support for choosing the SSL backend at runtime.
git config --global http.sslBackend schannel
# 或者
# http.sslVerify: A boolean to enable/disable verification of the server certificate used by the SSL/TLS connection.
# ⚠️ Do NOT do this!
git config --global http.sslVerify false
# 亦可以直接设置环境变量运行 git 操作
GIT_SSL_NO_VERIFY=true git clone https://username@git.example.com/scm/repository.git
# Git Config Option Ref: https://git-scm.com/docs/git-config
如果可以从 server 端拿到 certificate.pem 文件,可以尝试告诉 git 程序,CA(Certificate Authority) bundle 文件的位置来解决该问题:
# Convert the file into the X.509 format
# openssl-x509, x509 - Certificate display and signing utility
# https://www.openssl.org/docs/man1.0.2/man1/x509.html
openssl x509 -in certificate.pem -out certificate.crt
git config --system http.sslCAInfo /path/certificate.crt
# 或者可以修改 .gitconfig 的配置项目,然后重新安装一下 git
git config --global -e
[http "https://your.domain.com"]
# MUST be PEM format
# Some situations require both the CAPath AND CAInfo
sslCAInfo = /path/to/selfCA/self-signed-certificate.crt
sslCAPath = /path/to/selfCA/
sslVerify = true
# Must be PEM format and include BEGIN CERTIFICATE / END CERTIFICATE,
# not just the BEGIN PRIVATE KEY / END PRIVATE KEY for Git to recognise it.
sslCert = /path/to/privatekey/myprivatecert.pem
# Even if your PEM file is password protected, set this to false.
# Setting this to true always asks for a password even if you don't have one.
# When you do have a password, even with this set to false it will prompt anyhow.
sslCertPasswordProtected = 0
Tips:CA bundle 是一个包含根证书和中间证书的文件,与实际证书文件构成了完整的证书链。可以通过以下方式来获取 bundle 文件:cURL:https://curl.se/docs/caextract.html
如何获取自签名证书的方法不在这里赘述。
其他客户端程序也会遇到类似问题,比如 pip / conda / node,可以尝试用类似的思路来解决:
# curl code:
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
# python package
pip config set global.cert path/to/ca-bundle.crt
# conda package
conda config --set ssl_verify path/to/ca-bundle.crt
另外,有一些极少数的情况,被防火墙或杀毒禁止也会出现该问题,可以尝试关闭这些软件来验证是否可以解决。
如果你是在 2021 年 9 月之后遇到该问题,有可能是受到了 Let's Encrypt DST Root CA X3 Expiration (September 2021) 的影响,可以尝试以下的方法来解决。
- Ubuntu 14.04 LTS (Trusty Tahr) or Ubuntu 16.04.6 LTS (Xenial Xerus) 运行环境:
# 编辑文件 /etc/ca-certificates.conf, 找到该证书并注释
!mozilla/DST_Root_CA_X3.crt
# 或者直接命令行处理
sudo sed -i -e 's/mozilla\/DST_Root_CA_X3\.crt/!mozilla\/DST_Root_CA_X3\.crt/g' /etc/ca-certificates.conf
# 保存文件后运行命令
sudo rm /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt
sudo update-ca-certificates
- Mac OS X 10.13.6 (High Sierra) 上面, cURL(and therefore Git) 依赖于
/etc/ssl/cert.pem
去处理根证书认证,你可以手动移除 DST Root CA X3 - 如果你有使用 certbot 也需要升级到最新版本,renew 站点证书去移除 DST Root CA X3 的潜在问题
sudo certbot renew --force-renewal --preferred-chain "ISRG Root X1"
在 Window 环境中,你可以尝试把 git 升级到最新版本,会解决该问题。
相关资料
- KSE Manual - User Interface Overview
- Git for Windows: SSL certificate problem: certificate has expired
- DST Root CA X3 Expiration (September 2021) - Let's Encrypt
本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。
作者:Lone神 / 自由工程师
文章备份地址(保持更新): https://whycode.yousails.com/d/1-ssl-certificate-problem