Gia*_*ilo 72 python ssl openssl runtime-error
我正在运行一个 Python 代码,我必须从HTTPSConnectionPool(host='ssd.jpl.nasa.gov', port=443). 但每次我尝试运行代码时都会收到以下错误。我的系统是 MAC 操作系统 12.1
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='ssd.jpl.nasa.gov', port=443): Max retries exceeded with url: /api/horizons.api?format=text&EPHEM_TYPE=OBSERVER&QUANTITIES_[...]_ (Caused by SSLError(SSLError(1, '[SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED] unsafe legacy renegotiation disabled (_ssl.c:997)')))
Run Code Online (Sandbox Code Playgroud)
我真的不知道如何绕过这个问题。
小智 125
警告:启用旧版不安全重新协商时,SSL 连接将容易受到中间人前缀攻击,如CVE-2009-3555中所述。
在https://bugs.launchpad.net/bugs/1963834 和https://bugs.launchpad.net/ubuntu/+source/gnutls28/+bug/1856428的帮助下
请注意,不建议编辑系统的 openssl.conf,因为一旦更新 openssl,您可能会丢失所做的更改。
openssl.cnf在任何目录中创建一个包含以下内容的自定义文件:
openssl_conf = openssl_init
[openssl_init]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
Options = UnsafeLegacyRenegotiation
Run Code Online (Sandbox Code Playgroud)
在运行程序之前,请确保在运行 scraper 时OPENSSL_CONF将环境变量设置为自定义完整路径,如下所示:openssl.cnf
OPENSSL_CONF=/path/to/custom/openssl.cnf python your_scraper.py
Run Code Online (Sandbox Code Playgroud)
或者像这样:
export OPENSSL_CONF=/path/to/custom/openssl.cnf
python your_scraper.py
Run Code Online (Sandbox Code Playgroud)
或者,如果您使用 pipelinenv 或 systemd 或 docker,请将其放入您的.env文件中
OPENSSL_CONF=/path/to/custom/openssl.cnf
Run Code Online (Sandbox Code Playgroud)
ahm*_*ara 48
Harry Mallon的答案的完整代码片段:
定义一个重用的方法:
import requests
import urllib3
import ssl
class CustomHttpAdapter (requests.adapters.HTTPAdapter):
# "Transport adapter" that allows us to use custom ssl_context.
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = urllib3.poolmanager.PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_context=self.ssl_context)
def get_legacy_session():
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ctx.options |= 0x4 # OP_LEGACY_SERVER_CONNECT
session = requests.session()
session.mount('https://', CustomHttpAdapter(ctx))
return session
Run Code Online (Sandbox Code Playgroud)
然后用它代替请求调用:
get_legacy_session().get("some-url")
Run Code Online (Sandbox Code Playgroud)
Har*_*lon 34
我在 Linux 上遇到了同样的错误(当服务器不支持“RFC 5746 安全重新协商”并且客户端使用 OpenSSL 3(默认情况下强制执行该标准)时,就会发生这种情况)。
这是一个解决方案(您可能需要稍微调整一下)。
sslandurllib3ssl Contextclass CustomHttpAdapter (requests.adapters.HTTPAdapter):
'''Transport adapter" that allows us to use custom ssl_context.'''
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = urllib3.poolmanager.PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_context=self.ssl_context)
Run Code Online (Sandbox Code Playgroud)
ssl启用 的上下文OP_LEGACY_SERVER_CONNECT,并将其与您的自定义适配器一起使用。ssl.OP_LEGACY_SERVER_CONNECT在 Python 中尚不可用(https://bugs.python.org/issue44888)。然而事实证明,在 OpenSSL 中,其位字段值为 0x4。所以我们可以做以下事情。
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ctx.options |= 0x4
session.mount('https://', CustomHttpAdapter(ctx))
Run Code Online (Sandbox Code Playgroud)
Jer*_*unt 16
当使用 OpenSSL 3 连接到不支持它的服务器时,会出现此错误。解决办法是降级python中的加密包:
pip install cryptography==36.0.2在使用的环境中运行。
来源: https: //github.com/scrapy/scrapy/issues/5491
编辑:请参阅 Harry Mallon 和 ahmkara 的答案,以获取无需降级密码学的修复程序
如果你想使用 urlopen,这个片段对我有用。
import ssl
import urllib.request
url = 'http://....'
# Set up SSL context to allow legacy TLS versions
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ctx.options |= 0x4 # OP_LEGACY_SERVER_CONNECT
# Use urllib to open the URL and read the content
response = urllib.request.urlopen(url, context=ctx)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
169787 次 |
| 最近记录: |