#python #ssl #gsm
#python #ssl #gsm
Вопрос:
Я выполняю SSL-соединение с помощью скрипта Python. Когда я подключаюсь к высокоскоростному соединению, оно выполняется успешно, но при использовании медленного GSM-соединения я получаю сообщение об ошибке:
File "/usr/lib/python2.7/ssl.py", line 831, in do_handshake
self._sslobj.do_handshake()
Я использую SIM800L для подключения GSM в системе Linux (debian).
Я могу установить SSL-соединение через ‘openssl s_client -connect …’ в терминале, поэтому я думаю, что в ssl.py (кажется, всегда занимает около 60 секунд до указанной выше ошибки).
Существует ли ограничение ~ 60 секунд на вышеуказанное рукопожатие? Если да, то как это можно увеличить?
РЕДАКТИРОВАТЬ С БОЛЕЕ ПОДРОБНОЙ ИНФОРМАЦИЕЙ:
По Wi-Fi
Openssl подключается в течение нескольких секунд. Скрипт на Python выполнен успешно.
имя@name: ~ $ openssl s_client -строка подключения-ats.iot.eu-west-1.amazonaws.com:8883 -tls1_2 -CAfile /сертификат /AmazonRootCA1.pem -сертификат /certificate.pem.key -ключ /сертификат /private.pem.key
CONNECTED(00000003)
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
verify return:1
depth=0 CN = *.iot.eu-west-1.amazonaws.com
verify return:1
---
Certificate chain
0 s:CN = *.iot.eu-west-1.amazonaws.com
i:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
1 s:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
i:C = US, O = Amazon, CN = Amazon Root CA 1
2 s:C = US, O = Amazon, CN = Amazon Root CA 1
i:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
3 s:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
i:C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MI....3h9VY=
-----END CERTIFICATE-----
subject=CN = *.iot.eu-west-1.amazonaws.com
issuer=C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA SHA512:RSA SHA512:ECDSA SHA384:RSA SHA384:ECDSA SHA256:RSA SHA256:DSA SHA256:ECDSA SHA224:RSA SHA224:DSA SHA224:ECDSA SHA1:RSA SHA1:DSA SHA1
Shared Requested Signature Algorithms: ECDSA SHA512:RSA SHA512:ECDSA SHA384:RSA SHA384:ECDSA SHA256:RSA SHA256:DSA SHA256:ECDSA SHA224:RSA SHA224:DSA SHA224
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5400 bytes and written 1514 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 51...9
Session-ID-ctx:
Master-Key: 9...F
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1598423483
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: yes
---
имя@name:~ $ sudo python /application/awsiotpub.py
Loaded MQTT configuration information.
Endpoint URL: string-ats.iot.eu-west-1.amazonaws.com
Root Cert: /cert/AmazonRootCA1.pem
Device Cert: /cert/certificate.pem.key
Private Key: /cert/private.pem.key
Connecting to AWS IoT Broker...
ssl.py : SSLSocket.__init__ if connected
ssl.py : SSLSocket.__init__ if connected, self._sslobj = :
<_ssl._SSLSocket object at 0xb62480c0>
ssl.py - do_handshake()
ssl.py - do_handshake() - _check_connected START
ssl.py - do_handshake() - _check_connected DONE
ssl.py - do_handshake() - try do_handshake() START
ssl.py - do_handshake() - try do_handshake() DONE
Connected with status: 0
True
Publishing...
Published: 123
ON GSM
Openssl successfully connects after 67sec. Python script fails on ssl.py handshake after ~60sec.
name@name:~ $ openssl s_client -connect
string-ats.iot.eu-west-1.amazonaws.com:8883 -tls1_2 -CAfile
/cert/AmazonRootCA1.pem -cert /cert/certificate.pem.key -key
/cert/private.pem.key
CONNECTED(00000003)
.....
name@name:~ $ sudo python /application/awsiotpub.py
Loaded MQTT configuration information.
Endpoint URL: string-ats.iot.eu-west-1.amazonaws.com
Root Cert: /cert/AmazonRootCA1.pem
Device Cert: /cert/certificate.pem.key
Private Key: /cert/private.pem.key
Connecting to AWS IoT Broker...
ssl.py : SSLSocket.__init__ if connected
ssl.py : SSLSocket.__init__ if connected, self._sslobj = :
<_ssl._SSLSocket object at 0xb62480c0>
ssl.py - do_handshake()
ssl.py - do_handshake() - _check_connected START
ssl.py - do_handshake() - _check_connected DONE
ssl.py - do_handshake() - try do_handshake() START
ssl.py - do_handshake() - finally settimeout START
ssl.py - do_handshake() - finally settimeout DONE
Traceback (most recent call last):
File "awsiotpub.py", line 40, in <module>
Client.connect(mqtt_url, port = 8883, keepalive=240)
File "../paho/mqtt/client.py", line 937, in connect
Return self.reconnect()
File "../paho/mqtt/client.py" line 1100, in reconnect
Sock.do_handshake()
File "/user/lib/python2.7/ssl.py", line 839, in do_handshake
Self._sslobj.do_handshake()
Soket.error: [Errno 0] Error
ssl.py выдержка рукопожатия
.
.
.
def do_handshake(self, block=False):
"""Perform a TLS/SSL handshake."""
print("ssl.py - do_handshake()")
print("ssl.py - do_handshake() - _check_connected START")
self._check_connected()
print("ssl.py - do_handshake() - _check_connected DONE")
timeout = self.gettimeout()
try:
if timeout == 0.0 and block:
print("ssl.py - do_handshake() - if timeout == 0.0")
self.settimeout(None)
print("ssl.py - do_handshake() - try do_handshake() START")
self._sslobj.do_handshake()
print("ssl.py - do_handshake() - try do_handshake() DONE")
finally:
print("ssl.py - do_handshake() - finally settimeout START")
self.settimeout(timeout)
print("ssl.py - do_handshake() - finally settimeout DONE")
if self.context.check_hostname:
print("ssl.py - do_handshake() - context.check_hostname START")
if not self.server_hostname:
print("ssl.py - do_handshake() - context.check_hostname - if not server_hostname")
raise ValueError("check_hostname needs server_hostname "
"argument")
match_hostname(self.getpeercert(), self.server_hostname)
print("ssl.py - do_handshake() - context.check_hostname DONE")
.
.
.
Комментарии:
1. Для ответа на этот вопрос недостаточно подробностей. Нет способа воспроизвести проблему, и вы даже не показываете полезное описание ошибки, а только то, что «что-то» происходит в SSL
do_handshake
. Но что касается таймаутов — смотрите эту часть документации .2. @SteffenUllrich Спасибо за ответ! Я предоставил более подробную информацию. тайм-аут внутри ssl.py : do_handshake длится 240 секунд, но он останавливается и выдает ошибку через ~ 60 секунд.
3. «тайм-аут внутри ssl.py : do_handshake составляет 240 секунд» — где вы это видите? Я не вижу, что вы распечатываете тайм-аут, который вы получаете откуда
gettimeout
-то, и я не вижу, чтобы вы его явно устанавливали.4. @SteffenUllrich Да, извините, в приведенном выше вы этого не видите. В скрипте Python я указываю 240 секунд в качестве тайм-аута, а в ssl.py Я попробовал «печать (тайм-аут)», которая печатает 240. Не уверен, что этот тайм-аут предназначен для части подключения, а не для рукопожатия?
5. Я не могу воспроизвести вашу проблему. Я пробовал с простым сервером, который завершает рукопожатие через 80 секунд. У меня в моем клиенте Python нет тайм-аута, т. Е. рукопожатие завершено через 80 секунд. Если бы я использовал
settimeout
меньшее значение, это соответствовало бы этому параметру и привело бы к ошибке «Время ожидания операции рукопожатия истекло». Пробовал с python 2.7.13 и 3.7.3.