【问题标题】:How to enter SSL PEM pass phrase only once in gevent streamServer?如何在 gevent streamServer 中只输入一次 SSL PEM 密码?
【发布时间】:2013-06-17 18:58:21
【问题描述】:

每次客户端连接到服务器时,我都会收到输入 PEM 密码短语的提示。我只想在服务器启动时输入它,而不必再次输入它。 Twisted Matrix 框架只需要启动时的密码,为什么不用 gevent?还是我使用 gevent 错误? 如果我使用不需要 PEM 密码的证书,下面的代码可以正常工作,但我想使用带有密码的证书。

from gevent.server import StreamServer
from gevent.pool import Pool
from gevent import monkey

class SocketPool(object):

    def __init__(self): self.pool = Pool(1000)

    def listen(self, socket):
        while True:
            line = socket.recv(1024)
            if not line: break 
            print line
            socket.close()
            break

    def add_handler(self, socket, address):
        print "connection made:", address
        if self.pool.full(): raise Exception("At maximum pool size")
        else: self.pool.spawn(self.listen, socket)

    def shutdown(self): self.pool.kill()

monkey.patch_all()
sockPool = SocketPool() 
server = StreamServer(('', 5000), sockPool.add_handler, keyfile='key.pem', certfile='cert.pem')
server.serve_forever()

【问题讨论】:

    标签: ssl python-2.7 gevent


    【解决方案1】:

    似乎没有一种简单的方法可以在 python 2.7 上解决此问题。在内部,gevent.server uses the python ssl module 从 C 调用 OpenSSL 库。_ssl.sslwrap() 函数为每次调用创建一个新的 SSLContext,这就是每次建立连接时都会提示您输入密钥密码的原因。

    Twisted 使用 pyOpenSSL 而不是 ssl 模块。在 pyOpenSSL 中,您 create your SSLContext first 并且每次建立连接时都会使用该单个上下文。因此,使用 Twisted 时只会提示您输入一次密码。

    Python 3.2 添加了 ssl.SSLContext classwrap_socket() 方法。如果您使用的是此版本或更高版本,则可以修补 gevent 代码以使其更像 Twisted,即使用单个 SSLContext 并将对 _ssl.sslwrap() 的调用替换为对 wrap_socket() 方法的调用。不过是doesn't appear that gevent is ported to python3

    您可以通过在前面放置一个 SSL 代理来卸载 gevent 的 SSL 处理,以便将传入公共端口的 SSL 连接代理到您的 gevent 服务器上的未加密内部端口。您可以使用 Twisted 编写自己的代理或使用像 stunnel 这样的专用代理。但是,这可能会否定您最初想使用 gevent 的部分或全部原因。

    您可以修补 _ssl 模块以缓存 SSLContext 或使用其他方式接受密码。 python 2.7 中的_ssl 使用默认密码回调,它以交互方式提示输入密码。这并不难,但它要求您至少了解一点 C、python C API 和 OpenSSL API,而且您必须在部署的任何地方构建和覆盖模块。

    您可以使用自己的代码修补 gevent 以使用 SSL 包装套接字。这可以完全在 python 中使用 pyOpenSSL 之类的库来完成,但要做到这一点可能需要相当多的工作。

    最后,您可以只使用未加密的密钥。也许将密钥放在 RAM 磁盘或加密文件系统(或两者)上可以满足您的任何安全要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      相关资源
      最近更新 更多