如何从NGINX获得Gunicorn的真正的远程IP?

我总是获得本地主机作为远程IP。 我的应用程序运行在Nginx-Gunicorn下

这是我对nginx的configuration:

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" 

请记住, nginx代理请求给Gunicorn,所以到Gunicorn的任何请求都会从Gunicorn的angular度来看,就像它来自运行nginx的主机。

你的问题在你的access_log_format 。 从Gunicorn文档 :

 | Identifier | Description | |-------------|:-----------------------------------:| | h | remote address | | u | '-' | | t | user name | | r | date of the request | | m | status line (eg 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 ,除了您需要用实际需要的标题replaceHeader ,留下{X-Forwarded-For}i而不是h

所以这个(未经testing的)日志格式应该基于你已经给出的例子和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"'