You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:852) #646
Hi guys by any chance any of you have seen this issue when using httpx + trio, if so how did you manage to fix it?
This is happening when starting a request to an IP on port 80 that then redirects to 443.
Traceback (most recent call last):
File "/home/project/lib/python3.6/site-packages/trio/_ssl.py", line 466, in _retry
ret = fn(*args)
File "/usr/lib/python3.6/ssl.py", line 689, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:852)
Not seems that, no.
Does it reproduce on asyncio too?
Does it reproduce if connecting to https directly, rather than the redirect you mention?
Is the URL public, so that we could reproduce the issue?
Trying to access https://109.169.53.101/ in the browser shows an insecure connection page (on iOS Safari) — are certificates up to date there? Besides, inspecting the certificate in my browser shows « Version: 3 » — I assume that means SSLv3? If so, then the error is probably due to HTTPX only supporting non-deprecated certificates (TLS v1.2 and up). (And it might be that iOS Safari uses the same rule, ie dropped support for SSLv3.)
At this point I’d suggest verifying the SSL/TLS version used by the server certificates.
Shoudn't verify=False bypass any certificates issues? I inspected the IP with testssl.sh and SSLv3 is not being served, only TLSv1.2 and H2
SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 not offered
TLS 1.2 offered (OK)
TLS 1.3 not offered and downgraded to a weaker protocol
NPN/SPDY not offered
ALPN/HTTP2 h2, http/1.1 (offered)
The error doesn't exists if I simple try to connect directly to 443, only. So I would think that would be a redirect problem? Not passing context or something?
Also in what way would I be able to change the context in order to support SSLv2 and SSLv3 by default? I don't see any mention on how to do it in the documentation.
I assume that's because said IP is located on an internal network I can't access here?
My best guess is — are you supposed to make an HTTPS request on port 80 anyway? Aren't those supposed to be issued on port 443? Can't you switch to making the request on port 443 in the first place, in order to not hit the HTTP:80 => HTTPS:443 redirection?
This leads me to think — it might be possible that HTTPX does not honor changing the port when it receives a new redirection. We'd need to check that.
As far as I see via curl when the redirect is issued the port isn't there. By any chance httpx or even h11 is forcing the chosen port into the redirect?
$ curl -vLk "http://109.169.53.101:80"
* Rebuilt URL to: http://109.169.53.101:80/
* Trying 109.169.53.101...
* TCP_NODELAY set
* Connected to 109.169.53.101 (109.169.53.101) port 80 (#0)
> GET / HTTP/1.1
> Host: 109.169.53.101
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Wed, 18 Dec 2019 14:56:01 GMT
< Server: Apache/2.4.29
< Location: https://109.169.53.101/
< Content-Length: 231
< Content-Type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
* Connection #0 to host 109.169.53.101 left intact
* Issue another request to this URL: 'https://109.169.53.101/'
* Trying 109.169.53.101...
* TCP_NODELAY set
* Connected to 109.169.53.101 (109.169.53.101) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=cozybot.com
* start date: Oct 20 02:46:07 2019 GMT
* expire date: Jan 18 02:46:07 2020 GMT
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55c581148580)
> GET / HTTP/2
> Host: 109.169.53.101
> User-Agent: curl/7.58.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 301
< date: Wed, 18 Dec 2019 14:56:01 GMT
< server: Apache/2.4.29
< location: https://www.109.169.53.101/
< content-length: 235
< content-type: text/html; charset=iso-8859-1
<
* Ignoring the response-body
* Connection #1 to host 109.169.53.101 left intact
* Issue another request to this URL: 'https://www.109.169.53.101/'
* Could not resolve host: www.109.169.53.101
* Closing connection 2
curl: (6) Could not resolve host: www.109.169.53.101
Also you can find this issue if you try to connect to facebook.com on port 80.
It seems that everytime there is a Location something is forcing the add of port 80 when it shoudn't.
It looks like the issue is that httpx is including the :80 in the outgoing Host: header on the first request, and then the server is mirroring that back when it tries to redirect to https. So technically httpx is doing nothing wrong and the server is buggy, but httpx is doing something unusual that tickles the bug. Instead, httpx should leave out the port on outgoing host headers iff it's the default port.
Activity
lovelydinosaur commentedon Dec 18, 2019
Not seems that, no.
Does it reproduce on asyncio too?
Does it reproduce if connecting to https directly, rather than the redirect you mention?
Is the URL public, so that we could reproduce the issue?
florimondmanca commentedon Dec 18, 2019
@freis Is it the entire traceback? The more details we get on what happened exactly, the easier it is to debug. :-)
Also, you can run your program with trace mode on and report back the results here (there will be many details, but that's okay):
florimondmanca commentedon Dec 18, 2019
Also, it might just be that the error you're encountering is just what it says: the server is trying to use an SSL/TLS version we don't support.
These are the options set on the
SSLContextby HTTPX:Related: #155
freis commentedon Dec 18, 2019
Hello all thanks for your responses.
@tomchristie didn't test it on asyncio, also this doesn't happen when connecting to https directly.
@florimondmanca here is the log trace:
When connecting with port 80
When connecting to port 443
On the connection with 443 he decided to use http2 at the beggining because the server also has it, but it can be done without it also.
florimondmanca commentedon Dec 18, 2019
Trying to access https://109.169.53.101/ in the browser shows an insecure connection page (on iOS Safari) — are certificates up to date there? Besides, inspecting the certificate in my browser shows « Version: 3 » — I assume that means SSLv3? If so, then the error is probably due to HTTPX only supporting non-deprecated certificates (TLS v1.2 and up). (And it might be that iOS Safari uses the same rule, ie dropped support for SSLv3.)
At this point I’d suggest verifying the SSL/TLS version used by the server certificates.
freis commentedon Dec 18, 2019
Shoudn't verify=False bypass any certificates issues? I inspected the IP with testssl.sh and SSLv3 is not being served, only TLSv1.2 and H2
And these are the ciphers ofered:
The error doesn't exists if I simple try to connect directly to 443, only. So I would think that would be a redirect problem? Not passing context or something?
Also in what way would I be able to change the context in order to support SSLv2 and SSLv3 by default? I don't see any mention on how to do it in the documentation.
florimondmanca commentedon Dec 18, 2019
@freis I was able to reproduce the issue using these sample commands (in an IPython shell/asyncio):
Full traceback + TRACE logs.
(You'll notice that it fails on the first attempt to connect — doesn't get a chance to get a response and redirect.)
If I omit
:80(or pass:443), I get a different error:gaierror: [Errno 8] nodename nor servname provided, or not known.Full traceback and TRACE logs.
I assume that's because said IP is located on an internal network I can't access here?
My best guess is — are you supposed to make an HTTPS request on port 80 anyway? Aren't those supposed to be issued on port 443? Can't you switch to making the request on port 443 in the first place, in order to not hit the HTTP:80 => HTTPS:443 redirection?
This leads me to think — it might be possible that HTTPX does not honor changing the port when it receives a new redirection. We'd need to check that.
florimondmanca commentedon Dec 18, 2019
So, this line in the TRACE logs seems to indicate that HTTPX is issuing the post-redirect HTTPS request on port 80:
TRACE [2019-12-18 11:26:41] httpx.dispatch.connection_pool - new_connection connection=HTTPConnection(origin=Origin(scheme='https' host='109.169.53.101' port=80))And the reason why that is is because the server included
:80in theLocation, i.e.https://109.169.53.101:80/, as can be seen in this log line:So it seems to me that HTTPX is doing what it's told, and it's an issue with the server — it shouldn't include
:80in the HTTPS redirect URL.freis commentedon Dec 18, 2019
As far as I see via curl when the redirect is issued the port isn't there. By any chance httpx or even h11 is forcing the chosen port into the redirect?
Also you can find this issue if you try to connect to facebook.com on port 80.
It seems that everytime there is a Location something is forcing the add of port 80 when it shoudn't.
freis commentedon Dec 18, 2019
Also if it helps what I'm doing is:
njsmith commentedon Dec 18, 2019
It looks like the issue is that httpx is including the
:80in the outgoingHost:header on the first request, and then the server is mirroring that back when it tries to redirect to https. So technically httpx is doing nothing wrong and the server is buggy, but httpx is doing something unusual that tickles the bug. Instead, httpx should leave out the port on outgoing host headers iff it's the default port.freis commentedon Dec 18, 2019
It's wierd saying that the server is buggy if the same happens when trying the same with facebook.com, right?
I've test it with curl and it is what you are saying is true, it happens when the host has the port there: