Python TLS版本匹配
问题描述
我使用的是python3.8 我在我的Ubuntu系统上得到以下输出:>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.1f 31 Mar 2020'
>>> ssl.PROTOCOL_TLSv1_2
<_SSLMethod.PROTOCOL_TLSv1_2: 5>
我正在尝试通过TLS使用MODBUS TCP连接,因此我在#warning myCode START
和#warning myCode END
行之间添加了一些相关函数
这是客户端:
class TcpMaster(Master):
"""Subclass of Master. Implements the Modbus TCP MAC layer"""
def __init__(self, host="127.0.0.1", port=502, timeout_in_sec=5.0):
"""Constructor. Set the communication settings"""
super(TcpMaster, self).__init__(timeout_in_sec)
self._host = host
self._port = port
self._sock = None
def _do_open(self):
"""Connect to the Modbus slave"""
if self._sock:
self._sock.close()
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_timeout(self.get_timeout())
self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
call_hooks("modbus_tcp.TcpMaster.before_connect", (self, ))
#warning myCode START
context = SSLContext(PROTOCOL_TLS_CLIENT)
context.load_verify_locations('cert.pem')
with create_connection((self._host, self._port)) as client:
print("1")
with context.wrap_socket(client, server_hostname=self._host) as tls:
print(2)
1==1
#warning myCode END
self._sock.connect((self._host, self._port))
call_hooks("modbus_tcp.TcpMaster.after_connect", (self, ))
def _do_close(self):
"""Close the connection with the Modbus Slave"""
if self._sock:
call_hooks("modbus_tcp.TcpMaster.before_close", (self, ))
self._sock.close()
call_hooks("modbus_tcp.TcpMaster.after_close", (self, ))
self._sock = None
return True
def set_timeout(self, timeout_in_sec):
"""Change the timeout value"""
super(TcpMaster, self).set_timeout(timeout_in_sec)
if self._sock:
self._sock.setblocking(timeout_in_sec > 0)
if timeout_in_sec:
self._sock.settimeout(timeout_in_sec)
def _send(self, request):
"""Send request to the slave"""
retval = call_hooks("modbus_tcp.TcpMaster.before_send", (self, request))
if retval is not None:
request = retval
try:
flush_socket(self._sock, 3)
except Exception as msg:
#if we can't flush the socket successfully: a disconnection may happened
#try to reconnect
LOGGER.error('Error while flushing the socket: {0}'.format(msg))
self._do_open()
self._sock.send(request)
def _recv(self, expected_length=-1):
"""
Receive the response from the slave
Do not take expected_length into account because the length of the response is
written in the mbap. Used for RTU only
"""
response = to_data('')
length = 255
while len(response) < length:
rcv_byte = self._sock.recv(1)
if rcv_byte:
response += rcv_byte
if len(response) == 6:
to_be_recv_length = struct.unpack(">HHH", response)[2]
length = to_be_recv_length + 6
else:
break
retval = call_hooks("modbus_tcp.TcpMaster.after_recv", (self, response))
if retval is not None:
return retval
return response
def _make_query(self):
"""Returns an instance of a Query subclass implementing the modbus TCP protocol"""
return TcpQuery()
我不能看到打印程序开始等待并永远持续下去。当我检查Wireshark时,我得到以下输出:
我认为这个错误是由于TLS版本的原因,我的python支持1.2 TLS,但我在Wireshark上看到了TLS1.0版本。我如何解决该问题?
当我中断等待进程时,我收到以下消息:
with context.wrap_socket(client, server_hostname=self._host) as tls:
File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "/usr/lib/python3.8/ssl.py", line 1040, in _create
self.do_handshake()
File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
KeyboardInterrupt
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
编辑: 如果我试一下下面的线条,它不起作用。客户端发送TLSv1版本。
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.options |= ssl.OP_NO_SSLv3
context.options |= ssl.OP_NO_TLSv1
context.options |= ssl.OP_NO_TLSv1_1
解决方案
我认为出现此错误是因为TLS版本,
这是网络/传输层问题,即客户端没有收到服务器的响应,因此不会发送TCPACK,或者客户端确实发送了ACK,但它在到达服务器的途中丢失了(不清楚您在哪里嗅探流量)。
它与TLS版本无关,因此您无法将其作为此级别进行求解。
相关文章