Nginx对x_forwarded_for做IP白名单限制
使用http_x_forwarded_for变量做访问限制
==只能针对IP做限制,对网段无效.==
模拟前端nginx
server {
listen 888;
server_name 11.0.22.62;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
location / {
proxy_pass http://11.0.22.62:889;
}
}
模拟后端nginx
set $ip '172.16.69.67'; #定义一个变量,值为允许访问的ip,
if ($http_x_forwarded_for != $ip){ #如果$http_x_forwarded_for的ip不等于$ip,则返回403
return 403;
}
server {
listen 889;
server_name 11.0.22.62;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
#如果$http_x_forwarded_for为内部ip则,定义$inner的值为1
if ($http_x_forwarded_for = 172.16.69.67){set $inner 1;}
if ($http_x_forwarded_for = 172.16.69.156){set $inner 1;}
#如果$inner的值不为1,则返回403
if ($inner != 1){return 403;}
location / {
root html;
}
}
测试日志
使用Nginx自带模块realip获取用户IP地址
安装realip模块
realip是Nginx内置模块,需要在编译Nginx时加上–with-http_realip_module参数来启用它。
常用编译参数
$ ./configure --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module \
--with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module \
--with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module \
--with-http_random_index_module --with-http_secure_link_module \
--with-http_stub_status_module --with-http_auth_request_module \
--with-threads --with-stream --with-stream_ssl_module --with-mail \
--with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g'
$ make
$ make install
配置实例
IP及端口 | 角色 |
---|---|
11.0.22.62:888 | 前端代理 |
11.0.22.62:889 | 做限制的实例nginx |
11.0.22.24 | 客户端 |
172.16.69.0/24 | 客户端 |
前端代理
将请求转发给后端的11.0.22.62:889.
server {
listen 888;
server_name 11.0.22.62;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
location / {
proxy_pass http://11.0.22.62:889;
}
}
要做限制的nginx
如果$remote_addr
是11.0.22.62, 那么realip
模块会用real_ip_header
从header
头中拿出X-Forwarded-For
的IP,替换掉remote_addr
的IP,然后就可以用allow,deny进行限制.
server {
listen 889;
server_name 11.0.22.62;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
#下面的配置可以放到http层,则不用对每个server就行配置,放在server层的好处就是灵活一下.
set_real_ip_from 11.0.22.62; #上一级代理的IP地址或者IP段,可以写多行。
real_ip_header X-Forwarded-For; #从哪个header头检索出要的IP地址。
real_ip_recursive on; #递归的去除所配置中的可信IP。
#如果有多个规则,可以写一个acl规则文件,server里面include acl/acl.conf;
location / {
allow 172.16.69.0/24;
allow 172.16.81.0/24;
deny all;
root html;
}
}
日志
172.16.69.67 - - [04/Nov/2019:10:41:15 +0800] "GET / HTTP/1.0" "" "-" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.17 Safari/537.36" "172.16.69.67" "http://11.0.22.62" "-" "-" "0.000" "-"
172.16.69.67 - - [04/Nov/2019:10:41:15 +0800] "GET / HTTP/1.1" "" "-" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.17 Safari/537.36" "-" "http://11.0.22.62:888" "11.0.22.62:889" "0.001" "0.001" "11.0.22.62:889"
11.0.22.64 - - [04/Nov/2019:10:41:27 +0800] "GET / HTTP/1.0" "" "-" 403 169 "-" "curl/7.29.0" "11.0.22.64" "http://11.0.22.62" "-" "-" "0.000" "-"
11.0.22.64 - - [04/Nov/2019:10:41:27 +0800] "GET / HTTP/1.1" "" "-" 403 169 "-" "curl/7.29.0" "-" "http://11.0.22.62:888" "11.0.22.62:889" "0.001" "0.001" "11.0.22.62:889"