1

I get always localhost as remote IP. My application run under Nginx-Gunicorn

This is my configuration for nginx:

server { 
   listen      80; 
   server_name api.mydomain.com;

   charset     utf-8;

   client_max_body_size 1M; 

   location / { 
      set_real_ip_from 127.0.0.1/32;
      proxy_set_header X-Forwarded-Host $host:$server_port;
      proxy_set_header X-Forwarded-Server $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_pass http://aiohttp;
   }

   access_log /var/log/nginx/api_access.log;
   error_log  /var/log/nginx/api_error.log;
}

This is my log format for gunicorn:

access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'

And my gunicorn logs look like this:

127.0.0.1 - - [28/Apr/2017:12:52:53 +0000] "GET /entrypoint?p=2&d=123456 HTTP/1.0" 200 379 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"

1 Answer 1

7

Remember, nginx is proxying the request to Gunicorn for you, so any request that reaches Gunicorn will look, from Gunicorn's perspective, like it's coming from the host running nginx.

Your problem is in your access_log_format. From the Gunicorn docs:

| Identifier  |             Description             |
|-------------|:-----------------------------------:|
| h           |            remote address           |
| u           |                 '-'                 |
| t           |              user name              |
| r           |         date of the request         |
| m           |  status line (e.g. GET / HTTP/1.1)  |
| U           |            request method           |
| q           |    URL path without query string    |
| H           |               protocol              |
| s           |                status               |
| B           |           response length           |
| b           | response length or '-' (CLF format) |
| f           |               referer               |
| a           |              user agent             |
| T           |       request time in seconds       |
| D           |     request time in microseconds    |
| L           |   request time in decimal seconds   |
| p           |             process  ID             |
| {Header}i   |            request header           |
| {Header}o   |           response header           |
| {Variable}e |         environment variable        |

You're using %(h)s where you need to be pulling the content of the X-Forwarded-For request header. In the above table, that's shown as {Header}i, except you need to replace Header with the header you actually need, leaving you with {X-Forwarded-For}i instead of h.

So this (untested) log format should work, based on the examples you've given so far, and Gunicorn's docs:

access_log_format = '%({X-Forwarded-For}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
1
  • 1
    Thanks for %({X-Forwarded-For}i)s You are right, I had to get the concrete Header Apr 28, 2017 at 13:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .