Requests: دعم TLS SNI

تم إنشاؤها على ١ أغسطس ٢٠١٢  ·  46تعليقات  ·  مصدر: psf/requests

يبدو أنني أواجه مشكلات في استخدام الطلبات مع الخوادم التي تحتاج إلى دعم TLS SNI. متى ستتمتع الطلبات بهذه الميزة؟ هل هذا شيء مخطط؟

شكرا،
--الرامات "الذاكرة العشوائية في الهواتف والحواسيب

التعليق الأكثر فائدة

تم تحديد ذلك في الطلبات / الحزم / urllib3 / Contrib / pyopenssl.py :

  • pyOpenSSL (تم اختباره بـ 0.13)
  • ndg-httpsclient (تم اختباره بـ 0.3.2)
  • pyasn1 (تم اختباره بـ 0.1.6)

(أو python3.2 أو أعلى ، والذي يعمل دائمًا)

ال 46 كومينتر

لا يمكن وضعه في Python 2.x أعلى وحدة ssl الخاصة بـ stdlib.

الملتوية ، أليس كذلك؟ ربما حان الوقت للاعتماد على pyopenssl أو بعض وحدات SSL الأخرى؟

هناك طلب سحب لـ urllib3 لإضافة دعم SNI لـ Py32 + ، ولكن لا يزال بحاجة إلى تغطية اختبارية. https://github.com/shazow/urllib3/pull/89

shzow: شكرا للمؤشر. أنا للأسف أستخدم Twisted / Flask ، مما يعني أنني عالق في 2.7. يبدو أنه ملتوي يمكن أن يفعل شيئًا كهذا ، لكنني لم أر أمثلة ، وسيحتاج إلى فك تشفير pyopenssl + ملتوي للقيام بذلك. لست خبيرا في أي لسحب هذا قبالة. في هذه المرحلة ، مجرد التفكير في التفاف بعض أدوات سطر الأوامر مثل wget ... :(

يجب أن يكون PyOpenSSL قادرًا على القيام بذلك على 2.x. لذلك هناك أمل.

يمكنني أن أجعلها تعمل مع البيوبينسل. لكن ما زلت أواجه صعوبة في القيام بذلك بشكل ملتوي بشكل صحيح. http://pbin.be/show/719/ - نوع الأعمال. ولكن بعد ذلك يتعين على المرء بناء واجهة برمجة تطبيقات عليها حتى تكون مفيدة. ما زلت غير قادر على معرفة كيفية تمرير السياق الصحيح إلى الوكيل.

لوكاسا: هل تم حل هذا؟

لا ، نحن محظورون على shazow / urllib3 # 89.

مندمجة. الاستمرار في. :)

لاحظ أنه مدعوم فقط في Py32 + في الوقت الحالي. يجب أن يكون كافيا للبدء بالرغم من ذلك.

تحذير عادل آخر: بعض الاختبارات على Py32 تفشل في urllib3 master الآن. بعض المساعدة في حل هذا سيكون موضع تقدير كبير (وقد يؤثر على هذه الوظيفة): https://github.com/shazow/urllib3/issues/128

يعمل معي على archlinux x64 على py26 و py27 و py32 و py33

آه كان يجب أن أكون مؤهلًا أن هذا موجود على OSX. Scumbag OSX.

t-8ch: هل اختبارات sni تمر على py26 / 27/32 و 33 من أجلك؟

لا يتم تشغيل اختبارات SNI حتى على py2 ، ولكنها تعمل في py32 و py33.
لا توجد طريقة لعمل SNI بوحدة ssl للمكتبة القياسية قبل py32.

@ shazow : من المفترض أنك لا تهتم بجعل urllib3 يعتمد على PyOpenSSL؟

يسعدني أن يكون لدي مكتبة منفصلة تضيف SSL عبر دعم PyOpenSSL إلى urllib3.

يبدو أن @ t-8ch يعمل على إخراجها من الحديقة من خلال العمل على urllib3. سأتركه يخبرنا متى يمكن إغلاق هذا.

يحتوي urllib3 على دعم اختياري لـ SNI مع python2 ، على الرغم من وجود بعض التبعيات الاختيارية. (انظر urllib3 # 156 ).

أعتقد أن هذا يجب أن يعمل باستخدام:

from requests.packages.urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3

بعد إضافة هذا إلى packages في setup.py

requests.packages.urllib3.contrib

لاحظ أنه لا يتم استيراد الحزمة contrib افتراضيًا.

يوجد بديلان أساسيان لتمكين SNI في الطلبات:

  • قم بإنشاء وظيفة لتمكين SNI يدويًا والتي تقوم أساسًا بتشغيل الكود أعلاه. (الجانب السلبي هو أن المستخدمين سيحتاجون إلى تمكين دعم SNI بشكل صريح).
  • حاول استيراد المتطلبات المسبقة. إذا كانت موجودة ، فقم بتمكين SNI ، وإلا فلا تفعل ذلك.

ليس لدي مشكلة في تنفيذ أي من كلا البديلين ، على الرغم من أنني أفضل معرفة أيهما سيكون الخيار المفضل للطلبات. أنا شخصيا أصوت للبديل الثاني.

راجع للشغل: هل يمكننا إعادة فتح المشكلة الآن بعد أن حصلنا على دعم من urllib3؟

أنا في الواقع أفضل النوع الأول لأن الأشخاص الذين يحتاجون إليه هم الذين يعرفون أنهم سيحتاجون إليه وهم قليلون بما يكفي بحيث لا يسبب الكثير من الشكاوى. ومع ذلك ، إذا كنا سنكون متسقين مع واجهة برمجة التطبيقات الحالية ، فستكون الأخيرة هي الطريقة لتنفيذها. حاليًا ، سيوفر urllib3 (والطلبات) واجهة برمجة التطبيقات لإرسال طلبات HTTPS بدون وجود وحدة ssl ولكنها ستفشل في حالة عدم توفر وحدة ssl. بمعنى آخر ، واجهة برمجة التطبيقات موجودة ويمكنك استخدامها ولكنها لن تعمل فقط وهذا ما يشير إليه الاستثناء.

بالنسبة لإعادة فتح هذا ، فهذا متروك لـ @ kennethreitz. المشكلة بالطبع (مع كل هذا) هي أننا حاليًا تحت تجميد الميزات (# 1165 ، # 1168) لذلك لست متأكدًا مما إذا كان العمل يستحق القيام به لأنه قد لا يتم قبوله.

اسمحوا لي أن أكون أكثر وضوحًا: ما قصدته بالبديل الثاني هو "حاول استخدام SNI إذا كانت الأقسام الاختيارية متاحة ، ولكن ما زلت تستخدم SSL كما هو الحال دائمًا." هذا لا ينبغي أن يكسر أي شيء موجود حتى الآن.

بالنسبة لإعادة فتح (أو عدم) المشكلة ، IMHO ، لا ينبغي الاستخفاف بهذه المشكلة. يمكن أن تصبح الطلبات عديمة الفائدة بدون دعم SNI للعديد من السيناريوهات. على وجه الخصوص ، تصبح النطاقات المتعددة على مضيف IPv4 واحد بدون SNI مستحيلة. وعناوين IPv4 الإضافية غير واردة بالنسبة للعديد من المستخدمين (بسبب تكلفتها).

على أي حال ، هذه ميزة نصف ، نصف خطأ ، على الرغم من أنني سأنتظر رد @

هوغو: لقد أجريت للتو طلبات تثبيت Pip -U ، وعندما لا يمكنني استيراد المساهمات.
كيف يمكنني إصلاح ذلك؟ (خطأ في الاستيراد: لا توجد وحدة باسم مساهمات).

يوم الجمعة ، 3 مايو 2013 الساعة 1:12 مساءً ، Hugo Osvaldo Barrera <
[email protected]> كتب:

يحتوي urllib3 على دعم اختياري لـ SNI مع python2 ، على الرغم من وجود القليل
التبعيات الاختيارية. (انظر urllib3 # 156https: //github.com/shazow/urllib3/pull/156
).

أعتقد أن هذا يجب أن يعمل باستخدام:

من request.packages.urllib3.contrib استيراد pyopenssl
pyopenssl.inject_into_urllib3

لاحظ أنه لا يتم استيراد حزمة المساهمة بشكل افتراضي.

يوجد بديلان أساسيان لتمكين SNI في الطلبات:

  • قم بإنشاء وظيفة لتمكين SNI يدويًا والتي تقوم أساسًا بتشغيل ما ورد أعلاه
    الشفرة. (الجانب السلبي هو أن المستخدمين سيحتاجون إلى تمكين SNI بشكل صريح
    الدعم).
  • حاول استيراد المتطلبات المسبقة. إذا كانت موجودة ، فقم بتمكين SNI ، وإلا
    لا تفعل.

ليس لدي مشكلة في تنفيذ أي من كلا الخيارين ، على الرغم من أنني أفضل
لمعرفة أيهما سيكون الأفضل للطلبات. أنا شخصيا أصوت ل
البديل الثاني.

-
قم بالرد على هذه الرسالة الإلكترونية مباشرة أو tHubhttps: //github.com/kennethreitz/requests/issues/749#issuecomment -17406518
.

لا يتضمن ملف setup.py الخاص بالطلب تلك الحزمة (المصدر الموجود هناك ، ولكنه مستبعد عند التثبيت / الحزم) ، لذلك لم يتم تثبيته ، ولهذا ذكرت:

بعد إضافة هذا إلى packages in setup.py
الطلبات.packages.urllib3.contrib

ستحتاج أساسًا إلى التثبيت من المصدر.
تحقق من طلب السحب الخاص بي إذا كنت مهتمًا ، فإن القيام بهذا العمل هو مجرد سطرين. :)

"حاول استخدام SNI إذا كانت الأقسام الاختيارية متاحة ، ولكن ما زلت تستخدم طبقة المقابس الآمنة (SSL) لأنها ليست كذلك دائمًا لدينا."

SSL ليس دائمًا موجودًا على الرغم من ذلك. كانت هذه وجهة نظري. نحاول حاليًا استخدامه ولكننا نفشل بشدة وسريع إذا لم يكن لدينا وحاول المستخدم تقديم طلب https. وبالطريقة التي وصفتها بها ، كنت تحت الانطباع بأن SNI تطلب من المستخدم تمرير فكرة إضافية إلى urllib3 وكنت تركز فقط على الإعداد الخاص بها. إذا كان كل ما هو ضروري هو # 1347 فأنا 100٪ وراء هذا.

سيكون من الرائع حقًا أن يكون هذا هو (دعم SNI) الافتراضي والطلبات
يعمل فقط بدون أي كود إضافي أو إعداد من المصدر. بالنسبة لـ urllib3 الخاص به 2
أسطر من التعليمات البرمجية. لماذا لا تضيف ذلك فقط إلى الطلبات. هل أنا أحلم بيوم؟ :)

يوم الجمعة ، 3 مايو 2013 الساعة 10:43 مساءً ، كتب إيان كورداسكو إخطارات github.com:

"حاول استخدام SNI إذا كانت الأقسام الاختيارية متاحة ، ولكن لا تزال تستخدم SSL كـ
نحن دائمًا نمتلكها ، فهي ليست كذلك ".

SSL ليس دائمًا موجودًا على الرغم من ذلك. كانت هذه وجهة نظري. حاليا نحاول و
استخدمه ولكن افشل بشدة وسريع إذا لم يكن لدينا وحاول المستخدم القيام به
طلب https. الطريقة التي وصفتها بها على الرغم من أنني كنت تحت
الانطباع سيتطلب SNI من المستخدم تمرير فكرة إضافية إلى urllib3
وكنت تركز فقط على الإعداد لها. إذا كان كل هذا ضروريًا
هو # 1347 https://github.com/kennethreitz/requests/issues/1347 ثم أنا
100٪ وراء هذا.

-
قم بالرد على هذه الرسالة الإلكترونية مباشرة أو tHubhttps: //github.com/kennethreitz/requests/issues/749#issuecomment -17426626
.

pythonmobile تدور في الأعلى. إذا لم يتوقف عن الدوران ، فأنت تحلم.

inception

ترك تعليق من أجل الآخرين الذين قد يواجهون نفس المشكلة مثلي:
إذا كنت تواجه مشكلة في إنشاء طلبات آمنة باستخدام مكتبة requests ، لا سيما عند محاولة الوصول إلى تطبيق مستضاف على Google App Engine ، فقد يكون هذا هو السبب. الخطأ الذي كنت أراه هو "حدث EOF بشكل ينتهك البروتوكول". لتشخيص هذا ، حاول ضرب نفس المضيف باستخدام s_client (استبدل example.com بالمضيف المعني):

openssl s_client -connect example.com:443
openssl s_client -connect example.com:443 -servername example.com

إذا فشل الأمر الأول مع "فشل المصافحة" ونجح الأمر الثاني ، فأنت تحاول الوصول إلى خادم يستخدم SNI. يحتوي الموضوع الحالي على بعض المعلومات الجيدة حول كيفية تشغيل requests في هذه الحالة. ما فعلته هو محاولة تشغيل from requests.packages.urllib3.contrib import pyopenssl في ipython ، وواصلت تثبيت أي أخطاء استيراد. YMMV.

mshang الإصدار 1.2.3 يجب أن يفعل ذلك نيابة عنك بالفعل ؛ هل أنت متأكد أنك تقوم بتشغيل هذا الإصدار؟

hobarrera نعم ، أنا أقوم بتشغيل 1.2.3. requests.packages.urllib3.contrib موجودًا ، لكن بيانات الاستيراد هذه لا تزال تسببت في مجموعة من أخطاء الاستيراد. اضطررت إلى تثبيت ndg-httpsclient ونسيت ماذا أيضًا.

صيح. تحاول الطلبات فقط استيراد الوحدات المطلوبة ، وإذا لم تستطع الاستسلام والاستمرار في حياتها. قد يكون من الجيد توثيق ما تحتاجه لاستخدام SNI مع الطلبات.

تم تحديد ذلك في الطلبات / الحزم / urllib3 / Contrib / pyopenssl.py :

  • pyOpenSSL (تم اختباره بـ 0.13)
  • ndg-httpsclient (تم اختباره بـ 0.3.2)
  • pyasn1 (تم اختباره بـ 0.1.6)

(أو python3.2 أو أعلى ، والذي يعمل دائمًا)

يبدو أن كلا من الطلبات و urllib3 معطلين لـ SNI حاليًا. واحد
المشكلة هي أنه إذا أضاف المرء timeout = 5.0 ، فإن الكود يتصرف بشكل مختلف عن
بدون مهلة. المشكلة الثانية هي المجالات غير الموجودة.
تحتاج الاختبارات إلى إضافة المزيد من نطاقات SNI مقارنةً بالاعتماد على
قمة الرأس / httpbin /. كلاهما لا يعكس استخدام SNI على الإطلاق.

يوم الإثنين 10 حزيران (يونيو) 2013 الساعة 4:57 صباحًا ، Thomas Weißschuh
إخطاراتgithub.com

تم تحديد ذلك في الطلبات / الحزم / urllib3 / Contrib / pyopenssl. pyhttps: //github.com/kennethreitz/requests/blob/master/requests/packages/urllib3/contrib/pyopenssl.py
:

  • pyOpenSSL (تم اختباره بـ 0.13)
  • ndg-httpsclient (تم اختباره بـ 0.3.2)
  • pyasn1 (تم اختباره بـ 0.1.6)

(أو python3.2 أو أعلى ، والذي يعمل دائمًا)

-
قم بالرد على هذه الرسالة الإلكترونية مباشرة أو tHubhttps: //github.com/kennethreitz/requests/issues/749#issuecomment -19187417
.

pythonmobile إذا كان الأمر كذلك ، ولديك حالة اختبار جيدة قابلة للتكرار ، فالرجاء فتح مشكلة لتمييزها على urllib3. لا تحتوي الطلبات على رمز خاص بـ SNI (على حد علمي) ، لذا فإن الإصلاح هناك سيصلحنا أيضًا.

ما لم يتم إصلاح urllib3 بالفعل ، والذي يبدو أنه يحدث كثيرًا هذه الأيام. Shazow _et. al._ هي رائعة جدا. @ t-8ch ، هل رأيت يا رفاق / أصلحت هذا بالفعل؟

أعتقد أنه إذا كتبنا الاختبارات في الطلبات ، فمن الأسهل كتابتها واختباراتها ، على الرغم من أن هذا يعني فقط أنها ستختبر كود urllib3 في الغالب. بهذه الطريقة ، سيكون من الأسهل التحقق من كل استيراد لـ urllib3 في الطلبات ، ما إذا كان sni معطلاً أم لا وإطلاق إنذار. سأكتب اختبارات الطلبات قريبًا.

آسف pythonmobile ، لا أوافق. =)

SNI هي وظيفة urllib3 بشكل صريح. إذا تم كسر SNI في urllib3 ، فيجب عليك بالتأكيد تزويد هذا المشروع بإصلاح أو اختبار أو على الأقل تقرير خطأ. عندما يتم إصلاح هذا المشروع ، سيتم إصلاح الطلبات بطريقة سحرية أيضًا (عندما نقوم بتحديث urllib3 في المرة القادمة ، وهو ما نقوم به كثيرًا إلى حد ما). =)

في حين أن المزيد من الاختبارات للطلبات لن يضر بالتأكيد ، كما قال Lukasa ، ستحتاج إلى كتابة اختبار لـ urllib3 إذا كنت ترغب في رؤية هذا ثابتًا بالفعل. :)

لدينا بالفعل العديد من الاختبارات في نفس السياق ، اتصل بي إذا كنت بحاجة إلى أي مساعدة.

يبدو أن سلوك المهلة لـ pyOpenSSL يختلف عن سلوك ملف
وحدة SSL القياسية:

from OpenSSL import SSL
import socket
import ssl

sock = socket.create_connection(('httpbin.org', 443), timeout=4.0)
ssl_sock = ssl.wrap_socket(sock)
ssl_sock.send('GET /ip HTTP/1.1\r\nHost: httpbin.org\r\n\r\n')
print(ssl_sock.recv(10000))

ctx = SSL.Context(SSL.TLSv1_METHOD)
sock = socket.create_connection(('httpbin.org', 443), timeout=4.0)
ctn = SSL.Connection(ctx, sock)
ctn.set_connect_state()

ctn.send('GET /ip HTTP/1.1\r\nHost: httpbin.org\r\n\r\n')
print(sock.read(10000))

يؤدي هذا إلى طرح WantReadError ، وهو نفس الشيء الذي تم إلقاؤه أيضًا من urllib3
عند تحديد مهلة.

الوثائق لها
هذا ليقول عن الخطأ:

The operation did not complete; the same I/O method should be called again
later, with the same arguments. Any I/O method can lead to this since new
handshakes can occur at any time.

The wanted read is for dirty data sent over the network, not the clean data
inside the tunnel. For a socket based SSL connection, read means data coming at
us over the network. Until that read succeeds, the attempted
OpenSSL.SSL.Connection.recv, OpenSSL.SSL.Connection.send, or
OpenSSL.SSL.Connection.do_handshake is prevented or incomplete. You probably
want to select() on the socket before trying again. 

لا أعرف كيف يجب التعامل مع المهلة. هل المقبس بطريقة سحرية
تذكر المهلة على استدعاءات select() أم أن هذه مهمة
urllib3؟
لا يبدو تتبع المهلة يدويًا أمرًا مضحكًا حقًا.

pythonmobile ماذا تقصد بالمجالات غير الموجودة. لا أستطيع أن أتبعك.

pythonmobile هل يمكنك تجربة التغييرات من shazow / urllib3 # 233 ومعرفة ما إذا كان الرمز يعمل مع pyopenssl والمهلة؟

@ t-8ch pythonmobile : هل يمكنكم مشاهدة هذا الموضوع أيضًا: https://github.com/kennethreitz/requests/issues/1522#issuecomment -22443282

سيكون من الجيد الحصول على هذه الطلبات في اختبار الوحدة داخل urllib3 أو الطلبات.

تكمن مشكلة الحصول على هذه الاختبارات كوحدة في أنها تظهر فقط في تكوينات محددة للغاية. على سبيل المثال ، لم أتمكن مطلقًا من إعادة إنتاج النصف الثاني من هذه المشكلة أو # 1522 على أي من أنظمتي ، سواء كانت Windows أو OS X أو Ubuntu. لهذا السبب سألت pythonmobile لإجراء اختبار وحدة urllib3 .

ملحوظة: @ t-8ch ، لا أعتقد أنني أشكرك بما يكفي على عملك ، سواء هنا أو عند urllib3 . انت رائع. = د: كعكة:: أناناس:: موز:: ملف تعريف الارتباط:: بيرز:

lukasa شكرًا: ابتسم: أعتقد أنه يمكنني إضافة نفسي إلى AUTHORS.txt في وقت ما في المستقبل.

@ t-8ch افعلها. : +1:

التغييرات في shazow / urllib3 # 233 (تم سحبها الآن إلى urllib3 master) تعمل على إصلاح المشكلة بالنسبة لي ( SSLError('bad handshake', WantReadError()) ) التي حدثت لبعض عناوين url ، في بعض الأحيان ، في بعض التكوينات: rage4 :. هل يمكننا سحب هذا في طلبات سيد؟

rcoup سنقوم بسحب إصدار محدث إلى الطلبات عندما

أنا أقوم بتشغيل Python 2.7.6 ولا يمكنني تثبيت pyOpenSSL. لقد جربت العمل البديل في منشور htis -> https://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support/18579484#18579484

لا يمكنني أيضًا الترقية بواسطة Python. أي حلول أخرى؟

أطلب منا إعادة النظر في الاستخدام غير المشروط (إن وجد) لـ "injection_into_urllib3 ()".

تمت الإضافة قبل 7 سنوات ، وكان الهدف هو "إضافة دعم SNI لـ Python 2"

يوصف "urllib3.contrib.pyopenssl.inject_into_urllib3 ()" بـ "Monkey-patch urllib3 مع دعم بروتوكول SSL المدعوم من PyOpenSSL.":
(https://github.com/urllib3/urllib3/blob/master/src/urllib3/contrib/pyopenssl.py)

التبرير:
1: الأمان / الاستقرار: يجب أن يكون الترقيع القرد لاستبدال استخدام المكتبة القياسي بمكتبة تابعة لجهة خارجية أكثر عملية جراحية ، خاصة بالنسبة لـ ssl. إذا كان التصحيح مخصصًا للدعم في Python2 ، فعليك على الأقل التحقق من وجود إصدار رئيسي. أو أفضل من ذلك ، تحقق مما إذا كان دعم SNI موجودًا بالفعل ssl.HAS_SNI .

2: غير ضروري: اعتبارًا من 10 كانون الأول (ديسمبر) 2014 ، تم نقل كامل وحدة SSL الخاصة بـ Python 3.4 إلى Python 2.7.9. انظر PEP 466 للتبرير. https://www.python.org/downloads/release/python-279/. يتيح ذلك دعم SNI في المكتبة القياسية لـ> v2.7.9

3: غير مرن: كما تم تنفيذه ، لا توجد طريقة لتعطيل هذا السلوك. الخيار الوحيد لمنع استخدام requests لسياق pyopenssl هو إلغاء تثبيت pyopenssl من بيئة Python بالكامل.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات