SSL Encryption for Django’s Local/Native Server

Django comes packaged with a lightweight python server. It is not intended to be a production server but more a testing/development host. Running the server is as easy as running the following command within a Django project:

python manage.py runserver

Since it’s so lightweight, it doesn’t come with the same abilities as other servers like Apache or Nginx. It can’t perform encryption, however, there’s a nifty tool called stunnel that can do it for you!

“Stunnel is an open-source multi-platform computer program, used to provide universal TLS/SSL tunneling service” (Wikipedia).

Environment

The following steps were performed on my iMac running OS X Mavericks with a Django 1.5 installation. I believe my instructions should still work for different versions (most) and Linux distributions.

Steps

Initially, I downloaded the latest version of Stunnel, however I ran into numerous compiling issues. One of them being: “ld: warning: directory not found for option ‘-L/usr//lib64.’” The error indicated I did not have the necessary 64x library. When I downloaded version, 4.54, everything compiled nicely.

  • Download the stunnel-4.54.tar.gz source code.
  • Open a terminal window and run the following command to untar (unzip) the file.
 tar –xvf stunnel-4.54.tar.gz
  • Run the following commands to enter the directory and install the tool (credit).
cd stunnel-4.54
./configure && make && make check && sudo make install
  • During the install stage, you will be required to enter in certificate data. Stunnel will conveniently make a self-signed SSL certificate for you and save it to /usr/local/etc/stunnel/stunnel.pem. Thanks Stunnel!
  • Create a configuration file for Stunnel (credit). I put the file inside my Django project to keep things organized.
vim dev_https
  • Edit the file and add the following lines in order to manipulate Stunnel to work with your environment.
pid=
cert=/usr/local/etc/stunnel/stunnel.pem
foreground=yes
debug=7
[https]
accept=<HTTPS ACCEPTING PORT>
connect=<LOCAL PORT YOUR DJANGO SERVER IS USING>
TIMEOUTclose=1
  • Save the file (For vim: ESC ‘:wq’ ENTER).

config

  • Start the Stunnel HTTPS tunneling service.
sudo stunnel <PATH OF dev_https>

stunnel
  • Next, start your Django server.
python manage.py runserver 127.0.0.1:< LOCAL PORT YOUR DJANGO SERVER IS USING>

django

Note – I used 127.0.0.1 purposefully as my hosting IP address, I only want Django to run locally. I do not want the server to run on a public/accessible IP.  Only stunnel will receive web requests.

That’s it! Now stunnel is listening for all encrypted, incoming messges on whatever port you specified. When a request comes in, it will decrypt it and send it locally to your Django server. Following, Django will then respond through the tunnel to the requesting client with the proper data.