python - Python 请求 SSLCertVerificationError 的问题
问题描述
我试图弄清楚,为什么我有一个问题,即Python
代码在具有多个域和同一 IP 上的证书的虚拟主机上SSLCertVerificationError
抛出一个有效的 LetsEncrypt 证书如果我删除除一个之外的所有证书很好,但还有更多一个证书请求会忽略 Python 发送请求的域并拉取最新的,这是不正确的,导致域. LetsEncrypt certificate
SSLCertVerificationError
我的理解是,在SNI
(服务器名称指示)下,请求应该只提取请求所针对的域的证书,而不仅仅是最近的一个。我已经检查过了,我正在运行Python 3.8,请求 2.5的版本Nginx
已编译SNI
支持。我可以通过关闭 SSL 验证来抑制错误,但这似乎是一个糟糕的解决方法。
知道发生了什么吗?为什么SNI
当浏览器请求页面时工作正常Nginx
,pullign 正确的证书,但在 Python 的 requests 包下完成相同的操作时失败?我已经阅读了我能找到的所有内容,文档说它应该只在 , , 等的当前版本下工作nginx
,requests
但OpenSSL
它显然不在这里。
要复制,我可以从本地机器上无错误地执行 requests.get{'https://kedrosky.org')。但是在该服务器(托管域)上运行的脚本上,会返回错误域的较新证书,从而导致 SSLCertVerificationError。
解决方案
问题是服务器配置可能只针对 IPv4 正确完成,即使域也解析为 IPv6 地址。使用 IPv4,它会返回正确的证书:
$ openssl s_client -connect kedrosky.org:443 -4
...
subject=CN = kedrosky.com
但是对于 IPv6,它会返回一个不同的证书(这需要 IPv6 连接到本地计算机上的 Internet):
$ openssl s_client -connect kedrosky.org:443 -6
...
subject=CN = paulandhoward.com
这可能是因为只有 alisten 443
而不是listen [::]:443
,后者是 IPv6 所需的。在这种情况下,虚拟主机仅适用于 IPv4,但对于 IPv6,它只会返回默认值,即通常是配置的第一个证书。
您看到来自不同主机的不同结果的原因是一台只有 IPv4 连接,而另一台也可以使用 IPv6。
推荐阅读
- python - Selenoid:为什么我不能运行特定的浏览器版本?
- python - PySpark:DataFrame 到 RDD[DenseVector] 而不是 RDD[Row]
- sql-server - 无法在 SSDT 中预览报表 - 已尝试使用未为此报表服务器注册的数据扩展“oracle”
- frama-c - 使用 malloc 编程:为什么 Eva 不能证明 \valid(p)?
- multithreading - 如何在linux上获取没有gdb/pstack的进程的所有线程pthread_t id
- msbuild - CSC 错误 CS0006:找不到元数据文件“SonarAnalyzer.dll”
- javascript - 使用数据库中的坐标在画布上绘制点
- linux - 设备驱动程序在用户应用程序重复使用后崩溃
- linux - gcc 优化和调整标志
- api-key - 谷歌云语音 API