requests证书验证失败,但urllib3与curl验证成功的问题排查
Requests自签名证书验证失败,但Urllib3和Curl正常的排查方向
我尝试向使用自签名证书的站点发送GET请求,已导出链式证书为PEM文件,但使用requests库调用时报错,而urllib3和curl使用相同证书能成功。相关版本:
- requests 2.32.4
- urllib3 2.5.0
requests代码及报错:
import requests requests.get("https://bvs.skala", verify='/home/user/bvs-skala-chain.pem')
报错信息:
requests.exceptions.SSLError: HTTPSConnectionPool(host='bvs.skala', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:979)')))
urllib3和curl均能正常请求,已尝试设置REQUESTS_CA_BUNDLE和CURL_CA_BUNDLE环境变量但无效,以下是具体排查方向:
1. 检查PEM证书文件的格式与内容
- 证书链顺序验证:自签名证书链要求服务器证书在前,中间证书(若有)居中,根证书在最后。用以下命令查看证书顺序:
Requests对证书链顺序的校验可能比Urllib3更严格,顺序错误会直接导致验证失败。openssl crl2pkcs7 -nocrl -certfile /home/user/bvs-skala-chain.pem | openssl pkcs7 -print_certs -text - 文件完整性检查:确保PEM文件中没有多余空行、注释,每个证书块都是完整的
-----BEGIN CERTIFICATE-----到-----END CERTIFICATE-----结构。
2. 验证Requests对verify参数的处理
- 权限与路径检查:确认证书文件的绝对路径正确,且当前用户有读取权限:
权限至少设置为ls -l /home/user/bvs-skala-chain.pem644(保证其他用户可读)。 - 内存加载证书测试:尝试将证书内容读入内存后传递给
verify,绕过文件路径的潜在问题:import requests with open('/home/user/bvs-skala-chain.pem', 'r') as f: cert_content = f.read() requests.get("https://bvs.skala", verify=cert_content) - 开启Debug日志:查看Requests是否正确加载了指定证书:
日志中会显示证书加载路径及验证过程,可定位是否存在路径错误或未加载指定证书的问题。import requests import logging logging.basicConfig(level=logging.DEBUG) requests.get("https://bvs.skala", verify='/home/user/bvs-skala-chain.pem')
3. 排查Requests与Urllib3的兼容性
- 降级Urllib3测试:虽然Requests 2.32.4兼容Urllib3 2.x,但部分版本组合可能存在适配问题。尝试降级到Urllib3 2.0.x版本:
重新运行Requests代码看是否解决问题。pip install urllib3==2.0.7 - 检查自定义适配器:确认是否有其他库或代码修改了Requests的默认Urllib3适配器,导致证书验证逻辑被覆盖。
4. 排除环境变量与系统CA干扰
- 显式设置环境变量:确保环境变量在Requests导入前设置,避免启动时读取默认值:
import os os.environ['REQUESTS_CA_BUNDLE'] = '/home/user/bvs-skala-chain.pem' import requests requests.get("https://bvs.skala") - 查看默认CA路径:通过
requests.utils.DEFAULT_CA_BUNDLE_PATH查看Requests默认使用的CA证书路径,确认是否存在系统级CA与自定义证书冲突的情况:import requests print(requests.utils.DEFAULT_CA_BUNDLE_PATH)
5. 用OpenSSL直接验证证书链
- 使用OpenSSL命令测试证书链是否能正确验证目标站点:
查看输出中的openssl s_client -connect bvs.skala:443 -CAfile /home/user/bvs-skala-chain.pemVerify return code,若为0说明证书链本身无问题;若不为0,需排查证书过期、域名不匹配等基础问题。
内容的提问来源于stack exchange,提问作者Renat Zaripov
相关产品推荐
相关产品推荐

