Python requests模块SSL证书验证详解:从忽略验证到安全实践
1. 从一次“证书无效”的报错说起最近在写一个自动化脚本需要从公司内网一个自签了SSL证书的监控平台拉取数据。脚本很简单用Python的requests库几行代码就搞定了。然而一运行就给我当头一棒抛出了一个长长的SSLError核心信息是[SSL: CERTIFICATE_VERIFY_FAILED]翻译过来就是SSL证书验证失败。这个错误对于经常和HTTPS打交道的开发者来说简直是“老朋友”了。它背后代表的是requests库或者说底层的urllib3在严格履行其安全职责验证你正在通信的服务器身份是否可信。当它发现服务器的SSL证书无法被信任比如自签名、过期、域名不匹配时就会果断中止连接防止你掉入中间人攻击的陷阱。这个机制在访问公网正规网站时是完美的安全保障但一旦遇到开发测试环境、内部系统、或者一些老旧设备的管理界面自签名证书就成了常态。这时候我们往往需要一种“权宜之计”让程序能够暂时绕过严格的证书验证先把数据拿到手再说。这就是“忽略SSL证书”需求的典型场景。同时伴随而来的还有烦人的InsecureRequestWarning警告虽然不影响程序运行但满屏的黄色警告信息看着实在闹心也需要一并关闭。今天我们就来彻底聊聊在Python的requests模块中如何安全、正确地处理SSL证书验证以及关闭相关警告。我会结合自己的踩坑经验不仅告诉你“怎么做”更会深入解释“为什么这么做”以及在不同场景下的最佳实践和潜在风险。2. 理解SSL证书验证与verify参数在深入代码之前我们必须先搞清楚requests实际上是urllib3在进行HTTPS请求时到底做了什么。这个过程可以类比为你要进入一个高度机密的基地服务器。出示证件证书当你客户端尝试连接基地服务器时门卫requests库会要求基地出示其官方证件SSL证书。检查证件真伪验证签名门卫不会轻易相信一张白纸黑字的证件。他会检查这个证件是否由他信任的“发证机关”Certificate Authority, CA签发。你的操作系统或Python环境里预装了一份“可信发证机关名单”CA信任根证书库。门卫会用这份名单里的“公章”去核验证件上的签名。检查证件信息验证域名/有效期确认证件是真的之后门卫还要检查证件上的照片、姓名证书中的Common Name或Subject Alternative Names是否与你声称要访问的基地名称请求的URL域名一致。同时检查证件是否在有效期内。放行或拦截只有以上所有检查都通过门卫才会放行建立一条加密的、可信的通信通道。任何一步失败门卫都会立即拦截并报告错误抛出SSLError。在requests中控制这个“门卫”严格与否的核心参数就是verify。它默认值为True意味着执行上述全套严格检查。import requests # 默认行为进行完整的SSL证书验证 response requests.get(https://example.com) # 如果example.com证书无效这里会报错当我们将verify设置为False时就相当于命令门卫“别检查了直接放行”。这会跳过所有证书验证步骤。import requests # 忽略所有SSL证书验证 response requests.get(https://self-signed.badssl.com, verifyFalse)注意verifyFalse是极不安全的操作。它使你的连接暴露在中间人攻击的风险之下。攻击者可以轻易地冒充目标服务器窃取或篡改你传输的敏感数据如密码、令牌、个人信息。因此这绝对不应用于生产环境或处理任何敏感信息的场景。它仅应作为开发、测试、或访问完全可控的内部环境时的临时解决方案。3. 实战忽略证书验证的多种方法了解了原理我们来看看具体怎么操作。根据不同的使用场景有几种不同的方法。3.1 单次请求级别忽略这是最常用、最灵活的方式。通过给requests.get(),requests.post()等方法传递verifyFalse参数仅对当前这次请求忽略证书验证。import requests url https://internal-server.company.local/api/data payload {key: value} headers {Content-Type: application/json} # 针对这一次POST请求忽略SSL证书验证 try: response requests.post(url, jsonpayload, headersheaders, verifyFalse) print(response.status_code) print(response.json()) except requests.exceptions.SSLError as e: print(fSSL错误发生: {e})这种方法的好处是影响范围最小只针对特定的、已知有证书问题的请求。代码意图清晰。3.2 会话级别忽略如果你需要使用requests.Session()对象来保持会话如处理cookies、保持连接池并且这个会话需要访问多个使用自签名证书的端点那么在会话级别设置verifyFalse会更方便。import requests # 创建一个会话 session requests.Session() # 为该会话的所有请求关闭SSL验证 session.verify False # 现在通过这个会话发起的请求都不会验证证书 response1 session.get(https://internal-api.local/users) response2 session.post(https://internal-api.local/auth, data{user: admin}) # 注意直接使用 requests.get() 不受此会话影响它仍会验证证书。3.3 全局忽略极其不推荐通过修改requests库的默认配置可以全局关闭SSL验证。强烈不建议这样做因为它会影响你整个Python进程中所有使用requests的代码包括你可能依赖的第三方库带来不可预知的安全风险。import requests import urllib3 # 禁用全局的SSL警告先做这个否则会有警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # 修改requests的默认行为危险操作 requests.packages.urllib3.disable_warnings() # 另一种禁用警告的方式 # 实际上requests库没有直接的全局verify设置。通常是通过环境变量或修改默认会话。 # 更危险的做法是猴子补丁这里仅作演示切勿在生产环境使用。 original_request requests.request def insecure_request(*args, **kwargs): kwargs[verify] False return original_request(*args, **kwargs) requests.request insecure_request # 此后所有 requests.request 及其衍生方法get, post都将 verifyFalse再次强调除非你在一个完全隔离的、无网络风险的测试环境中否则请避免使用全局修改的方法。4. 处理烦人的InsecureRequestWarning警告当你使用verifyFalse时urllib3requests底层使用的HTTP库会出于安全考虑抛出一个InsecureRequestWarning。这是一个警告Warning不是错误Exception所以你的程序会继续运行但控制台会输出类似下面的内容/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host internal-server.company.local. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings warnings.warn(对于自动化脚本或希望保持输出整洁的场景我们需要关闭这个警告。4.1 通过urllib3禁用特定警告最标准、最推荐的做法是使用urllib3本身提供的方法来禁用InsecureRequestWarning。import requests import urllib3 # 禁用 InsecureRequestWarning 警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # 现在即使 verifyFalse也不会打印警告 response requests.get(https://self-signed.badssl.com, verifyFalse) print(请求成功无警告信息)4.2 通过requests的封装方法禁用requests库也提供了一个便捷的封装效果与上面相同。import requests # 使用 requests 封装的禁用警告方法 requests.packages.urllib3.disable_warnings(categoryrequests.packages.urllib3.exceptions.InsecureRequestWarning) response requests.get(https://self-signed.badssl.com, verifyFalse)4.3 使用Python的warnings模块全局过滤你也可以使用Python标准库的warnings模块进行更全局的控制。这种方法可以过滤掉所有地方的InsecureRequestWarning但需要知道完整的警告类路径。import warnings import requests # 从urllib3导入具体的警告类 from urllib3.exceptions import InsecureRequestWarning # 过滤掉特定的警告 warnings.filterwarnings(ignore, categoryInsecureRequestWarning) response requests.get(https://self-signed.badssl.com, verifyFalse)4.4 临时重定向警告输出如果你只想在特定代码块中抑制警告而不是全局禁用可以使用warnings.catch_warnings上下文管理器。这是更精细的控制方式。import warnings import requests with warnings.catch_warnings(): # 在这个代码块内忽略所有警告或可指定类别 warnings.simplefilter(ignore) # 或者只忽略 InsecureRequestWarning # from urllib3.exceptions import InsecureRequestWarning # warnings.filterwarnings(ignore, categoryInsecureRequestWarning) response requests.get(https://self-signed.badssl.com, verifyFalse) print(代码块内请求完成) # 代码块外警告恢复原有行为 response2 requests.get(https://self-signed.badssl.com, verifyFalse) # 这里又会有警告了个人建议在脚本的开头使用urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)是最清晰直接的做法。如果脚本是工具类可能会被他人复用可以在函数内部使用上下文管理器warnings.catch_warnings进行局部抑制避免影响调用者的环境。5. 更优方案使用自定义CA证书或私有证书完全忽略验证是下策。在多数企业内部场景下存在一个更安全、更规范的解决方案使用自定义的CA证书。很多公司会有自己的内部CA证书颁发机构为所有内部服务器签发证书。你只需要将公司内部CA的根证书通常是一个.crt或.pem文件添加到你的信任链中requests就能像信任公共CA一样信任这些内部证书。5.1 为单个请求指定CA证书包verify参数不仅可以接受布尔值还可以接受一个字符串路径指向一个包含CA证书的文件通常是.pem格式或者一个包含多个证书的目录。import requests # 假设你从公司IT部门拿到了内部CA的证书文件 internal_ca.pem ca_cert_path /path/to/your/internal_ca.pem # 将 verify 指向你的CA证书文件 response requests.get(https://internal-service.company.local, verifyca_cert_path)这样requests在验证internal-service.company.local的证书时不仅会检查系统默认的信任库还会检查你提供的internal_ca.pem。如果服务器证书是由这个内部CA签发的验证就会通过。5.2 将私有CA证书添加到系统或环境信任库对于长期需要访问大量内部服务的开发机更一劳永逸的方法是将内部CA证书安装到操作系统或Python环境的默认信任库中。这样所有使用系统CA库的程序包括requests都会自动信任这些内部证书。Linux/Mac (使用系统CA存储):通常可以将.pem证书文件复制到/usr/local/share/ca-certificates/目录然后运行更新命令。# 将证书复制到指定目录 sudo cp internal_ca.pem /usr/local/share/ca-certificates/ # 更新系统CA证书存储 sudo update-ca-certificates之后Python的requests通过ssl模块就会自动识别这个新加入的CA。Windows:可以通过证书管理器certmgr.msc将CA证书导入到“受信任的根证书颁发机构”存储中。通过环境变量指定跨平台:你可以设置REQUESTS_CA_BUNDLE环境变量指向一个自定义的CA证书包文件。# Bash export REQUESTS_CA_BUNDLE/path/to/your/ca_bundle.pem # 或者在Python脚本中设置 import os os.environ[REQUESTS_CA_BUNDLE] /path/to/your/ca_bundle.pem设置后requests会优先使用这个环境变量指定的证书包而不是系统默认的。5.3 创建自定义的CA证书包文件如果你的环境混合了多个私有CA或者你需要精确控制信任哪些CA可以自己创建一个CA证书包文件.pem格式。这个文件其实就是将多个CA证书PEM格式简单地拼接在一个文件里。# 将多个CA证书合并成一个bundle文件 cat ca_cert1.pem ca_cert2.pem my_custom_ca_bundle.pem然后在requests中使用这个bundle文件import requests response requests.get(https://some.internal.site, verify/path/to/my_custom_ca_bundle.pem)6. 深入排查当verifyFalse仍报错时有时候即使你设置了verifyFalse仍然可能遇到与SSL/TLS相关的错误。这通常不是证书验证本身的问题而是更深层的协议或配置问题。6.1 协议版本不匹配服务器可能只支持老旧的、不安全的TLS协议版本如TLSv1.0而现代Python环境默认可能已禁用这些版本。或者反过来客户端环境太老不支持服务器要求的新协议。解决方案在requests请求中指定协议版本。import requests import ssl from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager # 方法1为特定会话适配所有请求推荐 class LegacyTLSAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): # 强制使用 TLSv1.2可以根据需要改为 ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1 等 kwargs[ssl_version] ssl.PROTOCOL_TLSv1_2 return super().init_poolmanager(*args, **kwargs) session requests.Session() session.mount(https://, LegacyTLSAdapter()) session.verify False # 如果需要的话 response session.get(https://old-server.local) # 方法2更暴力的全局SSL上下文设置不推荐影响广泛 import urllib3 # 创建使用特定协议版本的HTTPS连接池管理器示例 # 这需要更底层的操作通常建议使用方法1。6.2 密码套件不匹配服务器可能只支持某些特定的、客户端不支持的加密套件。解决方案这个问题较难在requests高层解决通常需要调整系统或Python的SSL配置。一个尝试方向是使用CURL或openssl客户端测试服务器支持的套件确认问题。在极端情况下可能需要像上面一样通过自定义HTTPAdapter来配置底层的ssl.SSLContext设置特定的密码套件。6.3 证书格式问题即使verifyFalse在某些非常特殊的情况下服务器返回的证书本身格式就是畸形的导致SSL握手在验证之前就失败了。verifyFalse跳过了“验证”但没跳过“解析”。如果证书不是有效的X.509格式连接依然会失败。排查方法使用openssl s_client命令进行诊断。openssl s_client -connect your-server.com:443 -showcerts观察输出看是否能正常接收到证书。如果这里就报错那问题出在服务器端。6.4 其他网络层问题错误信息可能被包装在SSLError中但根本原因可能是网络代理、防火墙拦截了TLS握手包或者服务器端口根本不是HTTPS。排查思路先用浏览器或curl访问同一地址确认服务本身可用。检查是否有系统代理或环境变量如HTTP_PROXY,HTTPS_PROXY干扰。requests默认会使用这些代理设置。尝试在请求中显式设置proxies参数或将其设置为None来绕过代理。import requests # 尝试不使用代理 proxies { http: None, https: None, } response requests.get(https://target.com, verifyFalse, proxiesproxies)7. 安全实践与经验总结在开发中绕过SSL验证是常见操作但务必牢记安全边界。以下是我总结的一些经验原则环境隔离原则将verifyFalse的代码严格限制在开发、测试或完全可信的隔离内网环境中。可以通过环境变量来控制这一行为。import os import requests DEV_MODE os.getenv(ENVIRONMENT) development # 或者使用自定义配置 SKIP_SSL_VERIFY os.getenv(SKIP_SSL_VERIFY, false).lower() true session requests.Session() if DEV_MODE or SKIP_SSL_VERIFY: import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) session.verify False else: # 生产环境使用严格验证或指定特定的CA bundle # session.verify /path/to/prod/ca-bundle.crt pass # 使用 session 进行请求证书固定Certificate Pinning对于特别重要的客户端如移动App、关键服务客户端可以考虑证书固定。这不是完全忽略验证而是只信任一个或几个特定的证书或公钥而不是整个CA体系。requests本身不直接支持但可以通过自定义HTTPAdapter和ssl.SSLContext实现或使用requests的cert参数进行客户端证书双向验证这是另一种场景。警告处理要到位在脚本中禁用InsecureRequestWarning是一个好习惯可以保持输出清晰。但最好在脚本开头用日志或打印语句明确说明“SSL验证已禁用”让后续维护者清楚潜在风险。优先使用私有CA只要条件允许永远优先选择将内部CA证书加入信任链的方案verify/path/to/ca.pem而不是完全关闭验证。这是兼顾安全与便利的最佳实践。理解错误根源遇到SSL错误不要习惯性地verifyFalse了事。先花几分钟用openssl s_client或浏览器检查一下证书的详细信息颁发者、有效期、域名匹配。很多时候可能是服务器证书配置错误如用了IP地址但证书里是域名修复服务器配置才是根本解决之道。处理SSL证书问题就像处理一扇门的安全锁。verifyFalse是直接把锁拆了方便但危险。而使用正确的钥匙自定义CA证书或者调整锁具协议/套件配置才能在安全与便利之间找到平衡点。希望这些具体的代码和排查思路能让你下次再遇到CERTIFICATE_VERIFY_FAILED时可以从容地选择最合适的解决方案。

相关新闻

Arduino粉尘传感器实战:GP2Y1010AU0F硬件滤波与软件算法全解析

Arduino粉尘传感器实战:GP2Y1010AU0F硬件滤波与软件算法全解析

1. 项目概述与核心价值 “DIY海盗船系列”做到第7话,终于轮到环境感知模块了。这次我们要给这艘“船”装上“眼睛”和“鼻子”,让它能感知周围空气的“清澈度”,也就是实现粉尘检测功能。这听起来可能不如控制电机、点亮LED那么直观刺激&…

2026/7/29 16:17:54 阅读更多 →
OpCore-Simplify:3分钟搞定OpenCore配置,让黑苹果安装变得如此简单!

OpCore-Simplify:3分钟搞定OpenCore配置,让黑苹果安装变得如此简单!

OpCore-Simplify:3分钟搞定OpenCore配置,让黑苹果安装变得如此简单! 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify …

2026/7/29 16:16:53 阅读更多 →
3分钟解锁加密音乐:浏览器中免费转换主流音乐平台格式

3分钟解锁加密音乐:浏览器中免费转换主流音乐平台格式

3分钟解锁加密音乐:浏览器中免费转换主流音乐平台格式 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: https…

2026/7/29 16:16:53 阅读更多 →

最新新闻

TI CC3220 Wi-Fi模块硬件设计详解:从双核架构到射频布局实战

TI CC3220 Wi-Fi模块硬件设计详解:从双核架构到射频布局实战

1. 项目概述如果你正在寻找一款能快速将你的创意产品接入互联网的无线微控制器(MCU)方案,那么德州仪器(TI)的SimpleLink CC3220系列模块绝对值得你花时间深入研究。这不仅仅是一个Wi-Fi芯片,而是一个集成了…

2026/7/29 16:24:57 阅读更多 →
Scratch编程与数学思维融合:从完全数算法到可视化教学实践

Scratch编程与数学思维融合:从完全数算法到可视化教学实践

1. 项目缘起:当数学老师决定“不务正业” 作为一名教了十几年数学的老师,我常常在思考一个问题:如何让学生们真正“看见”数学,而不仅仅是“计算”数学。那些课本上冷冰冰的定义、定理和公式,比如“完全数”&#xff0…

2026/7/29 16:24:57 阅读更多 →
Botty:如何用智能自动化工具将D2R刷图效率提升300%

Botty:如何用智能自动化工具将D2R刷图效率提升300%

Botty:如何用智能自动化工具将D2R刷图效率提升300% 【免费下载链接】botty D2R Pixel Bot 项目地址: https://gitcode.com/gh_mirrors/bo/botty 你是否厌倦了在暗黑破坏神2重制版中重复刷图的枯燥操作?是否希望将宝贵的时间用于策略制定和装备搭配…

2026/7/29 16:24:57 阅读更多 →
home nas华为怎么搭建?从开箱到生态联动一篇讲清楚

home nas华为怎么搭建?从开箱到生态联动一篇讲清楚

华为家庭存储是华为面向家庭用户推出的一款私有云产品,定位“全家人的数据保险箱”。它和传统NAS不一样,更像一个为华为生态用户量身定制的数据备份中心。这篇文章把华为家庭存储的搭建流程、核心功能和实际体验梳理一遍,并为跨设备文件共享提…

2026/7/29 16:24:57 阅读更多 →
ThinkPad风扇控制终极指南:3种模式实现完美散热与静音平衡

ThinkPad风扇控制终极指南:3种模式实现完美散热与静音平衡

ThinkPad风扇控制终极指南:3种模式实现完美散热与静音平衡 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 TPFanCtrl2是一款专为ThinkPad用户设计的开源风扇…

2026/7/29 16:24:57 阅读更多 →
戴尔笔记本风扇控制终极指南:3大模式解决散热与噪音平衡难题

戴尔笔记本风扇控制终极指南:3大模式解决散热与噪音平衡难题

戴尔笔记本风扇控制终极指南:3大模式解决散热与噪音平衡难题 【免费下载链接】DellFanManagement A suite of tools for managing the fans in many Dell laptops. 项目地址: https://gitcode.com/gh_mirrors/de/DellFanManagement DellFanManagement是一款专…

2026/7/29 16:23:57 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻