Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django ALLOWED_HOST setting for Elastic beanstalk instance behind Elastic Load Balancer

Q. How do I set django ALLOW_HOSTS on elastic beanstalk instance to allow Elastic Load Balancer IP?

Background

I deployed django website on elastic beanstalk. Website domain is added to ALLOW_HOSTS so normal requests are accepted by django correctly.

ALLOWED_HOSTS = ['.mydomain.com']

Elastic Load balancer visit Elastic beanstalk instances directly with IP address for health check, so next line allow the health check:

# add elastic beanstalk instance local ip
aws_ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=0.1).text
ALLOWED_HOSTS.append(aws_ip)

But I still got invalid HOST IP errors that seems elastic beanstalk instances are visited with elastic load balancer public IP. There are solutions online for EC2 deployments as you can set HTTPD softwares to set http HOST header when it's visited by IP directly. But we cannot config apache on elastic beanstalk. So how do I add elastic load balancer IP to the ALLOW_HOSTS?

like image 463
Cloudream Avatar asked Dec 23 '15 04:12

Cloudream


2 Answers

There is no good reason to accept traffic that is directed to your ELB's IP. For the health check, my preferred method:

import requests
try:
    internal_ip = requests.get('http://instance-data/latest/meta-data/local-ipv4').text
except requests.exceptions.ConnectionError:
    pass
else:
    ALLOWED_HOSTS.append(internal_ip)
del requests
  • No complicated apache configuration, which depend on your domain
  • Fails quickly on dns, no need to rely on timeout
like image 102
noamk Avatar answered Nov 19 '22 12:11

noamk


I believe the best approach would be to configure Apache to handle request host validation. Even with beanstalk you should be able to configure Apache using .ebextensions.

The general idea is to check incoming requests for the 'ELB-HealthChecker/1.0' User-Agent and the health check URL you set as the request's REQUEST_URI. Those requests can have their host header changed to an allowed host with the RequestHeader set Host command.

If really don't want to configure Apache, you could implement a custom middleware to override Django's CommonMiddleware to allow the health checker requests to bypass Django's ALLOWED_HOST validation.

I went into greater detail in this answer if you need more on implementing one of these solutions.

like image 30
yummies Avatar answered Nov 19 '22 11:11

yummies