简体   繁体   English

向SocketServer添加SSL支持

[英]Adding SSL Support to SocketServer

I have a Server based on ThreadingTCPServer . 我有一个基于ThreadingTCPServer的服务器。 Now Ii want to add SSL Support to that Server. 现在我想要为该服务器添加SSL支持。 Without SSL it works fine but with SSLv3 I cant connect a Client to the Server, it always throws an exception: Error 111 Connection Refused . 没有SSL它工作正常但使用SSLv3我无法将客户端连接到服务器,它总是抛出异常: Error 111 Connection Refused The error mens there's no SSL Server on that port. 错误是该端口上没有SSL服务器。

I added the SSL Support based on an example I found here at Stackoverflow. 我根据Stackoverflow上的示例添加了SSL支持。 Here's my code: 这是我的代码:

Server: 服务器:

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

Client: 客户:

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

The key and certificate file is created using open SSL. 密钥和证书文件是使用开放SSL创建的。 I hope somebody can tell me what the problem is. 我希望有人能告诉我问题是什么。

thanks for your help 谢谢你的帮助

best regards patrick 最好的问候帕特里克

Only use the standard library 仅使用标准库

Server side : 服务器端 :

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()

Client side : 客户端 :

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()

works well 效果很好

In fact ssl from the standard library works ok, maybe the problem with the initial code was that you were not asking the base class not to bind and activate. 实际上来自标准库的ssl工作正常,可能初始代码的问题是你没有要求基类不绑定和激活。 See below working example based on TCPServer. 请参阅以下基于TCPServer的工作示例。 Certificate and Key files are expected to be in the same directory. 证书和密钥文件应位于同一目录中。

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()

install openssl 安装openssl

sudo aptitude install python-openssl sudo aptitude安装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()

now test server 现在测试服务器

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM