多处理的 Python ssl 问题
问题描述
我想从多个客户端子进程通过 TLS TCP 套接字将数据从客户端发送到服务器,因此我与所有子进程共享同一个 ssl 套接字.与一个子进程通信,但如果我使用多个子进程,TLS 服务器会崩溃并显示 ssl.SSLError
(SSL3_GET_RECORD:decryption failed or bad record mac).
I want to send data from a client to the server in a TLS TCP socket from multiple client subprocesses so I share the same ssl socket with all subprocesses. Communication works with one subprocess, but if I use more than one subprocesses, the TLS server crashes with an ssl.SSLError
(SSL3_GET_RECORD:decryption failed or bad record mac).
更具体:不依赖于哪个进程首先调用SSLSocket.write()
方法,但是从这个时候开始,只有这个进程可以调用它.如果另一个进程调用write()
,服务器会产生上述异常.
More specific: It does not depend which process first calls the SSLSocket.write()
method, but this process is the only one from this time on which can call it. If another process calls write()
, the server will result in the exception described above.
我使用了这个基本代码:
I used this basic code:
tlsserver.py
import socket, ssl
def deal_with_client(connstream):
data = connstream.read()
while data:
print data
data = connstream.read()
connstream.close()
bindsocket = socket.socket()
bindsocket.bind(('127.0.0.1', 9998))
bindsocket.listen(5)
while True:
newsocket, fromaddr = bindsocket.accept()
connstream = ssl.wrap_socket(newsocket,
server_side=True,
certfile="srv.crt",
keyfile="srv.key",
ssl_version=ssl.PROTOCOL_TLSv1)
deal_with_client(connstream)
tlsclient.py
import socket, ssl
import multiprocessing
class SubProc:
def __init__(self, sock):
self.sock = sock
def do(self):
self.sock.write("Test")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s)
ssl_sock.connect(('127.0.0.1', 9998))
print "Connected to", repr(ssl_sock.getpeername())
for x in (1,2):
subproc = SubProc(ssl_sock)
proc = multiprocessing.Process(target=subproc.do)
这是回溯:
Traceback (most recent call last):
File "tlsserver.py", line 21, in <module>
deal_with_client(connstream)
File "tlsserver.py", line 7, in deal_with_client
data = connstream.read()
File "/usr/lib64/python2.6/ssl.py", line 136, in read
return self._sslobj.read(len)
ssl.SSLError: [Errno 1] _ssl.c:1325: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
解决方案
问题是您为两个进程重复使用相同的连接.SSL 加密数据的方式使这失败了——两个进程必须就共享 SSL 连接的状态相互通信.即使你确实让它工作了,或者如果你没有使用 SSL,到达服务器的数据也会一团糟;您将无法真正区分哪些字节来自哪个进程.
The problem is that you're re-using the same connection for both processes. The way SSL encrypts data makes this fail -- the two processes would have to communicate with each other about the state of the shared SSL connection. Even if you do make it work, or if you didn't use SSL, the data would arrive at the server all jumbled up; you would have no real way of distinguishing which bytes came from which process.
您需要做的是通过在 subproc.do
中建立连接,为每个进程提供自己的 SSL 连接.或者,根本不让子进程与服务器通信,而是与主进程通信,并让主进程通过 SSL 连接进行中继.
What you need to do is give each process its own SSL connection, by making the connection in subproc.do
. Alternatively, don't have the subprocesses communicate with the server at all, but rather communicate with the main process, and have the main process relay it over the SSL connection.
相关文章