Setting up SSL with Amazon ELB, Nginx and Django
There’s no question any site you run should be served over HTTPS. It’s one of the most essential ways of making user data more secure. With initiatives like Let’s Encrypt , barriers of entry like certificate price should soon be a thing of the past. In this post I’d like to explain how to set up SSL on an AWS Elastic Load Balancer, which is compatible with the popular Django + Nginx stack.
ELB Setup
If you require a full walkthrough, I’d recommend using this step-by-step guide from Amazon. The most significant difference in setup is having listener ports (80 and 443) forward to port 80, as illustrated here:
The server will now communicate with ELB over http, so you should configure the AWS to only accept connections from the Load Balancer.
Nginx setup
This bit of configuration will redirect users trying to access the site over http to https, which is done by checking the X-Forwarded-Proto header set by the Load Balancer when forwarding the connection. This line must be added to the configuration file to perform the redirect:
if ($http_x_forwarded_proto != 'https') { return 301 https://$host$request_uri; }
Django setup
The last part of the configuration is making Django recognize those connections as secure. Fortunately this is accomplished by configuring one setting: SECURE_PROXY_SSL_HEADER. In this particular case, it would look exactly as it does in the docs:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
And that’s all. Hope this short guide saved you some googling time!