8

从CherryPy的3.0及以后,单向SSL可以通过简单地指向服务器证书和私钥被打开,像这样:2路SSL与CherryPy的

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,例如服务器还可以通过验证客户端证书来检查客户端的真实性?

如果是的话,有人能举个例子吗?或者发布一个例子的参考?

回答

4

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

+2

现在https://bitbucket.org/cherrypy/cherrypy/issue/1001/adding-support-for-client-certificate – Pim 2013-09-23 10:27:22

3

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

我还在CherryPy SSL Client Authentication找到了以下内容。我还没有比较这个和CherryPy补丁,但是这些信息可能会有所帮助。

最近,我们需要制定一个快速 但弹性REST应用和 发现适合的CherryPy比其他Python网络 框架,如双绞线更好我们的需求 。 不幸的是,它的简单性缺乏我们需要的 关键功能,服务器/客户端 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实现的结构,因此很难检索到 的应用程序 堆栈中的证书 。

当然,上述修补程序应该只用于您自己的风险。如果你想得到更好的解决方案 请告诉我们。

0

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