如何从 NGINX 获取 Gunicorn 上的真实远程 IP

如何从 NGINX 获取 Gunicorn 上的真实远程 IP

我总是将 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"'

我的 gunicorn 日志如下所示:

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

请记住,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"'

相关内容