I am using python 3.8 I got below outputs on my Ubuntu system:
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.1f 31 Mar 2020'
>>> ssl.PROTOCOL_TLSv1_2
<_SSLMethod.PROTOCOL_TLSv1_2: 5>
I am trying to use Modbus TCP connection with TLS so I added some related function between #warning myCode START
and #warning myCode END
lines
This is Client side:
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()
I coundt see print("2") program start waiting and contuinue forever. And when I checked the wireshark, I get below outputs:
I think this errors occurs because of the TLS version, my python support 1.2 TLS but I see TLS1.0 version on the wireshark. How can I solve the problem ?
When I interrupt the waiting process I get this:
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)
EDIT: If I try below lines, it does not work. Client send TLSv1 version.
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
CodePudding user response:
I think this errors occurs because of the TLS version,
This is a network/transport layer problem, i.e. the client does not get the servers response and thus does not send the TCP ACK - or the client does send the ACK but it is lost on the way to the server (it is unclear where you sniff the traffic).
It has nothing to do with the TLS version and therefore you cannot solve it as this level.