Ubuntu服务器Python请求SSL证书验证失败问题求助
解决Python请求SSL证书验证失败问题(curl正常但Python报错)
核心原因
Python的SSL证书信任池可能和系统(curl使用的)并非同一个。默认情况下,部分Python环境(比如通过pip安装的版本)会使用certifi包提供的独立证书池,而非系统级的受信任证书列表,这就导致你添加到系统的CA证书不被Python识别。
具体解决步骤
1. 确认Python使用的证书池路径
先检查Python当前默认的SSL验证路径,运行以下命令:
python -c "import ssl; print(ssl.get_default_verify_paths())"
对比输出中的openssl_cafile/openssl_capath和Ubuntu系统的CA路径(通常是/etc/ssl/certs/或/etc/ssl/certs/ca-certificates.crt),如果不一致,说明Python用的是独立证书池。
2. 将CA证书导入Python的证书池
如果Python使用certifi的证书池,先找到certifi的证书文件路径:
python -c "import certifi; print(certifi.where())"
将你的CA证书追加到该文件中(需要sudo权限):
sudo cat /path/to/your/ca.crt >> $(python -c "import certifi; print(certifi.where())")
3. 修正verify参数的使用
- 确保
verify指向的是包含完整信任链的PEM文件:如果目标网站的证书由中间CA签发,需要将根CA和中间CA证书合并成一个PEM文件:
然后在Python请求中使用:cat root_ca.crt intermediate_ca.crt > combined_trust.pemimport requests response = requests.get("https://target-site.com", verify="/path/to/combined_trust.pem") - 注意:
cert参数是用于双向SSL认证的(仅当服务器要求客户端提供证书时才需要),如果不需要客户端证书,直接去掉这个参数,避免干扰验证流程。
4. 强制Python使用系统CA证书
通过环境变量让Python使用系统级的受信任证书:
- 临时生效:运行脚本前先设置环境变量
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt python your_script.py - 永久生效:在脚本开头添加以下代码
import os os.environ['SSL_CERT_FILE'] = '/etc/ssl/certs/ca-certificates.crt'
5. 验证测试
用简单脚本验证修复效果:
import requests try: resp = requests.get("https://target-site.com") print(f"请求成功,状态码:{resp.status_code}") except Exception as e: print(f"错误详情:{str(e)}")
内容的提问来源于stack exchange,提问作者Elvin Jafarov
相关产品推荐
相关产品推荐

