修复 SSL Certificate Problem,如何定位及常见问题的处理策略

·  阅读 742

在开发过程中,使用 curl 进行请求或 git 克隆远程仓库时,可能会经常遇见一些 https 证书相关的错误,我们整理了一些常见的错误以及解决方案的汇总,保持更新,也欢迎你在评论中提供其他更好的方案。

知识补充:SSL / TLS 是什么?

传输层安全协议(Transport Layer Security,缩写:TLS)及其前身 SSL( Secure Sockets Layer),是客户端(Web 浏览器)与服务器端(Web sever)之间 🔐 加密通信的安全标准协议,**目的是为互联网通信提供安全及数据完整性保障,**目前已经成为互联网保密通信的工业标准。

如何定位和分析错误信息

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:curl.se/docs/caextr…

如何获取自签名证书的方法不在这里赘述。

其他客户端程序也会遇到类似问题,比如 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
复制代码

另外,有一些极少数的情况,被防火墙或杀毒禁止也会出现该问题,可以尝试关闭这些软件来验证是否可以解决。

相关问题:fatal: unable to access 'https://company.domain/project.git': SSL certificate problem: certificate has expired

如果你是在 2021 年 9 月之后遇到该问题,有可能是受到了 Let's Encrypt DST Root CA X3 Expiration (September 2021) 的影响,可以尝试以下的方法来解决。

# 编辑文件 /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 升级到最新版本,会解决该问题。

相关资料


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改