I want to serve a real-time stream that has to be securely encrypted due to sensitive data.
I've successfully got normal WebSockets streaming using both gevent and gunicorn as direct frontends, but now I need to make it secure, and am looking for either of these:
Speed is not super important here as the number of connections will be low. However, the integrity of the data is important.
To secure the transport, you should use a secure protocol like https:// instead of the unsecure https:// protocol. For WebSockets, you should use the wss:// (TLS-encrypted WebSockets) protocol instead of the unsecure ws:// protocol.. Using the latter method leaves the connection susceptible to third-party interference.
WebSocket Client with PythonCreate a new File “client.py” and import the packages as we did in our server code. Now let's create a Python asynchronous function (also called coroutine). async def test(): We will use the connect function from the WebSockets module to build a WebSocket client connection.
To open a websocket connection, we need to create new WebSocket using the special protocol ws in the url: let socket = new WebSocket("ws://javascript.info"); There's also encrypted wss:// protocol. It's like HTTPS for websockets.
The communication can be sent either way at any time during the lifetime of the WebSocket connection. The client and the server are continuously connected — data can be sent to the clients all the time, without any need to request it. It's fairly easy to work with WebSockets in Python.
Assuming that you have your app running correctly over non-SSL Tornado WebSockets, change the listen call from:
app.listen(args.listen_port, args.listen_interface)
to:
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"),
})
where "mydomain.crt" and "mydomain.key" are your usual SSL certificate files, and lib_dir is the directory they live in.
Don't forget to change the client to use "wss:"
Also note that the port you specify in the listen call will still be used if you specify ssl_options. i.e. it will not revert to listening on port 443.
You can check out the websockify project. Websockify is a proxy that allows a WebSockets capable browser to communicate with a raw binary TCP server. It does this by base64 encoding all traffic to/from the browser. However, the project is modular and the websocket.py file is a general WebSocket server that is designed to be extended (and there a couple of included tests that show how this works). It would be fairly easy to disable the base64 encoding if that is not needed for you project.
Websockify also includes a Javascript library 'websock.js' which is designed to interact with websockify. It will transparently fallback to using web-socket-js (Flash based) if the browser does not have native WebSocket support.
Websockify supports secure (TLS/wss) connections and also is able to answer Flash security policy requests inline on the same port.
Disclaimer: I made websockify.
Take a look at the standalone websockets server of the pywebsocket project supported by Google.
Note that this Python module uses CGIHTTPServer
so you need to tweak it to make it secure. I had a similar requirement for a project I was involved in some months ago, so I forked the standalone.py module and removed the dependencies with CGI stuff but I haven't tested secure connections very much.
Maybe you can import OpenSSL.SSL
and set up a WebSocketServer
as it is in my script. It should use a WebSocketRequestHandler
with the proper configuration of use_tls
, private_key
and certificate
in order to implement TLS (Transport Layer Security).
Read the source code. I think you can extend it to meet your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With