Django: get client IP from behind Amazon Elastic Load Balancer

July 13, 2016

Last update: May 23, 2021

Tested with Django 2.2 LTS and 3.2 LTS, it works even with Application Load Balancers

The problem

We want to get the client IP when our Django project is running on different nodes behind an Amazon Elastic Load Balancer. If we use the code below:

from django.http import HttpResponse def get_ip(request): ip = request.META['REMOTE_ADDR'] return HttpResponse(ip)

the value of the ip variable is the IP of load balancer. Definetely not what we are looking for.

A solution

According to Elastic Load Balancer documentation the original IP of the client is stored and forwarded to nodes in a HTTP header called X-Forwarded-For. So to obtain the real client IP we have to add these lines to our code:

from django.http import HttpResponse def get_ip(request): ip = request.META['REMOTE_ADDR'] # during development if 'HTTP_X_FORWARDED_FOR' in request.META: # load balancer ip = request.META['HTTP_X_FORWARDED_FOR'] return HttpResponse(ip)

We have to keep in mind this part of the offial documentation:

The X-Forwarded-For request header may contain multiple IP addresses that are comma separated. The left-most address is the client IP where the request was first made. This is followed by any subsequent proxy identifiers, in a chain.

If needed, we can split the content HTTP_X_FORWARDED_FOR and get the first element.

References

  1. HTTP Headers and Classic Load Balancers

  2. HttpRequest.META


A photo of Elia Contini
Written by
Elia Contini
Sardinian UX engineer and a Front-end web architect based in Switzerland. Marathoner, traveller, wannabe nature photographer.