向SocketServer添加SSL支持

问题描述:

我有一个基于ThreadingTCPServer的服务器。现在,Ii希望将SSL支持添加到该服务器。 没有SSL,它工作正常,但SSLv3我不能连接到服务器的客户端,它总是抛出一个异常:Error 111 Connection Refused。该错误表示该端口上没有SSL服务器。向SocketServer添加SSL支持

我根据我在*发现的一个例子添加了SSL支持。 这里是我的代码:

服务器:

class BeastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 
     SocketServer.BaseServer.__init__(self, server_address, 
                 RequestHandlerClass) 
     ctx = SSL.Context(SSL.SSLv3_METHOD) 
     cert = 'server.pem' 
     key = 'key.pem' 
     ctx.use_privatekey_file(key) 
     ctx.use_certificate_file(cert) 
     self.socket = SSL.Connection(ctx, socket.socket(self.address_family, 
                 self.socket_type)) 
     if bind_and_activate: 
     #self.server_bind() 
     #self.server_a 

客户:使用开放SSL创建

class Client(object) : 

    def verbinden (self, ip_) : 

     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     ssl_sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, 
        ssl_version=ssl.PROTOCOL_SSLv3, ca_certs='server.pem') 
     ssl_sock.connect((ip_, 10012)) 

     return ssl_sock 

的密钥和证书文件。 我希望有人能告诉我问题是什么。

感谢您的帮助

问候帕特里克

安装OpenSSL的

须藤资质安装python-OpenSSL的

from OpenSSL import SSL 
import socket, SocketServer 

class SSlSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 
     SocketServer.BaseServer.__init__(self, server_address, 
      RequestHandlerClass) 
     ctx = SSL.Context(SSL.SSLv3_METHOD) 
     cert = 'cert.pem' 
     key = 'private_key.pem' 
     ctx.use_privatekey_file(key) 
     ctx.use_certificate_file(cert) 
     self.socket = SSL.Connection(ctx, socket.socket(self.address_family, 
      self.socket_type)) 
     if bind_and_activate: 
      self.server_bind() 
      self.server_activate() 
    def shutdown_request(self,request): 
     request.shutdown() 

class Decoder(SocketServer.StreamRequestHandler): 
    def setup(self): 
     self.connection = self.request 
     self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) 
     self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) 

    def handle(self): 
     try: 
      socket1 = self.connection 
      str1 = socket1.recv(4096) 
      print str1 
     except Exception, e: 
      print 'socket error',e 
def main(): 
    server = SSlSocketServer(('127.0.0.1', 9999), Decoder) 
    server.serve_forever() 
if __name__ == '__main__': 
    main() 

现在测试服务器

import socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect(('localhost', 9999)) 
sslSocket = socket.ssl(s) 
print repr(sslSocket.server()) 
print repr(sslSocket.issuer()) 
sslSocket.write('Hello secure socket\n') 
s.close() 

事实上,标准库中的ssl工作正常,也许初始代码的问题在于你没有要求基类不要绑定和激活。请参阅下面基于TCPServer的工作示例。证书和密钥文件应该在同一个目录中。

import os 
import SocketServer 

class SSLTCPServer(SocketServer.TCPServer): 
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 
     """Constructor. May be extended, do not override.""" 
     SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass, False) 

     dir = os.path.dirname(__file__) 
     key_file = os.path.join(dir, 'server.key') 
     cert_file = os.path.join(dir, 'server.crt') 

     import ssl 
     self.socket = ssl.wrap_socket(self.socket, keyfile=key_file, certfile=cert_file, cert_reqs=ssl.CERT_NONE) 

     if bind_and_activate: 
      self.server_bind() 
      self.server_activate() 

只使用标准库

服务器端:

from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler 
import ssl 

class MySSL_TCPServer(TCPServer): 
    def __init__(self, 
       server_address, 
       RequestHandlerClass, 
       certfile, 
       keyfile, 
       ssl_version=ssl.PROTOCOL_TLSv1, 
       bind_and_activate=True): 
     TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate) 
     self.certfile = certfile 
     self.keyfile = keyfile 
     self.ssl_version = ssl_version 

    def get_request(self): 
     newsocket, fromaddr = self.socket.accept() 
     connstream = ssl.wrap_socket(newsocket, 
           server_side=True, 
           certfile = self.certfile, 
           keyfile = self.keyfile, 
           ssl_version = self.ssl_version) 
     return connstream, fromaddr 

class MySSL_ThreadingTCPServer(ThreadingMixIn, MySSL_TCPServer): pass 

class testHandler(StreamRequestHandler): 
    def handle(self): 
     data = self.connection.recv(4096) 
     self.wfile.write(data) 
#test code 
MySSL_ThreadingTCPServer(('127.0.0.1',5151),testHandler,"cert.pem","key.pem").serve_forever() 

客户端:

import os 
import socket, ssl 

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
ssl_sock = ssl.wrap_socket(s, 
          ca_certs="cert.pem", 
          cert_reqs=ssl.CERT_REQUIRED, 
          ssl_version=ssl.PROTOCOL_TLSv1) 
ssl_sock.connect(('127.0.0.1',5151)) 
ssl_sock.send('hello ~MySSL !') 
print ssl_sock.recv(4096) 
ssl_sock.close() 

作品以及