使用CherryPy的双向SSL

时间:2010-12-13 09:49:55

标签: ssl certificate ssl-certificate cherrypy client-certificates

从CherryPy 3.0开始,只需指向服务器证书和私钥即可打开单向SSL,如下所示:

import cherrypy

class HelloWorld(object):
    def index(self):
        return "Hello SSL World!"
    index.exposed = True

cherrypy.server.ssl_certificate = "keys/server.crt"
cherrypy.server.ssl_private_key = "keys/server.crtkey" 
cherrypy.quickstart(HelloWorld())

这使客户端能够验证服务器的真实性。有谁知道CherryPy是否支持双向ssl,例如服务器还可以通过验证客户端证书来检查客户端的真实性吗?

如果是的话,有人能举例说明这是怎么做的?或者发布对示例的引用?

3 个答案:

答案 0 :(得分:4)

它没有开箱即用。您必须修补wsgiserver才能提供该功能。 http://www.cherrypy.org/ticket/1001处有一张票(和补丁)正在进行中。

答案 1 :(得分:3)

我一直在寻找同样的事情。我知道CherryPy网站上有一些补丁。

我还在CherryPy SSL Client Authentication找到了以下内容。我没有将它与CherryPy补丁进行比较,但可能信息会有所帮助。

  

我们最近需要快速开发   但有弹性的REST应用程序和   发现CherryPy符合我们的需求   比其他Python网络更好   框架,如Twisted。   不幸的是,它的简单性缺乏   我们需要的关键功能,服务器/客户端   SSL证书验证。因此   我们花了几个小时写了几个   快速修改当前   发布,3.1.2。以下代码   片段是我们的修改   制成:

cherrypy/_cpserver.py

@@ -55,7 +55,6 @@ instance = None ssl_certificate = None ssl_private_key
= None
+ ssl_ca_certificate = None nodelay = True

def __init__(self):

cherrypy/wsgiserver/__init__.py

@@ -1480,6 +1480,7 @@
# Paths to certificate and private key files ssl_certificate = None ssl_private_key = None
+    ssl_ca_certificate = None

def __init__(self, bind_addr, wsgi_app, numthreads=10, server_name=None, max=-1, request_queue_size=5, timeout=10, shutdown_timeout=5):

@@ -1619,7 +1620,9 @@

self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if self.nodelay: self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-        if self.ssl_certificate and self.ssl_private_key:
+        if self.ssl_certificate and self.ssl_private_key and \
+            self.ssl_ca_certificate:
+ if SSL is None: raise ImportError("You must install pyOpenSSL to use HTTPS.")

@@ -1627,6 +1630,11 @@ ctx = SSL.Context(SSL.SSLv23_METHOD) ctx.use_privatekey_file(self.ssl_private_key) ctx.use_certificate_file(self.ssl_certificate)
+            x509 = crypto.load_certificate(crypto.FILETYPE_PEM,
+                open(self.ssl_ca_certificate).read())
+            store = ctx.get_cert_store()
+            store.add_cert(x509)
+            ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda *x:True) self.socket = SSLConnection(ctx, self.socket) self.populate_ssl_environ()
  

以上补丁需要   包含新配置   CherryPy服务器内部的选项   组态,   server.ssl_ca_certificate。这个   选项标识证书   连接客户端的权限文件   将被证实,如果   客户端不提供有效的客户端   证书将关闭   立即联系。

     

我们的解决方案具有优势和优势   缺点,主要优点   如果连接客户端没有   提供有效的证书   连接立即关闭。   这有利于安全问题   它不允许客户任何   访问CherryPy应用程序   堆。但是,由于限制   是在套接字级别完成的   CherryPy应用程序永远看不到   客户连接,因此   解决方案有点不灵活。

     

最佳解决方案将允许   客户端连接到CherryPy   套接字并发送客户端证书   进入应用程序堆栈。然后一个   自定义CherryPy工具将验证   里面的证书   应用程序堆栈并关闭   必要时连接;不幸   因为CherryPy的结构   pyOpenSSL实现它   难以检索客户端   申请表内的证书   叠加。

     

当然上面的补丁应该   只能自担风险使用。如果你   请提出更好的解决方案   让我们知道。

答案 2 :(得分:0)

如果当前版本的CherryPy不支持客户端证书验证,则可以将CherryPy配置为侦听127.0.0.1:80,安装HAProxy以侦听443并验证客户端证书并将流量转发到127.0.0.1 :80 HAProxy简单,轻便,快速,可靠。 An example of HAProxy configuration