IT Share you

파이썬 요청 requests.exceptions.SSLError : [Errno 8] _ssl.c : 504 : EOF가 프로토콜 위반으로 발생했습니다.

shareyou 2020. 11. 30. 20:16
반응형

파이썬 요청 requests.exceptions.SSLError : [Errno 8] _ssl.c : 504 : EOF가 프로토콜 위반으로 발생했습니다.


OpenSSL 1.0.1c, python 2.7.3, Requests 1.0.3 및 1.0.4 (둘 다 시도)를 사용하는 Ubuntu 12.10 에 있으며 다음 코드를 사용하여 url 변수의 웹 사이트에 연결하려고 할 때입니다.

def SendInitialRequest(xmlmessage, redirecturl):
    url = 'https://centineltest.cardinalcommerce.com/maps/txns.asp'

    payload = 'cmpi_msg=' + ET.tostring(xmlmessage)
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    r = requests.post(url, data=payload, headers=headers, verify=None)
    print r.text

다음 오류가 발생합니다.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "clams/libs/centinel/thinclient.py", line 134, in SendInitialRequest
    r = requests.post(url, data=payload, headers=headers, verify=None)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 87, in post
    return request('post', url, data=data, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 269, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 364, in send
    r = adapter.send(request, **kwargs)
  File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/adapters.py", line 163, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

openssl을 사용하여 연결을 시도하면 다음이 반환됩니다.

$ openssl s_client -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
140019346777760: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 226 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---

tls1을 사용하도록 강제하면 작동합니다 (출력이 잘림).

$ openssl s_client -tls1 -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU
verify error:num=20:unable to get local issuer certificate
verify return:0
---

나는 이것에 대한 수많은 버그 보고서보았다 . 그러나 파이썬 요청 라이브러리를 사용하여 문제를 해결할 수있는 방법을 찾지 못했습니다. 도움을 주시면 대단히 감사하겠습니다.


요청 문제 페이지 에서 다른 사용자를 위해 여기에 다시 게시 :

Requests '는 버전 1 이전에이 작업을 지원하지 않습니다. 버전 1 이후에는 다음과 같이 HTTPAdapter를 서브 클래 싱해야합니다.

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)

이 작업을 마치면 다음을 수행 할 수 있습니다.

import requests
s = requests.Session()
s.mount('https://', MyAdapter())

해당 세션 개체를 통한 모든 요청은 TLSv1을 사용합니다.


verify = False를 설정하면 서버 인증서 확인 만 건너 뛰고 SSL 프로토콜 오류를 해결하는 데 도움이되지 않습니다.

이 문제는 웹 서버에서 SSLv2가 비활성화되어 있기 때문일 수 있지만 Python 2.x는 기본적으로 PROTOCOL_SSLv23과 연결을 설정하려고합니다. 이것은 https://github.com/python/cpython/blob/360aa60b2a36f5f6e9e20325efd8d472f7559b1e/Lib/ssl.py#L1057 에서 발생합니다.

ssl_version 키워드 매개 변수를 재정 의하여 ssl 모듈에서 ssl.wrap_socket ()을 monkey-patch 할 수 있습니다. 다음 코드는 그대로 사용할 수 있습니다. 요청하기 전에 프로그램 시작 부분에 이것을 넣으십시오.

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)

Installing the "security" package extras for requests solved for me:

sudo apt-get install libffi-dev

sudo pip install -U requests[security]


This is a known bug, you can work it around with a hack:

Open up site-packages/requests/packages/urllib3/connectionpool.py (or otherwise just make a local copy of requests inside your own project), and change the block that says:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=self.ssl_version)

to:

def connect(self):
    # Add certificate verification
    sock = socket.create_connection((self.host, self.port), self.timeout)

    # Wrap socket using verification with the root certs in
    # trusted_root_certs
    self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
                                cert_reqs=self.cert_reqs,
                                ca_certs=self.ca_certs,
                                server_hostname=self.host,
                                ssl_version=ssl.PROTOCOL_TLSv1)

Otherwise, I suppose there's an override somewhere which is less hacky, but I couldn't find one with a few glances.

NOTE: On a sidenote, requests from PIP (1.0.4) on a MacOS just works with the URL you provided.


I encountered this error, and the fix appears to be turning off SNI, which Python 2.7 does not support:

http://bugs.python.org/issue5639

urllib3 on python 2.7 SNI error on Google App Engine


To people that can't get above fixes working.

Had to change file ssl.py to fix it. Look for function create_default_context and change line:

context = SSLContext(PROTOCOL_SSLv23)

to

context = SSLContext(PROTOCOL_TLSv1)

Maybe someone can create easier solution without editing ssl.py?


I had the same issue:

raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol

I had fiddler running, I stopped fiddler capture and did not see this error. Could be because of fiddler.


Unfortunately the accepted answer did not work for me. As a temporary workaround you could also use verify=False when connecting to the secure website.

From Python Requests throwing up SSLError

requests.get('https://example.com', verify=True)

I was having similar issue and I think if we simply ignore the ssl verification will work like charm as it worked for me. So connecting to server with https scheme but directing them not to verify the certificate.

Using requests. Just mention verify=False instead of None

    requests.post(url, data=payload, headers=headers, verify=False)

Hoping this will work for those who needs :).


I have had this error when connecting to a RabbitMQ MQTT server via TLS. I'm pretty sure the server is broken but anyway it worked with OpenSSL 1.0.1, but not OpenSSL 1.0.2.

You can check your version in Python using this:

import ssl
ssl.OPENSSL_VERSION

I'm not sure how to downgrade OpenSSL within Python (it seems to be statically linked on Windows at least), other than using an older version of Python.

참고URL : https://stackoverflow.com/questions/14102416/python-requests-requests-exceptions-sslerror-errno-8-ssl-c504-eof-occurred

반응형