-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ssl.SSLError: [SSL: KRB5_S_INIT] application data after close notify (_ssl.c:2605) #3535
Comments
GitMate.io thinks the contributor most likely able to help you is @asvetlov. Possibly related issues are #3502 (BUG. ssl.SSLError: [SSL: KRB5_S_INIT] application data after close notify), #3477 ("Application data after close notify" regression in 3.5.0 with SSL connection), #3052 (SSL with closed connections), #2497 (ClientSession keep transferring data after closed), and #370 (Server closes connection before sending data). |
I can reproduce it. |
OK, Will try to resolve today. |
Thanks! |
I can not trigger that on the master branch. The same on 3.5.4 (Python 3.6) |
Issue specific to Python 3.7? Also:
|
That's interesting. openssl 1.1.1-1ubuntu2.1 |
WOW. Either SSL-related issue, or asyncio race-condition, that resolves differently on different Python versions. |
3.7 can have more invariant checks. |
Seems, bug not in my changes. Problem is in aborting SSL-connection while it has buffered cleartext data. My bugs in chunked encoding triggered the same situation: connection was about to close while server had already sent some data. We have to abort connection (instead of graceful closing) when we return connection [with incomplete read response] to a pool. |
I had a glimpse on sources. Seems I can't debug them fast. I don't even figured out where is the problem: in aiohttp, in asyncio or in SSL socket implementation. What I found: The only place where It seems, we should NOT call OpenSSL's It seems, it is prohibited now (or always been?) to gracefully close SSL-connections while we have unread data (i.e. peer may sends us data unexpectedly). If that situation is possible we have to abort connection instead of graceful closing. |
Thanks for sharing your findings |
…\nThis is currently broken, see aio-libs/aiohttp#3535, test and merge when that's solved.
For those looking for a work-around to at least silence these exceptions: the traceback seen is output produced by the From my main co-routine for the loop, I call import asyncio
import ssl
import sys
SSL_PROTOCOLS = (asyncio.sslproto.SSLProtocol,)
try:
import uvloop.loop
except ImportError:
pass
else:
SSL_PROTOCOLS = (*SSL_PROTOCOLS, uvloop.loop.SSLProtocol)
def ignore_aiohttp_ssl_eror(loop):
"""Ignore aiohttp #3535 / cpython #13548 issue with SSL data after close
There is an issue in Python 3.7 up to 3.7.3 that over-reports a
ssl.SSLError fatal error (ssl.SSLError: [SSL: KRB5_S_INIT] application data
after close notify (_ssl.c:2609)) after we are already done with the
connection. See GitHub issues aio-libs/aiohttp#3535 and
python/cpython#13548.
Given a loop, this sets up an exception handler that ignores this specific
exception, but passes everything else on to the previous exception handler
this one replaces.
Checks for fixed Python versions, disabling itself when running on 3.7.4+
or 3.8.
"""
if sys.version_info >= (3, 7, 4):
return
orig_handler = loop.get_exception_handler()
def ignore_ssl_error(loop, context):
if context.get("message") in {
"SSL error in data received",
"Fatal error on transport",
}:
# validate we have the right exception, transport and protocol
exception = context.get('exception')
protocol = context.get('protocol')
if (
isinstance(exception, ssl.SSLError)
and exception.reason == 'KRB5_S_INIT'
and isinstance(protocol, SSL_PROTOCOLS)
):
if loop.get_debug():
asyncio.log.logger.debug('Ignoring asyncio SSL KRB5_S_INIT error')
return
if orig_handler is not None:
orig_handler(loop, context)
else:
loop.default_exception_handler(context)
loop.set_exception_handler(ignore_ssl_error) (Edited to disable on Python 3.7.4 and to support uvloop) |
Last line should be: |
No, it should not.
|
The way I've gotten around this is to ensure that I always read/consume the response before being done with the response. While it's not ideal if you don't actually need the response body, for my use case, it's not burdensome to call |
I have a different use-case: I read the headers and head of content for information (like what type the content is and if it's an image, how large it is). So I will not read the entire response. |
Fixed by upstream: python/cpython#13548 |
Working with python 3.7.4 |
I also got this as well with python:3.7.4 (but using https://github.com/aaugustin/websockets) |
Also using python:3.7.3-alpine3.10 |
Same problem with python:3.7.4. For now, I've solved this issue by building a docker image from python:3.7.2 |
I did some more digging into this because we were seeing this error in HTTPX. This error also seems to be impacting people in various other libraries. @socketpair has linked most of the relevant things above already, but here is a summary of what I understand:
As annoying as it sounds, this error message is saying exactly what's going on. When you close an SSL connection, the This second call to What does this all mean? There may be places/cases in aiohttp (again, I don't know it well) where a connection is closed before all the outstanding data is read from it. As far as I understand--and I am not a security expert so take this with a grain of salt-- |
This Thread is super useful for me, thanks! |
So.... do we have a fix for those of us on 3.7.3?!?!?! |
NM... traced my issue to Brotli.. installed brotlippy and all is good, even though I was getting |
Could @asvetlov elaborate how the upstream fix applies here, please? I wrote some silly code that uses Traceback (most recent call last):
File "/.../simple.py", line 101, in __aexit__
await self.w.wait_closed()
File "/.../asyncio/streams.py", line 359, in wait_closed
await self._protocol._get_close_waiter(self)
File "/.../asyncio/sslproto.py", line 529, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "/.../asyncio/sslproto.py", line 207, in feed_ssldata
self._sslobj.unwrap()
File "/.../ssl.py", line 948, in unwrap
return self._sslobj.shutdown()
ssl.SSLError: [SSL: KRB5_S_INIT] application data after close notify (_ssl.c:2730) Depending on how I massage the code, the error either happens always, or occasionally (data race?). I'm running this with Python 3.9.0a4 and beginning to suspect that maybe there's more to be fixed upstream... |
I've opened https://bugs.python.org/issue39951 for my flavour of possibly same issue. |
Is there a way to fix this without changing versions? |
aio-libs/aiohttp#3535 Suggests that this bump may fix some SSL-related errors
Getting the same error:
using Python 3.8.6 and OpenSSL 1.1.1d. |
@flvndh that one is totally unrelated to this and is coming from httpx which we have absolutely nothing to do with. |
FWIW posting in a closed issue is not the best way to get new messages noticed. If there's specific issues that still exist, it's best to submit them separately. 🔒 |
The following very simple aiohttp client:
produces the following exception:
I noticed bug #3477 but it is closed and the problem is still there (I have the latest pip version).
The text was updated successfully, but these errors were encountered: