X-Forwarded-For
在使⽤nginx做反向代理时,我们为了记录整个的代理过程,我们往往会在配置⽂件中做如下配置:
location / { 省略...
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://1xx.xxx.xxx.xxx; }
红⾊部分就是为了记录代理过程做的配置,在http header中添加代理的信息,我们可以把X-Forwarded-For当成http扩展头,其格式⼀般为:X-Forwarded-For:192.168.247.1, 192.168.247.131, 192.168.247.132注意,引⽤X-Forwarded-For时要这样$http_x_forwarded_for
做⼀下测试
1.我们测试⼀下请求经过三层代理的情况,测试设备分配:
win10 ⼀台
运⾏在win10上的虚拟机centos6-0,ip:192.168.247.131,⼀级代理运⾏在win10上的虚拟机centos6-1, ip:192.168.247.132 ,⼆级代理运⾏在win10上的虚拟机centos6-2, ip:192.168.247.133 ,三级代理云服务器,应⽤服务器
2.测试环境配置:
win10 在/etc/hosts⽂件中添加192.168.247.131 http://test.proxy.com
centos6-0,ip:192.168.247.131,安装nginx,把所有请求转发到192.168.247.132centos6-1, ip:192.168.247.132,安装nginx,把所有请求转发到192.168.247.133centos6-2, ip:192.168.247.133,安装nginx,把所有请求转发到云服务器在云服务器上的⽇志中打印http header中的X-Forwarded-For信息防⽕墙可以关闭掉,防⽌win10请求⽆法进⼊代理链
3.nginx配置⽂件
#centos6-0,ip:192.168.247.131 ,nginx.conflocation / {
root html;
index index.html index.htm index.php;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://192.168.247.132; }
#centos6-1,ip:192.168.247.132 ,nginx.conf location / { root html;
index index.html index.htm index.php;
#proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://192.168.247.133; }
#centos6-2,ip:192.168.247.133 ,nginx.conf location / {
root html;
index index.html index.htm index.php; #proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://123.206.96.111; }
#云服务器⽅便起见在⽇志中设置打印$http_x_forwarded_for,进⾏观察 log_format main '$http_x_forwarded_for|$http_x_real_ip|$remote_addr - $remote_user [$time_local] \"$request\" '
'$status $body_bytes_sent \"$http_referer\" ' '\"$http_user_agent\" \"$http_x_forwarded_for\"';
4.基于上⾯的配置在win10浏览器输⼊:\"http://test.proxy.com\" 查看云服务器⽇志打印结果如下:
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.1|101.2.182.6 - - [22/May/2017:18:20:27 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F
192.168.247.1, 192.168.247.131, 192.168.247.132 为$http_x_forwarded_for内容,显然记录了代理过程,其中192.168.247.1是客户端ip192.168.247.1 为基于上述设置的真实IP(不⼀定准确)101.2.182.6 公⽹IP
继续。。。
我们要仔细测试⼀下在不同代理服务器设置X-FORWARDED-FOR在应⽤服务器拿到的$http_x_forwarded_for有何不同
1.只在proxy01设置X-FORWARDED-FOR, 在proxy02,proxy03配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.1|192.168.247.1|101.2.182.6 - - [22/May/2017:18:52:49 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT 10.0; WOW) App
2.只在proxy02设置X-FORWARDED-FOR, 在proxy01,proxy03配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.131|192.168.247.1|101.2.182.6 - - [22/May/2017:18:59:59 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT 10.0; WOW) A
3.只在proxy03设置X-FORWARDED-FOR, 在proxy01,proxy02配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.132|192.168.247.1|101.2.182.6 - - [22/May/2017:19:01:27 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT 10.0; WOW) A
4.只在proxy01,proxy03设置X-FORWARDED-FOR, 在proxy02配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.1, 192.168.247.132|192.168.247.1|101.2.182.6 - - [22/May/2017:19:05:49 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT 10
5.只在proxy02,proxy03设置X-FORWARDED-FOR, 在proxy01配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.131, 192.168.247.132|192.168.247.1|101.2.182.6 - - [22/May/2017:19:08:39 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT
6.只在proxy01,proxy02设置X-FORWARDED-FOR, 在proxy03配置⽂件中注释掉proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192.168.247.1, 192.168.247.131|192.168.247.1|101.2.182.6 - - [22/May/2017:19:10:40 +0800] \"GET /admin/login/?next=%2Fadmin%2F HTTP/1.0\" 200 623 \"http://test.proxy.com/admin/login/?next=%2Fadmin%2F\" \"Mozilla/5.0 (Windows NT 10
⼩结:
1.通过以上⼏种情况我们可以了解到设置X-Forwarded-For是⼀个可叠加的过程,后⾯的代理会把前⾯代理的IP加⼊X-Forwarded-For,类似于python的列表append的作⽤.2.我们看到在三层代理情况下⽆论如何设置,应⽤服务器不可能从$http_x_forwarded_for拿到与它直连的这台服务器的ip(proxy03 ip),此时我们可以使⽤$remote_addr(远程ip,表⽰直连的那台代理).⼀句话,当前服务器⽆法通过$http_x_forwarded_for获得上级代理或者客户端的ip,应该使⽤$remote_addr.
3.在代理过程中⾄少有⼀个代理设置了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;否则后⾯代理或者应⽤服务器⽆法获得相关信息.
4.注意,应⽤服务器可以通过$proxy_add_x_forwarded_for客户端IP(只要⾄少proxy01代理设置了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;我们取第⼀IP就好了),但是我们要考虑客户端伪造头部的情况,如下⽰例:
假设我们在所有代理都加上了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;然后我们在proxy01机器上本机curl代替win10模拟⼀个客户端请求,在proxy01上执⾏: curl localhost/admin -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: 2.2.2.2'
1.1.1.1, 127.0.0.1, 192.168.247.131, 192.168.247.132|127.0.0.1|101.2.182.6 - - [23/May/2017:11:02:09 +0800] \"GET /admin HTTP/1.0\" 301 263 \"-\" \"curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
可以看到,1.1.1.1放到了最前⾯,所以我们不能够想当然的去取第⼀个ip作为客户端的这是IP.这⾥127.0.0.1是真实IP.
5.虽然X-Forwarded-For可以伪造,但是对我们依然有⽤,⽐如我们就从proxy01代理往后截取就⾏了,这样就能做到直接忽视伪造得IP.
X-Real-IP
下⾯我们看⼀下有多级代理存在时如何获取客户端真实IP.
⾸先要明确在header⾥⾯的 X-Real-IP只是⼀个变量,后⾯的设置会覆盖前⾯的设置(跟X-Forwarded-For的追加特性区别明显),所以我们⼀般只在第⼀个代理设置proxy_set_header X-Real-IP $remote_addr;就好了,然后再应⽤端直接引⽤$http_x_real_ip就⾏.1.假如我们只在proxy01设置了 X-Real-IP
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.1|101.2.182.6 - - [23/May/2017:11:23:00 +0800] \"GET /test/ HTTP/1.0\" 200 9 \"http://test.proxy.com/test/\" \"Mozilla/5.0 (Windows NT 10.0; WOW) AppleWebKit/537.36 (KHTML,
2.假如我们只在proxy02设置了X-Real-IP
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.131|101.2.182.6 - - [23/May/2017:11:26:22 +0800] \"GET /test/ HTTP/1.0\" 200 9 \"http://test.proxy.com/test/\" \"Mozilla/5.0 (Windows NT 10.0; WOW) AppleWebKit/537.36 (KHTM
3.假如我们只在proxy03设置了X-Real-IP
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.132|101.2.182.6 - - [23/May/2017:11:27:21 +0800] \"GET /test/ HTTP/1.0\" 200 9 \"http://test.proxy.com/test/\" \"Mozilla/5.0 (Windows NT 10.0; WOW) AppleWebKit/537.36 (KHTM
4.所有代理都设置X-Real-IP
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.132|101.2.182.6 - - [23/May/2017:11:29:09 +0800] \"GET /test/ HTTP/1.0\" 200 9 \"http://test.proxy.com/test/\" \"Mozilla/5.0 (Windows NT 10.0; WOW) AppleWebKit/537.36 (KHTM
5.强迫症来了,再试⼀个只设置proxy01,proxy02的看看
192.168.247.1, 192.168.247.131, 192.168.247.132|192.168.247.131|101.2.182.6 - - [23/May/2017:11:30:36 +0800] \"GET /test/ HTTP/1.0\" 200 9 \"http://test.proxy.com/test/\" \"Mozilla/5.0 (Windows NT 10.0; WOW) AppleWebKit/537.36 (KHTM
假如有⼈假冒X-Real-IP呢?
6. 在proxy01上执⾏: curl localhost/admin -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: xx.xx.xx.xx'1.1.1.1, 127.0.0.1, 192.168.247.131, 192.168.247.132|192.168.247.131|101.2.182.6 - - [23/May/2017:11:36:02 +0800] \"GET /admin HTTP/1.0\" 301 263 \"-\" \"curl/7.15.5 (i386-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
并没有影响.
IT'S OVER.
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- jqkq.cn 版权所有 赣ICP备2024042794号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务