SSL/HTTPS – Secure Web and WebSocket server in python

As a next step, I created a SSL/HTTPS – Secure Web and WebSocket server in python. It can be found in github as wotking example and as (updated) gist:
https://github.com/SevenW/httpwebsockethandler
https://gist.github.com/SevenW/47be2f9ab74cac26bf21

In this post, I described how to setup a python webserver that servers normal webpages, as well as websockets at the same port. In other words, at the same page. I real application using it is the Plugwise-2-py web application. This application can actually switch on and off lights, so there are some demands on its security and robustness.

Enabling SSL/HTTPS in a python webserver is actually very simple.

It requires one to setup a certificate to prove it concerns your website, and the webservers socket needs to be wrapped with SSL.
The wrapping code simply looks like this:

server = ThreadedHTTPServer(('', port), SimpleHTTPServer)
server.daemon_threads = True
server.auth = b64encode(credentials)
if secure:
	server.auth = b64encode(credentials)
	server.socket = ssl.wrap_socket (server.socket, certfile='./server.pem', server_side=True)
server.serve_forever()

Actually the method ssl.wrap_socket does the trick.

Adding a certificate is a bit more elaborate. Several blogs describe how to generate a self-signed certificate. If the website is intended to be visited by others, then it may be better to get a certificate from an official agency. This can be done for free at StartCom: https://www.startssl.com/. Using such an offical certificate is strongly recommended.
To generate a simple self-signed certificate simply type this in a linux command box:
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
Respond with enter to the questions, or fill in something nicer, although it does not really matter. Output of the openssl command looks like:

Generating a 1024 bit RSA private key
.....++++++
.....................++++++
writing new private key to 'server.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:

The generated file ‘server.pem‘ now needs to be copied to the current directory when the webserver is started. This is also the webroot of the server. This certificate contains both the private key, as well as the site certificate.

Finally, I revisited the HTTPWebSocketHandler class, and added exception handling. Originally it could not properly deal with silently disappearing socket connections with the web clients, for example when a computer went to a standby state.

One thought to “SSL/HTTPS – Secure Web and WebSocket server in python”

Leave a Reply

Your email address will not be published. Required fields are marked *