使用自签名证书请求REST API时SSL验证失败,跨环境异常排查求助
问题:跨环境下SSL证书验证失败排查
我使用SSL证书向REST API发送请求,编写的代码如下:
import requests import os url = "https://ip_address/api" headers = { 'Authorization': 'Bearer bearer_token' } path = os.path.join("/","tmp") response = requests.request("GET", url, headers=headers, verify=os.path.join(path, "certfile.pem")) print(response.status_code) print(response.content)
运行环境差异
正常运行环境
- 本地Ubuntu 22.04.1 LTS(Python 3.10.6)虚拟环境
- Docker容器(Python 3.10.4)
- Server 1(Ubuntu 20.04,Python 3.10)
- 同事的Windows 11(Python 3.9.6)及WSL(Ubuntu 22.04.1 LTS,Python 3.10.6)
报错环境
- 第二位同事:Ubuntu 22.04,Python 3.8/3.9
- 第三位同事:Ubuntu 22.04,Python 3.9/3.6
- Server 2(QRadar):RHEL,Python 3.6
- Server 3:Ubuntu 22.04,Python 3.8
报错信息
所有报错环境均返回相同错误:
requests.exceptions.SSLError: HTTPSConnectionPool(host='xx.xx.xx.xxx', port=443): Max retries exceeded with url: /api/users/self (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:877)'),))
我尝试更换requests、urllib3、httpx库运行脚本,结果一致:能正常运行的环境用任何库都正常,报错的环境换库仍然报错。请问问题可能出在哪里?
可能的排查方向
- Python版本关联的SSL库差异:Python 3.10及以上默认搭配的OpenSSL版本通常高于3.9及以下版本,API服务器使用的SSL/TLS协议、加密套件或证书类型(如ECDSA)可能在旧版OpenSSL中不被支持,或者证书链验证逻辑存在版本差异。
- 证书文件与系统根证书问题:
- 检查报错环境中
/tmp/certfile.pem的读取权限,确保运行脚本的用户能访问该文件; - 用命令
openssl x509 -in /tmp/certfile.pem -text -noout验证证书完整性、格式是否正确; - 部分系统可能要求证书链包含中间证书,旧系统的根证书存储可能缺少API服务器依赖的根证书。
- 检查报错环境中
- SNI支持缺陷:旧版Python/OpenSSL组合可能存在SNI(Server Name Indication)支持问题,即使请求用的是IP地址,部分服务器配置仍需SNI才能正确返回对应证书。
- 系统SSL配置限制:检查报错系统的SSL配置文件(如Ubuntu的
/etc/ssl/openssl.cnf、RHEL的/etc/pki/tls/openssl.cnf),是否禁用了API服务器所需的SSL/TLS协议版本或加密套件。
内容的提问来源于stack exchange,提问作者Python_coding
相关产品推荐
相关产品推荐

