2010-09-16 139 views
10

我想從一個客戶端的數據發送到服務器在多個客戶端子進程的TLS TCP套接字,所以我共享相同的ssl套接字與所有子進程。通信適用於一個子進程,但如果我使用多個子進程,則TLS服務器會崩潰,並出現ssl.SSLError(SSL3_GET_RECORD:解密失敗或錯誤的記錄mac)。多重處理的Python ssl問題

更具體:它不取決於哪個進程首先調用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) 

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 

回答

17

問題是,您正在爲這兩個進程重新使用相同的連接。 SSL加密數據的方式會導致失敗 - 兩個進程必須相互通信以瞭解共享SSL連接的狀態。即使你確實使它工作,或者如果你沒有使用SSL,數據也會到達服務器,而這些服務器都是混亂的;你將沒有真正的方法來區分哪些字節來自哪個進程。

您需要做的是通過在subproc.do中進行連接,爲每個進程分配自己的SSL連接。或者,不要讓子進程與服務器通信,而是與主進程通信,並讓主進程通過SSL連接進行中繼。

+0

感謝您的信息!我擔心這會成爲問題。我想我會爲一個只進行ssl通信的進程,所有其他進程將通過管道與這個進程進行通信。這聽起來合理嗎? – 2010-09-16 08:41:55

+1

你會如此善良,你能解釋爲什麼即使一把鎖也不能解決這個問題嗎? – 2010-09-16 09:22:32

+1

我在使用SSL和multiprocessing.Process時遇到了類似的問題。我發現切換到使用多線程。線程充分解決了這個問題。我無法準確找到我讀到的內容,導致我走上了這條路,但我相信這是因爲openssl庫正在使用進程信息來處理原始套接字上的en/decryption。並且,當該套接字在一個進程上創建並傳遞給另一個進程時,出現問題。在一個線程中創建並傳遞給另一個線程似乎很好 – danielpops 2016-06-21 18:35:00