0

I want to log an IP address from where particular url is accessed. I am implementing this functionality in django middleware. I tried obtaining IP address using method given in this answer:

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

I debugged this method and found that request.META.get('HTTP_X_FORWARDED_FOR') was None. and request.META.get('REMOTE_ADDR') was 10.0.0.2. However, I dont understand from where this IP 10.0.0.2 came from. I am running django inside docker container on my laptop and accessing the website iniside the browser on the same laptop using address: http://127.0.0.1:9001/. So I thought ideally the address should be at least 127.0.0.1. The IP address allotted to my laptop by router is 192.168.0.100. The website will be used inside LAN. So I feel it will be more apt to log this IP address. But I checked all keys inside request.META dictionary and found none to contain IP address 192.168.0.100. Also following two keys inside request.META contain local IP:

'HTTP_ORIGIN':'http://127.0.0.1:9001'
'HTTP_REFERER':'http://127.0.0.1:9001/'

Q1. From where the IP 10.0.0.2 obtained?
Q2. What request.META key should I access to log IP address from which the website is accessed.

MsA
  • 2,599
  • 3
  • 22
  • 47
  • If your router's ip address is `192.168.0.100`, then `10.0.0.2` may be the default ip of your **Docker** network. – Ankit Tiwari May 18 '23 at 12:44
  • I think when you access your server from browser it sends request from `192.168.0.100` ip and inside docker it translate it to `10.0.0.2` becouse of that you're getting `10.0.0.2` in `request.META.get('REMOTE_ADDR')` try using reverse proxy which will get client ip and set to `HTTP_X_FORWARDED_FOR` for more info check this [post](https://serverfault.com/a/920060/967236) – Ankit Tiwari May 18 '23 at 13:00

1 Answers1

1

This is a bit of a messy "it depends" type thing. The REMOTE_ADDR is always going to be the actual IP address a response goes to, but when you're using Docker or nginx or some other proxy then it's likely not the IP you actually want. 10.x.x.x is a "local" address and likely one used by the Docker network to communicate between containers.

Often when there's some intermediate proxy for the HTTP request, it will add an additional header to help convey the actual requesting IP. However, that's not guaranteed. Some proxies add X-Forwarded-For while others add X-Real-Ip and others won't add anything unless you configure it that way. (I think nginx requires you to add configuration to actually add a header, normally it won't add anything.) The question you pointed to mentioned mod_rpaf and that's what was adding the X-Forwarded-For header. You get None in X-Forwarded-For because you don't have anything setting that value for you.

Tim Tisdall
  • 9,914
  • 3
  • 52
  • 82
  • We use nginx reverse proxy in deployment. I dont recall any explicit configuration is done by our team to add any extra headers. I dont have the whole setup currently on my laptop. But what is usually used in this scenario. – MsA May 18 '23 at 13:36
  • The [nginx `ngx_http_realip_module`](http://nginx.org/en/docs/http/ngx_http_realip_module.html) will set a `$realip_remote_addr` variable and I think defaults to passing the IP via `X-Real-IP`. You could add `real_ip_header X-Forwarded-For;` to change which header is used. For a reverse proxy you may need `proxy_set_header X-Forwarded-For $realip_remote_addr;` (but maybe that's done already by `real_ip_header`?). – Tim Tisdall May 18 '23 at 15:45
  • You may just want do do something like `x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') or request.META.get('HTTP_X_REAL_IP')` – Tim Tisdall May 18 '23 at 15:46
  • Ohkay will try this, but one weird thing. I tried getting IP addresses of all containers with `docker network inspect my_network | grep "IPv4Address"`. It lists IP addresses of `10.0.1.XXX` series. But the IP address that is getting logged is `10.0.0.2`. Any hint whats going on here? – MsA May 18 '23 at 15:51
  • sorry, no idea.. maybe `docker network inspect bridge`? I'm not really familiar with how the docker networking works. – Tim Tisdall May 18 '23 at 18:39