多处理的Python ssl问题

Man*_*aux 15 python ssl multiprocessing

我想从多个客户端子进程的TLS TCP套接字中将数据从客户端发送到服务器,因此我与所有子进程共享相同的ssl套接字.通信适用于一个子进程,但如果我使用多个子ssl.SSLError进程,则TLS服务器崩溃(SSL3_GET_RECORD:解密失败或错误记录mac).

更具体:它不依赖于哪个进程首先调用该SSLSocket.write()方法,但此进程是此时唯一可以调用它的进程.如果另一个进程调用write(),服务器将导致上述异常.

我使用了这个基本代码:

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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

这是回溯:

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
Run Code Online (Sandbox Code Playgroud)

Tho*_*ers 25

问题是您正在为两个进程重用相同的连接.SSL加密数据的方式使其失败 - 两个进程必须相互通信以了解共享SSL连接的状态.即使你确实使用它,或者如果你没有使用SSL,数据也会到达服务器所有的混乱; 你没有真正的方法来区分哪个字节来自哪个进程.

您需要做的是通过建立连接为每个进程提供自己的SSL连接subproc.do.或者,不要让子进程与服务器进行通信,而是与主进程通信,并使主进程通过SSL连接进行中继.

  • 我在使用SSL和multiprocessing.Process方面遇到了类似的问题.我发现切换到使用多线程.Thread充分解决了这个问题.我无法准确地找到我读到的导致我走这条路的东西,但我相信这是因为openssl库使用进程信息来对原始套接字上的en/decryption做一些事情.当在一个进程上创建该套接字然后传递给另一个进程时,出现问题.在一个线程中创建并传递给另一个线程似乎没问题 (2认同)