How to Make Django's ALLOWED_HOSTS work with AWS ELB Health Checks

5 January 2014

Django 1.3.6 introduced an ALLOWED_HOSTS setting that let’s you configure a whitelist of domain names that your Django app should respond to. This is a smart security feature, and can save your servers a lot of overhead from bad requests. However, the feature blocks internal requests from Amazon Web Services’ Elastic Load Balancer because the ELB health check uses an internal IP address instead of a domain name. After some Googling, it seems that most folks were solving this by setting ALLOWED_HOSTS = ['*'], basically disabling the feature. Bad Idea™.

Since the internal IP address the EC2 instance uses could change over time and because we want our settings to work no matter how many instances we spin up, I turned to ec2metadata to dynamically add the internal IP to ALLOWED_HOSTS. This still gives us the same security/traffic benefits because the IP space is reserved for internal networks only; meaning that external web traffic cannot easily fake your internal IP address when requesting URIs. I’m using the python-requests library, but you could make this work with urllib if you don’t want external dependencies.