非常抱歉文章太长了,但我真的在尽力详细说明...
我有一个专门的网站,用作远程服务器上运行的各种环境模型之间交换数据的桥梁,并且运行于不同类型的操作系统(Linux、MacOS和Windows)。基本上每个服务器都可以上传/下载数据文件到该网站,然后文件再由另一台服务器上的不同模型进行进一步处理。
该网站具有基本的安全保护措施(IP过滤、密码和使用LetsEncrypt证书的SSL)。所有远程服务器都可以通过我们创建的简单Web界面访问该网站并上传/下载数据。
现在我们正在尝试使用一个简单的Python(2.7)守护进程(基于requests模块)自动化一些交换。该守护进程监视某些文件夹并将内容上传到该网站。
该守护进程在所有远程服务器上都正常工作,除了一台运行Windows 7 Enterprise 64位的服务器。该服务器已安装Python 2.7.13和以下软件包:DateTime(4.1.1)、psutil(5.2.0)、pytz(2016.10)、requests(2.13.0)和zope.interface(4.3.3)。
从该服务器上,SSL连接通过Web浏览器可以正常工作,但是守护进程总是返回:
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)
以下是我们迄今为止尝试过的:
- 将verify设置为false。这可以正常工作,但我们不能在最终生产环境中使用它。
- 从另一台守护程序正常工作的服务器上复制证书,并将verify设置为证书文件名称(没有成功)
- 将'User-agent'设置为与Windows机器上通过Web浏览器进行连接时获取的完全相同的字符串(没有成功)
我们应该在Windows服务器上查看哪些其他设置以尝试解决问题? 它可能是防火墙设置,可以通过浏览器的SSL连接传递,但阻止Python守护程序吗?
更新
出现错误的运行Windows远程服务器的组织在代理级别替换所有SSL证书。
他们的IT人员通过将我们网站的URL添加到其代理设置的“直通”站点列表中来解决了我们的问题。
这个方法可以工作,现在很好。 但是,我想知道是否可以直接在Python中处理证书替换...
'PyOpenSSLContext' object has no attribute 'load_default_certs'
。 - kraussiancreate_urllib3_context
的导入替换为import ssl
,然后更改上下文的赋值为context = ssl.create_default_context()
。 - jakob.jcreate_default_context
方法实际上自动执行了load_default_certs
操作,这是一种更简单的设置上下文的方法,而不必从 urllib3 导入私有成员。这似乎适用于 Python 2.7 和 Python 3。我对上述代码的测试也适用于 Python 3,但使用你的方法可能会更简单。 - David Fraserrequests.get()
等函数时都会在后台使用一个会话。因此,没有办法在没有会话的情况下使用“requests”。 - cowlinator