pyopenssl
pyopenssl copied to clipboard
How to set timeout for do_handshake()?
Hello, I met a weird connection problem.
TCP connection is ok to establish with my target IP. However, it hangs for a long time at do_handshake()
.
Here is my code. conn.settimeout(3)
and conn.setblocking(True)
is used for TCP connection timeout.
import socket
from OpenSSL import crypto, SSL
ssl_context = SSL.Context(method=SSL.SSLv23_METHOD)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn = SSL.Connection(ssl_context, sock)
conn.settimeout(3)
conn.connect(("some_ip", 443))
print('> connected')
conn.setblocking(True)
print('> set to blocking')
conn.do_handshake()
print('> done handshake')
Sometimes it just resets when calls do_handshake()
. This is good, which I can ignore it and continue to proceed other targets.
$ python xxx.py
> connected
> set to blocking
Traceback (most recent call last):
File "xxx.py", line 15, in <module>
conn.do_handshake()
File "/usr/local/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1934, in do_handshake
self._raise_ssl_error(self._ssl, result)
File "/usr/local/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1663, in _raise_ssl_error
raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (104, 'ECONNRESET')
It hangs! This is the worst situation. I have to interrupt it.
$ python xxx.py
> connected
> set to blocking
^CTraceback (most recent call last):
File "xxx.py", line 15, in <module>
conn.do_handshake()
File "/usr/local/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1933, in do_handshake
result = _lib.SSL_do_handshake(self._ssl)
KeyboardInterrupt
I did a test. do_handshake()
raises exception after 300 seconds. It surprises me that it's not due to timeout.
$ time python xxx.py
> connected
> set to blocking
Traceback (most recent call last):
File "xxx.py", line 15, in <module>
conn.do_handshake()
File "/usr/local/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1934, in do_handshake
self._raise_ssl_error(self._ssl, result)
File "/usr/local/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1663, in _raise_ssl_error
raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (104, 'ECONNRESET')
real 5m3.233s
user 0m0.355s
sys 0m0.028s
300 seconds is not acceptable. There are thousands of targets to scan. I cannot wait for N*300 seconds, although it's a small portion.
python:3.7.9-slim
PyOpenSSL==19.1.0
How can it make do_handshake()
succeed or fail within a small amount of time?
Thanks.
I found 300 seconds as well in openssl command.
$ time openssl s_client -connect some_ip:443
CONNECTED(00000003)
write:errno=104
---
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
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1609729737
Timeout : 300 (sec) # <=== 300 seconds
Verify return code: 0 (ok)
---
real 5m3.172s
user 0m0.004s
sys 0m0.000s
Hey @vvoody,
I would also like to see the pyOpenSSL
Connection
object have a settimeout()
. There is a settimeout()
function within the <class 'ssl.SSLSocket'>
. You can see it fire below, after running c_rehash
:
#!/usr/bin/env python3
from socket import socket
import ssl
hostname = 'google.com'
port = 443
with socket() as sock:
sock.setblocking(True)
sock.connect((hostname, port))
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations(cafile=None,
cadata=None,
capath="/path/to/ca_files/")
with context.wrap_socket(sock=sock,
server_hostname=hostname,
do_handshake_on_connect=False) as ssl_sock:
ssl_sock.settimeout(2.0)
ssl_sock.do_handshake()
print(hostname, ssl_sock.getpeername(), ssl_sock.version())
print(ssl_sock)
Unfortunately, it is an old issue, see #168