Nginx如果透过代理获取真实IP地址
# 环境
client_ip:10.10.10.1
proxy_server_1:10.10.10.16
proxy_server_2:10.10.10.17
web_server:10.10.10.18
使用X-Forwarded-For+realip模块
使用realip模块可以解决该问题。
查看nginx的编译参数:nginx -V(默认是安装了realip模块的)
- set_real_ip_from:表示从何处获取真实IP,只认可自己信赖的IP,可以是网段,也可以设置多个。
- real_ip_header:表示从哪个header属性中获取真实IP。
- real_ip_recursive:递归检索真实IP,如果从X-Forwarded-For中获取,则需要递归检索;如果中X-Real-IP中获取,无需递归。
Nginx配置
# proxy_server_1的nginx配置
location / {
proxy_pass http://10.10.10.17;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# proxy_server_2的nginx配置
location / {
proxy_pass http://10.10.10.18;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# web_server的nginx配置,在server中新增
set_real_ip_from 10.10.10.16;
set_real_ip_from 10.10.10.17;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
使用浏览器正常访问,默认不改变日志格式的情况下,我们来看3台server的日志情况。
# proxy_server_1的日志
10.10.10.1 - - [25/Jun/2019:20:49:03 -0400] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "-"
# proxy_server_2的日志
10.10.10.16 - - [25/Jun/2019:20:49:03 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1"
# web_server的日志
10.10.10.1 - - [25/Jun/2019:20:49:03 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1, 10.10.10.16"
这个时候的remote_addr就是用户的真实IP,添加XFF头访问,我们来看3台server的日志情况。
# proxy_server_1的日志
10.10.10.1 - - [25/Jun/2019:20:59:10 -0400] "GET / HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1"
# proxy_server_2的日志
10.10.10.16 - - [25/Jun/2019:20:59:10 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1, 10.10.10.1"
# web_server的日志
10.10.10.1 - - [25/Jun/2019:20:59:10 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1, 10.10.10.1, 10.10.10.16"
可以看到用户自己配置的XFF头并没有被识别为真实的IP。
使用X-Forwarded-For+安全设置
在第一个代理处处理用户传递的XFF,达到忽略用户传递的XFF值的效果。
配置nginx
# proxy_server_1的nginx配置
location / {
proxy_pass http://10.10.10.17;
proxy_set_header X-Forwarded-For $remote_addr;
}
# proxy_server_2的nginx配置
location / {
proxy_pass http://10.10.10.18;
}
# web_server不做任何配置
使用浏览器正常访问,默认不改变日志格式的情况下,我们来看3台server的日志情况
# proxy_server_1的日志
10.10.10.1 - - [25/Jun/2019:21:17:42 -0400] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "-"
# proxy_server_2的日志
10.10.10.16 - - [25/Jun/2019:21:17:42 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1"
# web_server的日志
10.10.10.17 - - [25/Jun/2019:21:17:42 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1"
这个时候http_x_forwarded_for就是代表用户真实IP,添加XFF头访问,我们来看3台server的日志情况。
# proxy_server_1的日志
10.10.10.1 - - [25/Jun/2019:21:19:51 -0400] "GET / HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1"
# proxy_server_2的日志
10.10.10.16 - - [25/Jun/2019:21:19:51 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1"
# web_server的日志
10.10.10.17 - - [25/Jun/2019:21:19:51 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "10.10.10.1"
使用X-Real-IP
配置Nginx
# proxy_server_1的nginx配置
location / {
proxy_pass http://10.10.10.17;
proxy_set_header X-Real-IP $remote_addr;
}
# proxy_server_2的nginx配置
location / {
proxy_pass http://10.10.10.18;
}
# 两台proxy_server与web_server的日志第一个字段由$http_x_real_ip 替换 $remote_addr
log_format main '$http_x_real_ip - $remote_user
使用浏览器正常访问,我们来看3台server的日志情况
# proxy_server_1的日志
- - - [25/Jun/2019:21:33:47 -0400] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "-"
# proxy_server_2的日志
10.10.10.1 - - [25/Jun/2019:21:41:59 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "-"
# web_server的日志
10.10.10.1 - - [25/Jun/2019:21:33:47 -0400] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "-"
这个时候web_server的http_x_real_ip就是代表用户真实IP,添加XFF头访问,我们来看3台server的日志情况。
# proxy_server_1的日志
- - - [25/Jun/2019:21:34:24 -0400] "GET / HTTP/1.1" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1"
# proxy_server_2的日志
10.10.10.1 - - [25/Jun/2019:21:42:26 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1"
# web_server的日志
10.10.10.1 - - [25/Jun/2019:21:34:24 -0400] "GET / HTTP/1.0" 200 15 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36" "192.168.1.1"
与未配置XFF一致。