urlfetch.UrlfetchException: _ssl.c:510: EOF произошел с нарушением протокола

Я использую Python 2.7.6 на Ubuntu.

Я получаю эту ошибку, когда использую urlfetch (1.0.2) для отправки данных на удаленный сервер. Начинается 2 дня назад после обновления ssl сертификата сервера.

О подобных проблемах сообщалось и в другом пакете Python request. Решение состоит в том, чтобы обновить некоторые зависимости, запустив

pip install --force-reinstall requests[security]

но я получил только это

Requirement already satisfied: requests[security] in /usr/lib/python2.7/dist-packages
  requests 2.2.1 does not provide the extra 'security'

Ничего не скачивается и не устанавливается.

Некоторые сообщения предполагают, что это связано с шифром (https://github.com/kennethreitz/requests/issues/3608#issuecomment-250681069)

openssl s_client -connect www.example.com:443 
CONNECTED(00000003)
140353237063328:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 305 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

Выглядит нормально? Могу ли я что-нибудь сделать, чтобы это исправить?

Целевой сервер работает на Google App Engine. Новый сертификат SSL не поддерживает vip.

Информация о версии Ubuntu:

NAME="Ubuntu"
VERSION="14.04.2 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.2 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

person Anthony Kong    schedule 18.05.2017    source источник


Ответы (2)


Мой первый выбор состоял в том, чтобы использовать этот ответ для решения проблемы путем исправления обезьяны ssl.py.

import ssl
from functools import wraps
def sslwrap(func):
    @wraps(func)
    def bar(*args, **kw):
        kw['ssl_version'] = ssl.PROTOCOL_TLSv1
        return func(*args, **kw)
    return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)

Однако это не сработало.

В конце концов я обнаружил, что могу решить эту проблему, обновив python до 2.7.13 из исходного кода. Вот шаги:

1) Установите зависимость разработчика Python

sudo apt-get install -y \
autotools-dev      \
blt-dev            \
bzip2              \
dpkg-dev           \
g++-multilib       \
gcc-multilib       \
libbluetooth-dev   \
libbz2-dev         \
libexpat1-dev      \
libffi-dev         \
libffi6            \
libffi6-dbg        \
libgdbm-dev        \
libgpm2            \
libncursesw5-dev   \
libreadline-dev    \
libsqlite3-dev     \
libssl-dev         \
libtinfo-dev       \
mime-support       \
net-tools          \
netbase            \
python-crypto      \
python-mox3        \
python-pil         \
python-ply         \
quilt              \
tk-dev             \
zlib1g-dev

2) Скачать исходный код

wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tgz

3) Распаковать

tar xfz Python-2.7.13.tgz

4) настроить

cd Python-2.7.13/
./configure --prefix /usr/local/lib/python2.7.13 --enable-ipv6

5) построить

make

6) развернуть

sudo make install

7) Установите pip и urlfetch и другие зависимости

person Anthony Kong    schedule 18.05.2017
comment
Также вы можете попробовать использовать pyenv или pythonz для установки новых python. - person duyue; 11.11.2017

Эта ошибка возникает в более старых версиях Python, которые не поддерживают расширение TLS SNI (индикация имени сервера). Вам необходимо использовать SNI для подключения к сайтам, размещенным в App Engine, с помощью HTTPS. Похоже, поддержка SNI присутствует в Python 2.7.9 и более поздних версиях.

Если вы отправляете запросы из приложения App Engine, написанного на Python, и вам нужна поддержка SNI, вам необходимо ссылка на версию 2.7.11 библиотеки ssl в вашем файле app.yaml, иначе вы столкнетесь с той же проблемой.

person Phillip Pearson    schedule 18.05.2017