python - Python 使用内部 CA 请求 SSLError
问题描述
我的公司为内部服务运营自己的内部 CA,我需要访问连接 Ansible AWX [python] 以与我们使用由该 CA 签名的证书的内部服务之一进行通信。基本上:
- AWX 启动了一个安装在其中的容器
awx_task
,/etc/pki/ca-trust/source/anchors
其中包含根 CA 证书。[双重检查] update-ca-trust
运行,将 CA 证书捆绑到各种东西中,包括/etc/pki/tls/certs/ca-bundle.crt
. [双重检查]requests
应该使用这个捆绑包。我无法在容器内或主机上找到与 CA 相关的环境变量来覆盖它。
但是,当我触发在其中运行的 Ansible 游戏的测试运行时,awx_task
我得到了错误:
requests.exceptions.SSLError: HTTPSConnectionPool(host='vault.example.com', port=443): 最大重试次数超出了 url: / (由 SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败) _ssl.c:618)'),))
在主机上我可以运行
import requests
requests.get("https://vault.example.com")
并得到200
回应,如果strace
我可以看到它正在阅读的过程/etc/pki/tls/certs/ca-bundle.crt
。但从里面awx_task
我得到的requests.exceptions.SSLError
和上面一样。不幸的是,Docker 不允许我在容器内运行 strace,所以我看不到它试图读取的内容。
但是,如果我将代码修改为:
import requests
requests.get("https://vault.example.com", verify="/etc/pki/tls/certs/ca-bundle.crt")
200
我从容器内部得到响应。
我在这里想念什么?
解决方案
问题是@Will 指出的,当前版本的 Requests 使用完全独立于 OpenSSL 的 Certifi 包。捆绑包 PEM 实际上位于 Python 站点包目录中的某个位置。
在不修改代码的情况下,您可以使用环境变量覆盖它:
REQUESTS_CA_BUNDLE=/etc/pki/tls/certs/ca-bundle.crt
社论:这是强制执行 CA 信任的绝对荒谬的方式。如果您想减少系统信任,请在系统级别减少它。我真的厌倦了追逐分散在源代码树中的随机 PEM 包 [可能永远不会更新] 只是因为一些#devoops nutbag 认为他知道如何比实际操作更好地运行系统,并将他们的坏主意分流给毫无戒心的系统。
(ノಠ益ಠ)ノ彡┻━┻</p>
推荐阅读
- string - 仅在不是空字符串时打印
- r - grid.arrange 两个具有相同 y 轴刻度的图
- javascript - 如何模拟慢速互联网连接以测试网页?
- python - 如何使用按钮在 django 服务器中运行 python 脚本
- ionic-framework - 如何在离子中默认禁用白色闪屏?
- xamarin.forms - 为 iOS Xamarin 表单执行远程构建时出现 Prism Navigation 错误
- c - 为什么 UTF-8 输出到 C 控制台可以与 Cygwin 一起使用,但不能与 MinGW 一起使用?
- javascript - Angular - 在项目中保留变量的最佳方法
- javascript - API 响应正文在 IDE 上被视为字符串,但在本地托管服务器上显示时被视为对象
- entity-framework-core - EF Core 中的一对一关系抛出