如何在Python中实现安全的WebSocket (wss://)服务器?
我想提供一个实时的数据流,因为里面有敏感信息,所以必须进行安全加密。
我已经成功地使用gevent和gunicorn搭建了普通的WebSocket流,但现在我需要让它变得安全,所以我在寻找以下几种方案:
- 一个可以提供安全WebSocket连接的服务器,这个服务器可以转发到(比如说)gunicorn,后者监听的是不安全的WebSocket连接。
- 一个可以直接提供安全WebSocket连接的框架。我在研究Tornado,觉得它可以做到,但我也愿意听听其他建议。
- 我使用ZeroMQ来实现发布/订阅模式。如果有适合ZeroMQ的好的WebSocket协议实现,那就太好了。
速度在这里不是特别重要,因为连接的数量会比较少。不过,数据的完整性是非常重要的。
5 个回答
看看这个独立的WebSocket服务器,它是由谷歌支持的pywebsocket项目的一部分。
需要注意的是,这个Python模块使用了CGIHTTPServer
,所以你需要对它进行一些调整,以确保安全。我几个月前参与的一个项目也有类似的需求,所以我对standalone.py模块进行了修改,去掉了与CGI相关的部分,但我对安全连接的测试不多。
也许你可以导入OpenSSL.SSL
,并像我在脚本中那样设置一个WebSocketServer
。它应该使用一个WebSocketRequestHandler
,并正确配置use_tls
、private_key
和certificate
,以实现TLS(传输层安全)。
阅读一下源代码。我觉得你可以根据自己的需求进行扩展。
你可以看看这个websockify项目。Websockify是一个代理工具,它可以让支持WebSockets的浏览器和一个普通的二进制TCP服务器进行通信。它的工作原理是把浏览器和服务器之间的所有数据都用base64编码。不过,这个项目是模块化的,里面的websocket.py文件是一个通用的WebSocket服务器,设计上可以进行扩展(里面还有一些测试示例,展示了如何使用)。如果你的项目不需要base64编码,关闭这个功能也很简单。
Websockify还包含一个名为'websock.js'的JavaScript库,专门用来和websockify进行交互。如果浏览器不支持原生的WebSocket,它会自动切换到使用web-socket-js(基于Flash的)来进行连接。
Websockify支持安全连接(TLS/wss),而且能够在同一个端口上直接处理Flash安全策略请求。
免责声明:我是websockify的开发者。
假设你的应用在没有SSL的Tornado WebSockets上运行得很好,现在你需要把监听的代码从:
app.listen(args.listen_port, args.listen_interface)
改成:
app.listen(args.listen_port, args.listen_interface, ssl_options={
"certfile": os.path.join(lib_dir, "mydomain.crt"),
"keyfile": os.path.join(lib_dir, "mydomain.key"),
})
这里的“mydomain.crt”和“mydomain.key”是你平常用的SSL证书文件,而lib_dir是这些文件所在的文件夹。
别忘了把客户端的连接方式改成“wss:”哦。
另外要注意,如果你在监听的代码中指定了ssl_options,那么你设置的端口仍然会被使用,也就是说,它不会自动改回使用443端口。