Requests: Поддержка TLS SNI

Созданный на 1 авг. 2012  ·  46Комментарии  ·  Источник: psf/requests

Кажется, у меня проблемы с использованием запросов к серверам, которым нужна поддержка TLS SNI. Когда в запросах появится эта функция? Это то, что запланировано?

Спасибо,
--Баран

Самый полезный комментарий

Это указано в request / packages / urllib3 / contrib / pyopenssl.py :

  • pyOpenSSL (проверено с 0.13)
  • ndg-httpsclient (проверено с 0.3.2)
  • pyasn1 (проверено с 0.1.6)

(Или python3.2 или выше, который всегда работает)

Все 46 Комментарий

Недоступно в Python 2.x поверх ssl-модуля stdlib.

В Twisted он есть, правда? Может быть, пора полагаться на pyopenssl или какой-то другой модуль ssl?

Есть запрос на перенос для urllib3 с добавлением поддержки SNI для Py32 +, но он все еще нуждается в тестовом покрытии. https://github.com/shazow/urllib3/pull/89

shzow: Спасибо за указатель. К сожалению, я использую Twisted / Flask, а это значит, что я придерживаюсь версии 2.7. Twisted, кажется, может делать что-то подобное, но я не видел примеров, и для этого потребуется pyopenssl + twisted декодирование. Я не эксперт ни в том, ни в другом, чтобы это осуществить. На данный момент просто подумываю обернуть какую-нибудь утилиту командной строки, например wget ... :(

PyOpenSSL должен уметь это делать на 2.x. Так что надежда есть.

Я мог бы заставить его работать с pyopenssl. Но мне все еще трудно сделать это правильно. http://pbin.be/show/719/ - вид работ. Но затем нужно создать на нем API, чтобы он был хоть сколько-нибудь полезным. Я до сих пор не могу понять, как передать агенту правильный контекст.

Лукаса: это решено?

Нет. Мы заблокированы на shazow / urllib3 # 89.

Слился. Продолжать. :)

Обратите внимание, что на данный момент он поддерживается только на Py32 +. Но этого должно быть достаточно, чтобы начать.

Еще одно справедливое предупреждение: некоторые тесты на Py32 сейчас не работают на мастере urllib3. Мы будем очень благодарны за некоторую помощь в решении этой проблемы (и это может повлиять на эту функциональность): https://github.com/shazow/urllib3/issues/128

работает для меня на archlinux x64 на py26, py27, py32, py33

Ах, я должен был квалифицировать, что это на OSX. Отморозок OSX.

t-8ch: Вы прошли тесты sni на py26 / 27/32 и 33?

Тесты SNI даже не запускаются на py2, но на py32 и py33 он работает.
Невозможно выполнить SNI с модулем ssl стандартной библиотеки до py32.

@shazow : Вы,

Я был бы счастлив иметь отдельную библиотеку, которая добавляет 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?

На самом деле я предпочитаю первое, потому что люди, которым это нужно, - это те, кто знает, что он им понадобится, и их достаточно мало, чтобы это не вызвало слишком много жалоб. Однако, если мы собираемся соответствовать существующему API, последний был бы способом его реализации. В настоящее время urllib3 (и запросы) будут предоставлять API для отправки запросов HTTPS без присутствия модуля ssl, но не будут работать в случае, если модуль ssl недоступен. Другими словами, API есть, и вы можете использовать его, но он просто не будет работать, и на это указывает исключение.

Что касается повторного открытия, это зависит от @kennethreitz. Проблема, конечно (со всем этим) в том, что мы в настоящее время замораживаем функции (# 1165, # 1168), поэтому я не уверен, стоит ли вообще делать эту работу, потому что она может быть не принята.

Позвольте мне быть немного яснее: то, что я имел в виду под второй альтернативой, было «Попробуйте использовать SNI, если доступны дополнительные зависимости, но все же используйте SSL, поскольку у нас он всегда есть, а его нет». Это не должно сломать ничего, что существовало до сих пор.

Что касается повторного открытия (или нет) вопроса, ИМХО, к этому вопросу не следует относиться легкомысленно. запросы могут стать бесполезными без поддержки SNI для многих сценариев. В частности, создание нескольких доменов на одном хосте IPv4 без SNI становится невозможным. А дополнительные IPv4-адреса для многих пользователей не обсуждаются (из-за их стоимости).

В любом случае, это наполовину функция, наполовину ошибка, хотя я буду ждать ответа @kennethreitz относительно повторного открытия проблемы.

Хьюго: Я только что выполнил запросы pip install -U, и когда я не могу импортировать contrib.
Как мне это исправить? (Ошибка импорта: нет модуля с именем contrib).

Пт, 3 мая 2013 г., 13:12, Уго Освальдо Баррера <
[email protected]> написал:

urllib3 имеет дополнительную поддержку SNI с python2, хотя с некоторыми
необязательные зависимости. (См. Urllib3 # 156 https://github.com/shazow/urllib3/pull/156
).

Я считаю, что это должно работать, используя:

из request.packages.urllib3.contrib import pyopenssl
pyopenssl.inject_into_urllib3

Обратите внимание, что пакет contrib по умолчанию не импортируется.

В основном есть две альтернативы для включения SNI в запросах:

  • Создайте функцию для ручного включения SNI, которая в основном запускает вышеуказанное
    код. (Обратной стороной является то, что пользователям необходимо будет явно включить SNI
    служба поддержки).
  • Попробуйте импортировать предварительные условия. Если они есть, включите SNI, иначе
    не надо.

У меня нет проблем с реализацией обеих альтернатив, хотя я бы предпочел
чтобы узнать, какой из них предпочтительнее для запросов. Я лично голосую за
вторая альтернатива.

-
Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/kennethreitz/requests/issues/749#issuecomment -17406518
.

request setup.py не включает этот пакет (исходный код есть, но он исключен при установке / упаковке), поэтому он не установлен, поэтому я упомянул:

После добавления в packages in setup.py
request.packages.urllib3.contrib

В основном вам нужно будет установить из исходников.
Если вам интересно, ознакомьтесь с моим запросом на перенос, чтобы выполнить эту работу, достаточно всего пары строк. :)

«Попробуйте использовать SNI, если доступны дополнительные deps, но все же используйте SSL, поскольку у нас он всегда есть, а его нет».

Однако SSL присутствует не всегда. Это была моя точка зрения. В настоящее время мы пытаемся использовать его, но терпим неудачу, если у нас его нет и пользователь пытается сделать https-запрос. Однако, как вы это описали, у меня сложилось впечатление, что SNI потребует от пользователя передать некоторые дополнительные сведения в urllib3, а вы сосредоточились только на его настройке. Если все, что нужно, это # ​​1347, то я за это на 100%.

Было бы очень хорошо, если бы это было по умолчанию (поддержка SNI) и запросы
просто работает без дополнительного кода или настройки из исходного кода. Для urllib3 это 2
строки кода. Почему бы просто не добавить это в запросы. Я мечтаю день? :)

Пт, 3 мая 2013 г., в 22:43 Ян Кордаско [email protected] написал:

"Попробуйте использовать SNI, если доступны дополнительные зависимости, но все же используйте SSL как
у нас всегда это есть, а их нет ".

Однако SSL присутствует не всегда. Это была моя точка зрения. В настоящее время мы стараемся и
используйте его, но терпите неудачу быстро и быстро, если у нас его нет, и пользователь пытается сделать
запрос https. Как вы это описали, я был под
SNI впечатления потребует от пользователя передать некоторые дополнительные сведения в urllib3.
и вы сосредоточились только на настройке для этого. Если все это необходимо
# 1347 https://github.com/kennethreitz/requests/issues/1347, тогда я
100% за этим.

-
Ответьте на это письмо напрямую или просмотрите его на Gi 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 а что еще я забыл.

Верный. Requests просто пытается импортировать необходимые модули, а если не может, сдается и продолжает свою жизнь. Тем не менее, неплохо было бы задокументировать, что вам нужно для использования SNI с запросами.

Это указано в request / packages / 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
[email protected] написал :

Это указано в request / packages / 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 или выше, который всегда работает)

-
Ответьте на это письмо напрямую или просмотрите его на Gi 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 или requests.

Проблема с получением их в качестве модульного теста заключается в том, что они появляются только в очень определенных конфигурациях. Например, мне никогда не удавалось воспроизвести ни вторую половину этого выпуска, ни # 1522 ни на одной из моих систем, будь то Windows, OS X или Ubuntu. Вот почему я попросил @pythonmobile провести воспроизводимый модульный тест. Если мы сможем его найти, мы сможем развиваться против него, иначе мы застряли в надежде, что @ t-8ch продолжит быть гением и волшебным образом решит все наши проблемы на уровне urllib3 .

NB: @ t-8ch, я не думаю, что я достаточно благодарен вам за вашу работу, как здесь, так и в urllib3 . Ты восхитителен. = D: торт:: ананас:: ​​банан:: печенье:: пиво:

@lukasa Спасибо: smile: Думаю, я мог бы добавить себя в AUTHORS.txt нибудь в будущем.

@ t-8ch Сделай это. : +1:

Изменения в shazow / urllib3 # 233 (теперь перенесены в мастер urllib3) устраняют для меня проблему ( SSLError('bad handshake', WantReadError()) ), которая иногда возникала для некоторых URL-адресов в некоторых конфигурациях: rage4 :. Можем ли мы втянуть это в мастер запросов?

@rcoup Мы добавим последнюю версию в Requests, когда мы

Я использую Python 2.7.6 и не могу установить pyOpenSSL. Я пробовал обходные пути в сообщении htis → https://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support/18579484#18579484

Я тоже не могу обновиться на Python. Какие-нибудь другие решения?

Прошу пересмотреть безусловное использование (если таковое имеется) inject_into_urllib3 ().

Добавлено 7 лет назад с целью «добавить поддержку SNI для Python 2».

«urllib3.contrib.pyopenssl.inject_into_urllib3 ()» описывается как «обезьяна-патч urllib3 с поддержкой SSL с поддержкой PyOpenSSL»:
(https://github.com/urllib3/urllib3/blob/master/src/urllib3/contrib/pyopenssl.py)

Обоснование:
1: Безопасность / стабильность: исправление Monkey для замены использования стандартной библиотеки сторонней библиотекой, вероятно, должно быть более хирургическим, особенно для 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 рейтинги

Смежные вопросы

JimHokanson picture JimHokanson  ·  3Комментарии

justlurking picture justlurking  ·  3Комментарии

NoahCardoza picture NoahCardoza  ·  4Комментарии

jake491 picture jake491  ·  3Комментарии

jakul picture jakul  ·  3Комментарии