Назад | Перейти на главную страницу

Как я могу получить настоящий удаленный IP-адрес в Gunicorn от NGINX

Я всегда получаю localhost как удаленный IP. Мое приложение работает под Nginx-Gunicorn

Это моя конфигурация для 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;
}

Это мой формат журнала для Gunicorn:

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

И мои журналы стрельбы выглядят так:

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"

Помните, nginx передает запрос в Gunicorn за вас, поэтому любой запрос, который доходит до Gunicorn, будет смотрюс точки зрения Gunicorn, как будто он исходит от хоста, nginx.

Ваша проблема в вашем access_log_format. Из Документы Gunicorn:

| 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        |

Вы используете %(h)s где вам нужно вытащить содержимое X-Forwarded-For заголовок запроса. В приведенной выше таблице это показано как {Header}i, за исключением того, что вам нужно заменить Header с заголовком, который вам действительно нужен, оставив вас с {X-Forwarded-For}i вместо того h.

Итак, этот (непроверенный) формат журнала должен работать, основываясь на примерах, которые вы привели до сих пор, и документации Gunicorn:

access_log_format = '%({X-Forwarded-For}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'