十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

pip 的 HTTPS 证书验证完全指南:自定义 CA 证书库与系统信任存储(truststore)机制解析

pip 的 HTTPS 证书验证完全指南:自定义 CA 证书库与系统信任存储(truststore)机制解析 包管理器开发工具【免费下载链接】pipThe Python package installer项目地址https://gitcode.com/gh_mirrors/pi/pip点击查看免费下载pip 在通过 HTTPS 下载包时默认执行 SSL 证书验证以防范针对软件包下载的中间人攻击。本文以 docs/html/topics/https-certificates.md 为主线系统讲解 pip 的证书验证默认行为、如何用--cert/PIP_CERT/REQUESTS_CA_BUNDLE/CURL_CA_BUNDLE指定自定义 CA 证书库以及 pip 24.2 起默认集成系统证书库基于 truststore的实现细节与退出开关。读完本文你将能够根据企业内网、私有索引、代理环境等不同场景准确配置 pip 的证书验证策略并能理解其底层调用链以便排查 TLS/SSL 故障。pip 默认的证书验证行为为什么需要它从 pip 1.3 版本开始pip 对其发起的每一个 HTTPS 网络连接都会执行 SSL 证书验证。这一点在官方文档中被明确强调证书验证的目的是防止针对软件包下载的中间人攻击man-in-the-middle——如果没有验证攻击者可以在网络链路上伪装成 PyPI 或任意软件源向你分发被篡改的包。这一默认行为在源码中有清晰体现。在 src/pip/_internal/network/session.py 中pip 维护了一份安全来源secure origin白名单SECURE_ORIGINS: list[SecureOrigin] [ # protocol, hostname, port (https, *, *), # 任何 HTTPS 来源 (*, localhost, *), # 本机回环 (*, 127.0.0.0/8, *), (*, ::1/128, *), (file, *, None), (ssh, *, *), # ssh 始终视为安全 ]当目标来源匹配安全白名单时pip 使用执行证书验证的 HTTPS 适配器HTTPAdapter或CacheControlAdapter而不在名单内的 HTTP 来源会被忽略并记录警告。这套机制同时解释了另一个常见现象pip 对http://来源使用InsecureHTTPAdapter其cert_verify方法强制以verifyFalse关闭验证见 session.py 的 InsecureHTTPAdapter因为明文 HTTP 本来就没有任何证书可言。使用特定证书库--cert 与相关环境变量默认情况下pip 使用随自身分发的certifi证书包当前仓库内 vendored 版本为certifi2026.7.22见 src/pip/_vendor/vendor.txt。如果你的公司或机构使用自建的 CA 签发的证书或者你依赖某个特定的证书捆绑包就需要覆盖这一默认行为。--cert 命令行参数--cert允许用户为 pip 指定不同的证书库certificate store / bundlepip install --cert /path/to/my-ca-bundle.pem some-package该参数在 src/pip/_internal/cli/cmdoptions.py 中的定义如下cert: Callable[..., Option] partial( PipOption, --cert, destcert, typepath, metavarpath, help( Path to PEM-encoded CA certificate bundle. If provided, overrides the default. See SSL Certificate Verification in pip documentation for more information. ), )要点值必须是PEM 编码的 CA 证书捆绑包文件路径typepath一旦提供会覆盖默认证书库即不再单独使用 certifi它是通用选项属于general_group见 cmdoptions.py 的 general_group因此适用于 install、download、wheel、index 等所有会访问网络的子命令由于是通用选项同样可以写入 pip 配置文件例如pip.conf的[global]段[global] cert /etc/ssl/certs/my-company-ca.pem环境变量PIP_CERT、REQUESTS_CA_BUNDLE、CURL_CA_BUNDLE官方文档明确列出的环境变量包括环境变量作用PIP_CERT--cert的环境变量形式优先级与命令行参数一致命令行参数会覆盖REQUESTS_CA_BUNDLE传统 requests 生态约定的 CA bundle 环境变量被 pip 的网络栈兼容识别CURL_CA_BUNDLEcurl 生态约定的 CA bundle 环境变量同样被兼容识别一个典型的用法示例export PIP_CERT/path/to/my-ca-bundle.pem pip install some-package值得一提的是pip debug命令会在输出中列出当前环境中这两个 curl/requests 生态变量的值见 tests/functional/test_debug.py 中对REQUESTS_CA_BUNDLE:与CURL_CA_BUNDLE:输出的断言因此当你怀疑环境变量影响验证结果时可先运行pip debug检查。获取一份特定的 CA bundle如果你需要一个现成的权威证书捆绑包官方文档建议使用 curl 项目提供的Mozilla CA bundleCA 证书提取自 Mozilla 的根证书库。得到.pem文件后即可通过上面的--cert或PIP_CERT交给 pip 使用。对于离线内网环境这也是把 CA 证书注入 pip 的最直接方式。使用系统证书库truststore 与 pip 24.2 的行为变更版本演进从 opt-in 到默认开启pip 版本行为 22.2不使用系统证书22.2 起需要显式--use-featuretruststore才使用系统证书opt-in24.2 起默认使用系统证书与 certifi 叠加用于验证 HTTPS 连接也就是说从 pip 24.2 开始pip 在验证 HTTPS 连接时同时使用系统证书库与 certifi无需任何配置。这解决了企业环境中最常见的痛点内网代理或私有 PyPI 使用企业自签 CA 时只要该 CA 已导入操作系统信任库macOS 钥匙串、Windows 证书存储、Linux 的 /etc/ssl/certs 等pip 就能直接信任不必再手动导出证书文件。truststore 是什么这一功能由truststore包提供。当前仓库将truststore0.10.4作为 vendored 依赖内置见 src/pip/_vendor/vendor.txt 与 src/pip/_vendor/truststore/init.py。truststore 的核心能力是让 Python 的ssl.SSLContext直接加载操作系统原生的信任存储而不是依赖独立的 CA 文件。它要求 Python 3.10 及以上版本且需要运行时可用的SSLObject.get_unverified_chain()相关 API。源码级实现truststore 上下文是如何被创建的在 src/pip/_internal/cli/index_command.py 中pip 创建 truststore SSL 上下文的过程如下lru_cache def _create_truststore_ssl_context() - SSLContext | None: try: import ssl except ImportError: logger.warning(Disabling truststore since ssl support is missing) return None try: from pip._vendor import truststore except ImportError: logger.warning(Disabling truststore because platform isnt supported) return None ctx truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.load_verify_locations(certifi.where()) return ctx几个值得注意的实现细节certifi 仍在参与truststore 上下文通过load_verify_locations(certifi.where())把 certifi 的 bundle 也加载进去这就是文档所说系统证书与 certifi 叠加使用的直接证据优雅降级如果 Python 缺少ssl模块或当前平台不支持 truststorepip 会记录警告并返回None退化为纯 certifi 验证而不是报错中断结果缓存lru_cache保证同一进程中只创建一次 SSL 上下文。遇到 TLS/SSL 错误时该找谁官方文档有一个明确的运维提示当使用 truststore 功能遇到 TLS/SSL 错误时应当向 truststore 项目的维护者反馈问题在 truststore 的 GitHub issue 跟踪器中提交而不是向 pip 的 issue 跟踪器提交。因为该环节的证书加载与系统信任库解析逻辑完全由 truststore 负责其维护者才具备诊断和修复该问题所需的上下文。pip 侧的适配层_SSLContextAdapterMixin只是把 truststore 生成的SSLContext透传给网络适配器。功能测试佐证tests/functional/test_truststore.py 提供了一个pip_no_truststorefixture它在每次调用时附加--use-deprecatedlegacy-certs参数并验证关闭 truststore 后依然可以正常安装 PyPI 包与 GitHub 直接下载的包。这说明 truststore 与 legacy 证书路径在功能上是等价的只是信任来源不同。退出系统证书--use-deprecatedlegacy-certs如果系统证书库的引入反而造成了问题例如系统信任库被污染、或你希望严格只信任 certifipip 提供了退出开关pip install --use-deprecatedlegacy-certs some-package该标志名为legacy-certs是--use-deprecated选项的合法取值之一。选项定义见 src/pip/_internal/cli/cmdoptions.pyuse_deprecated_feature: Callable[..., Option] partial( Option, --use-deprecated, destdeprecated_features_enabled, metavarfeature, actionappend, default[], choices[ legacy-resolver, legacy-certs, ], help(Enable deprecated functionality, that will be removed in the future.), )在 index_command.py 的 _build_session 中是否启用系统证书正是通过检查该选项决定的if legacy-certs not in options.deprecated_features_enabled: ssl_context _create_truststore_ssl_context() else: ssl_context None即传了legacy-certs时ssl_context为Nonepip 走纯 certifi 的默认验证路径否则创建 truststore 上下文。由于它被标记为--use-deprecated可以预期该选项在未来版本中会被移除届时系统证书验证将成为唯一路径。证书验证的完整调用链从参数到 TLS 握手把上面几节串起来一次pip install的证书验证调用链大致如下参数解析--cert、--client-cert、--use-deprecated等选项由 cmdoptions.py 定义并进入options会话构建_build_session()index_command.py按legacy-certs与否创建ssl_context随后session.verify options.cert用户指定自定义 CA bundle 时生效session.cert options.client_cert设置 TLS 客户端证书一个包含私钥与证书的 PEM 文件适配器挂载PipSessionnetwork/session.py将ssl_context注入HTTPAdapter/CacheControlAdapter两者继承自_SSLContextAdapterMixin并分别挂载到https://、http://、file://TLS 握手urllib3 连接池使用该ssl_context完成证书链校验。其中_SSLContextAdapterMixinnetwork/session.py有两个值得注意的细节init_poolmanager把ssl_context通过pool_kwargs传给连接池实现运行时动态决定使用哪套证书库proxy_manager_for除了设置ssl_context还设置了proxy_ssl_context当通过 HTTPS 代理连接时urllib3 对代理本身会另开一条 TLS 连接隧道建立前必须让这条代理连接也使用同一套truststoreSSL 上下文否则代理这条腿会用普通默认上下文验证产生虚假的证书错误。这一行为有对应的单元测试保护见 tests/unit/test_network_session.py 的 TestSSLContextAdapterMixinProxy其中断言proxy_manager.proxy_ssl_context is ssl_context。实践建议与故障排查清单内网/私有索引使用自签 CA优先把 CA 导入操作系统信任库并升级到 pip ≥ 24.2即可免配置生效无法升级时用--cert pem路径或PIP_CERT显式指定希望与 curl 保持一致的证书行为设置CURL_CA_BUNDLE或REQUESTS_CA_BUNDLE指向同一 bundle出现证书错误且已配置系统 CA先用pip debug检查环境变量是否被意外设置、再用pip install --use-deprecatedlegacy-certs对比验证是否是 truststore 路径的问题若是则按官方指引转向 truststore 项目反馈而不是 pip 仓库需要双向 TLS客户端证书的索引使用--client-cert 单文件PEM私钥与证书在同一文件明确只有 certifi 可信禁用系统证书库使用--use-deprecatedlegacy-certs。延伸阅读官方文档原文docs/html/topics/https-certificates.md证书参数与--use-deprecated定义src/pip/_internal/cli/cmdoptions.pytruststore SSL 上下文创建与会话构建src/pip/_internal/cli/index_command.py会话与适配器实现含安全来源白名单、代理 SSL 上下文src/pip/_internal/network/session.pytruststore 与 certifi 的 vendored 版本见 src/pip/_vendor/truststore/init.py 与 src/pip/_vendor/vendor.txt相关测试tests/functional/test_truststore.py、tests/unit/test_network_session.py、tests/functional/test_debug.py赞分享包管理器开发工具【免费下载链接】pipThe Python package installer项目地址https://gitcode.com/gh_mirrors/pi/pip点击查看免费下载相关推荐curl HTTPS/TLS 证书校验全指南验证原理、CA 信任存储管理与排障实战curl HTTPS/TLS 证书校验全指南验证原理、CA 信任存储管理与排障实战 这篇技术指南以 docs/SSLCERTS.md https://linkCLI网络通信DBeaver插件证书信任存储管理维护自定义CA证书的方法DBeaver插件证书信任存储管理维护自定义CA证书的方法 你是否在使用DBeaver连接数据库时遇到过SSL证书验证失败的问题特别是当数据库使用自签名证书数据库客户端桌面应用数据库Traefik 证书配置完全指南用户自定义证书、证书存储与默认证书Certificates StoresTraefik 证书配置完全指南用户自定义证书、证书存储与默认证书Certificates Stores 本篇技术指南围绕 Traefik云原生应用后端API网关负载均衡微服务网络云原生上一篇Windows热键冲突终极指南3分钟定位占用快捷键的元凶下一篇Windows热键冲突检测终极指南3分钟找出占用快捷键的程序创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表