قد يتسبب الاعتماد المرتقب لـ OpenSSL 1.1 (أو بشكل أكثر تحديدًا 1.1.1 ) بواسطة توزيعات Linux في حدوث مشكلات للطلبات عند التحقق من مواقع الويب القديمة.
تم الإبلاغ عن هذا لأول مرة في Debian bugtracker باعتباره الخطأ رقم 907807 ، وكان في الأصل ضد برنامج linkchecker (وتم إعادة توجيهه إلى الأعلى كـ https://github.com/linkchecker/linkchecker/issues/188) ، ولكن تبين أن مكتبة الطلبات تعاني بشكل مباشر من هذه المشكلة أيضًا.
~ من المحتمل أن تؤدي هذه المشكلة إلى حظر إصدار الطلبات باستخدام باستر ، والإصدار الحالي "التجريبي" والإصدار المستقر القادم (منتصف 2019؟) ما لم يتم إصلاحه إلى حد ما. ~ كان هذا التأكيد غير صحيح: تم وضع علامة على الخطأ حاليًا بـ "عادي" الشدة التي لا تمنع الافراج.
كانت المواقع المختبرة:
يتم تحميل جميع المواقع بشكل صحيح في Firefox 60.1.0 وعلى الرغم من أنني لم أختبر ذلك مع OpenSSL 1.1.1 ، أشك في أنه سيتأثر لأن Firefox (و Chromium) لهما مكتبة TLS الخاصة بهما (NSS). لاحظ أيضًا أن urllib3
يبدو أنه ليس لديه مشكلة في تحميل تلك المواقع نفسها:
>>> import urllib3
>>> http = urllib3.PoolManager()
>>> r = http.request('GET', 'https://get.adobe.com/')
>>>
يجب تحميل جميع المواقع بشكل صحيح ، والتحميل بشكل صحيح في Debian buster (والذي لا يزال يحتوي على OpenSSL 1.1.0):
$ python
Python 2.7.15+ (default, Aug 31 2018, 11:56:52)
[GCC 8.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('https://get.adobe.com')
<Response [200]>
(unstable-amd64-sbuild)anarcat<strong i="10">@curie</strong>:/$ python
Python 2.7.15+ (default, Aug 31 2018, 11:56:52)
[GCC 8.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('https://get.adobe.com')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 72, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 506, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='get.adobe.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, u'[SSL: WRONG_SIGNATURE_TYPE] wrong signature type (_ssl.c:726)'),))
>>> requests.get('https://www.nada.kth.se')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 72, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 506, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.nada.kth.se', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, u'[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:726)'),))
>>> requests.get('https://caniuse.com')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 72, in get
return request('get', url, params=params, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 508, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 618, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 506, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='caniuse.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, u'[SSL: VERSION_TOO_LOW] version too low (_ssl.c:726)'),))
قم بتشغيل آلة غير مستقرة في دبيان للحصول على أحدث حزمة 1.1.1 ~~ pre9. يمكن القيام بذلك باستخدام Docker باستخدام:
docker run -it debian:unstable
إذا لم يكن لديك وصول إلى مثل هذه البيئة ، فيمكن العثور على أحدث كود OpenSSL في صفحة المشروع الخاصة بهم .
import requests
for url in ('https://get.adobe.com/', 'https://caniuse.com',
'https://www.nada.kth.se/~snilsson/publications/IP-address-lookup-using-LC-tries/'):
requests.get(url)
$ python -m requests.help
(unstable-amd64-sbuild)anarcat<strong i="16">@curie</strong>:/$ python -m requests.help
{
"chardet": {
"version": "3.0.4"
},
"cryptography": {
"version": ""
},
"idna": {
"version": "2.6"
},
"implementation": {
"name": "CPython",
"version": "2.7.15+"
},
"platform": {
"release": "4.17.0-3-amd64",
"system": "Linux"
},
"pyOpenSSL": {
"openssl_version": "",
"version": null
},
"requests": {
"version": "2.18.4"
},
"system_ssl": {
"version": "10101009"
},
"urllib3": {
"version": "1.22"
},
"using_pyopenssl": false
}
إنني على دراية بأننا أحد الإصدارات الثانوية وراء المنبع في دبيان ، ويتم العمل على هذا الأمر. لكنني راجعت طلبات التغيير ولا يبدو أن هناك أي تغيير ذي صلة بهذا. لذلك فأنا أؤكد أن الإصدارات الحالية تعاني أيضًا من نفس المشكلة.
لاحظ أيضًا أن هذا قد يكون انحدارًا في OpenSSL نفسه. أقوم بحفظ هذا هنا لمعرفة رأيك فيما يتعلق بهذه المشكلة وما إذا كان شيئًا ينتمي إلى الطلبات أو مكتبة (مكتبات) التشفير الأولية.
بالنسبة لمشكلة Adobe التي فتحتها: https://github.com/openssl/openssl/issues/7126
مشكلة caniuse هي: https://github.com/Fyrd/caniuse/issues/4198
يرجع السبب في ذلك إلى قيام Debian بإعداد إصدار TLS بحد أدنى 1.2. يجب عليهم بالفعل إضافة دعم TLS 1.2 على الأقل.
لمشكلة SNI ، راجع: https://wiki.openssl.org/index.php/TLS1.3#Server_Name_Indication
ستواجه هذه المشكلة لأي شيء تستضيفه Google.
لذا فإن بعض هذه المشكلات ناتجة عن زيادة دبيان لمستوى أمان openssl افتراضيًا. الإصلاح المناسب هو إصلاح مواقع الويب. لكن من الممكن خفض إعدادات الأمان هذه كحل بديل. من فضلك لا تتجاوز الإعدادات الافتراضية بشكل افتراضي.
مشكلة SNI شيء يجب عليك إصلاحه حقًا. لا أعرف أي جزء لا يضبطه.
مرحبا ، هل يمكنك تقديم الحلول؟ لقد حاولت خفض اتصال الأمان لتجنب DH_KEY_TOO_SMALL
، لكن لم أجد أي حل يناسبني (اختبار Debian ، الطلبات المثبتة من حزمة debian). على وجه التحديد لـ https://www.ceskatelevize.cz/
. ليس من المحتمل جدًا أن يقوموا بإصلاح الأمان في أي وقت قريبًا.
انظر /usr/share/doc/libssl1.1/NEWS.Debian.gz
لقد رأيت ذلك ، لكنني لا أرغب في خفض مستوى الأمان للنظام بأكمله ، فقط لبرنامج نصي محدد. لقد جربت أيضًا https://stackoverflow.com/q/38015537/2440346 ، لكن تغيير urllib3.util.ssl_.DEFAULT_CIPHERS
لا يعمل أيضًا.
إذا كنت تريد خفض إعداد الأمان في ملف آخر بخلاف
/etc/ssl/openssl.cfg تحتاج إلى استخدام DEFAULT @ SECLEVEL = 1
لقد جربت عددًا من الأساليب ، لكن لم ينجح أي منها ، انظر
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
# Attempt 1:
# requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = '@SECLEVEL=1'
# Attempt 2:
# requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'DEFAULT@SECLEVEL=1'
# Attempt 3:
# requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL'
requests.get('https://www.ceskatelevize.cz/')
# Attempt 4:
# CIPHERS = '@SECLEVEL=1'
# Attempt 5:
# CIPHERS = 'DEFAULT@SECLEVEL=1'
# Attempt 6:
CIPHERS = 'ALL'
class CustomAdapter(HTTPAdapter):
"""
A TransportAdapter that re-enables 3DES support in Requests.
"""
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(CustomAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=CIPHERS)
kwargs['ssl_context'] = context
return super(CustomAdapter, self).proxy_manager_for(*args, **kwargs)
session = requests.Session()
session.mount('https://www.ceskatelevize.cz', CustomAdapter())
session.get('https://www.ceskatelevize.cz/')
يعمل ما يلي بالنسبة لي:
import requests
from requests import adapters
import ssl
from urllib3 import poolmanager
class TLSAdapter(adapters.HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
"""Create and initialize the urllib3 PoolManager."""
ctx = ssl.create_default_context()
ctx.set_ciphers('DEFAULT@SECLEVEL=1')
self.poolmanager = poolmanager.PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLS,
ssl_context=ctx)
session = requests.session()
session.mount('https://', TLSAdapter())
session.get(TARGET)
يعمل ما يلي بالنسبة لي:
import requests from requests import adapters import ssl from urllib3 import poolmanager class TLSAdapter(adapters.HTTPAdapter): def init_poolmanager(self, connections, maxsize, block=False): """Create and initialize the urllib3 PoolManager.""" ctx = ssl.create_default_context() ctx.set_ciphers('DEFAULT@SECLEVEL=1') self.poolmanager = poolmanager.PoolManager( num_pools=connections, maxsize=maxsize, block=block, ssl_version=ssl.PROTOCOL_TLS, ssl_context=ctx) session = requests.session() session.mount('https://', TLSAdapter()) session.get(TARGET)
شكرا!
إنه مفيد لخطأ SSLE الخاص بي [SSL: DH_KEY_TOO_SMALL]
@ codefather-labs شكرًا كان لدي نفس المشكلة ، غريب جدًا
التعليق الأكثر فائدة
يعمل ما يلي بالنسبة لي: