You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Requests请求SSL证书验证失败问题求助

解决CentOS 8上Python requests的SSL证书验证失败问题

问题情况

本地Windows 10机器上运行的Python脚本,通过requests库调用内部API完全正常,但部署到RHEL CentOS 8服务器时,出现SSL证书验证失败错误:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

要求必须保持SSL验证,不能使用verify=False的不安全方式。

已知信息

  • 使用Python的requests库发起请求
  • 自行创建了用于验证的.pem文件,格式为多份证书拼接:
    -----BEGIN CERTIFICATE-----
    **********************************
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    **********************************
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    **********************************
    -----END CERTIFICATE-----
    
  • 脚本在两台机器上完全一致
  • 服务器可向其他系统发起正常的SSL验证请求
  • 目标API使用的加密套件在openssl ciphers输出列表中存在
  • 请求代码:
    response = requests.get(team_search, auth=(api_id, api_key), headers=headers, verify=certificate)
    

完整错误回溯

Traceback (most recent call last):
  File "/path/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/path/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)
  File "/path/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1042, in _validate_conn
    conn.connect()
  File "/path/.local/lib/python3.9/site-packages/urllib3/connection.py", line 414, in connect
    self.sock = ssl_wrap_socket(
  File "/path/.local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "/path/.local/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib64/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/lib64/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/lib64/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/.local/lib/python3.9/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/path/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "/path/.local/lib/python3.9/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='api.veracode.com', port=443): Max retries exceeded with url: /api/authn/v2/teams/?page=0&size=1000 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/WebApps/access-review-test/PAR/manage.py", line 21, in <module>
    main()
  File "/path/WebApps/access-review-test/PAR/manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/path/.local/lib/python3.9/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/path/.local/lib/python3.9/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/path/.local/lib/python3.9/site-packages/django/core/management/base.py", line 414, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/path/.local/lib/python3.9/site-packages/django/core/management/base.py", line 460, in execute
    output = self.handle(*args, **options)
  File "/path/WebApps/access-review-test/PAR/AccessReview/management/commands/update_veracodeusers.py", line 41, in handle
    response = requests.get(team_search, auth=RequestsAuthPluginVeracodeHMAC(api_id, api_key), headers=headers, verify=certificate)
  File "/path/.local/lib/python3.9/site-packages/requests/api.py", line 73, in get
    return request("get", url, params=params, **kwargs)
  File "/path/.local/lib/python3.9/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
  File "/path/.local/lib/python3.9/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/path/.local/lib/python3.9/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/path/.local/lib/python3.9/site-packages/requests/adapters.py", line 563, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.veracode.com', port=443): Max retries exceeded with url: /api/authn/v2/teams/?page=0&size=1000 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))

解决方案

1. 确保.pem包含完整的证书链

本地Windows可能自动补充缺失的根/中间证书,但CentOS不会。执行以下命令提取目标API的完整证书链:

openssl s_client -connect api.veracode.com:443 -showcerts

将输出中所有-----BEGIN CERTIFICATE-----到-----END CERTIFICATE-----的内容按顺序拼接,替换现有.pem文件,确保从服务器证书、中间证书到根证书的完整链条都包含。

2. 检查证书文件的权限和路径

  • 确保脚本运行用户能读取.pem文件,设置权限:
    chmod 644 /path/to/your/certificate.pem
    
  • 脚本中verify参数使用绝对路径,避免相对路径导致服务器上找不到文件。

3. 合并系统默认CA证书与自定义证书

如果自定义.pem仅包含中间证书,可将系统默认的CA根证书合并进去:

cat /etc/pki/tls/certs/ca-bundle.crt /path/to/your/certificate.pem > /path/to/combined_certs.pem

然后修改脚本,将verify指向合并后的combined_certs.pem。

4. 配置Python的SSL验证环境

  • 查看Python默认的证书路径:
    python -c "import ssl; print(ssl.get_default_verify_paths())"
    
  • 若虚拟环境使用独立的CA存储,可设置环境变量让requests全局使用自定义证书:
    export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
    
    或在脚本开头添加:
    import os
    os.environ['REQUESTS_CA_BUNDLE'] = '/path/to/your/certificate.pem'
    

内容的提问来源于stack exchange,提问作者Sogetsue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:56:07