2010-09-16 12 views
10

Deseo enviar datos de un cliente al servidor en un socket TCP TLS desde múltiples subprocesos de cliente, así que comparto el mismo socket ssl con todos los subprocesos. La comunicación funciona con un subproceso, pero si utilizo más de un subproceso, el servidor TLS se bloquea con un ssl.SSLError (SSL3_GET_RECORD: descifrado fallido o un mal registro mac).Problema de Python ssl con multiprocesamiento

más específica: No depende de qué proceso primero llama al método SSLSocket.write(), pero este proceso es el único de este tiempo en el que se puede llamar. Si otro proceso llama al write(), el servidor dará como resultado la excepción descrita anteriormente.

He utilizado este código básico:

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) 

Y esta es la traza inversa:

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 

Respuesta

17

El problema es que está reutilizando la misma conexión para ambos procesos. La forma en que SSL encripta los datos hace que esto falle: los dos procesos tendrían que comunicarse entre ellos sobre el estado de la conexión SSL compartida. Incluso si lo hace funcionar, o si no usó SSL, los datos llegarían al servidor mezclados; no tendría forma de distinguir qué bytes provienen de qué proceso.

Lo que debe hacer es dar a cada proceso su propia conexión SSL, haciendo la conexión en subproc.do. Alternativamente, no haga que los subprocesos se comuniquen con el servidor, sino comuníquese con el proceso principal y haga que el proceso principal lo retransmita a través de la conexión SSL.

+0

¡Gracias por la información! Temía que este fuera el problema. Creo que lo haré en un proceso que solo haga la comunicación SSL y todos los demás procesos se comunicarán con este a través de las tuberías. ¿Esto suena razonable? –

+1

¿Sería tan amable y podría explicar por qué incluso una cerradura no resuelve este problema? –

+1

Estaba teniendo problemas similares con el uso de SSL y multiprocesamiento. Proceso. Encontré ese cambio al uso de subprocesos múltiples. He leído lo suficiente sobre este problema. No puedo encontrar exactamente lo que leí que me llevó a seguir este camino, pero creo que es debido a la forma en que la biblioteca openssl está utilizando la información del proceso para hacer algo con el en/descifrado en el zócalo sin procesar. Y cuando ese socket se crea en un proceso y luego pasa a otro proceso, algo sale mal. Crear en un hilo y pasar a otro hilo parece estar bien – danielpops