Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement a secure WebSocket (wss://) server in Python?

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:

  1. A server that can serve secure WebSocket connections that are proxied to (for example) gunicorn which listens for non-secure WebSocket connections.
  2. A framework that can serve secure WebSocket connections directly. I've been looking at Tornado and believe it can handle it, but I'm still open to suggestions.
  3. I use ZeroMQ for the PUB/SUB pattern. If there is a good WebSocket protocol implementation for ZeroMQ, that would be great.

Speed is not super important here as the number of connections will be low. However, the integrity of the data is important.

like image 602
Blixt Avatar asked May 13 '11 15:05

Blixt


People also ask

How do I create a secure WebSocket server?

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.

How do I create a WebSocket server in Python?

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.

How do I create a WSS WebSocket?

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.

Is Python good 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.


3 Answers

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.

like image 92
northernman Avatar answered Sep 28 '22 18:09

northernman


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.

like image 28
kanaka Avatar answered Sep 28 '22 17:09

kanaka


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.

like image 33
scoffey Avatar answered Sep 28 '22 16:09

scoffey