X-Forward-For
在使用nginx做反向代理时,我们为了记录整个的代理过程,我们往往会在配置文件中做如下配置:
http {
.........
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server{
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
X-Forwarded-For格式为:192.168.11.131, 192.168.247.132, 192.168.247.133 引用X-Forwarded-For时使用$http_x_forwarded_for
测试经过多层代理后,在应用层上获取的x_forwarded_for值为多少
虚拟测试环境
win10主机
centos7系统,ip为192.168.11.131为第一层代理
centos7系统,ip为192.168.11.132为第二层代理
centos7系统,ip为192.168.11.133为第三层代理
win10 在/etc/hosts文件中添加192.168.11.130 http://www.abc.com
ip:192.168.11.131,安装nginx,把所有请求转发到192.168.11.132
ip:192.168.11.132,安装nginx,把所有请求转发到192.168.11.133
ip:192.168.11.133,安装nginx,把所有请求转发到云服务器
在云服务器上的日志中打印http header中的X-Forwarded-For信息
nginx配置
192.168.11.131
http {
.........
log_format main '"$http_x_forwarded_for"';
server{
location / {
proxy_pass http://192.168.11.132;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
192.168.11.132
http {
.........
log_format main '"$http_x_forwarded_for"';
server{
location / {
proxy_pass http://192.168.11.133;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
192.168.11.133
http {
.........
log_format main "$http_x_forwarded_for"';
server{
location / {
proxy_pass http://47.102.216.11;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
#云服务器方便起见在日志中设置打印$http_x_forwarded_for,进行观察
http {
.........
log_format main '$http_x_forwarded_for';
}
仅在proxy1上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy02,proxy03配置文件中注释掉,云服务器上打印
192.168.11.130
仅在proxy2上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy01,proxy03配置文件中注释掉,云服务器上打印
192.168.11.131
仅在proxy3上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy01,proxy02配置文件中注释掉,云服务器上打印
196.168.11.132
在proxy1 proxy2上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy03配置文件中注释掉,云服务器上打印
192.168.11.130,192.168.11.131
在proxy1 proxy3上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy02配置文件中注释掉,云服务器上打印
192.168.11.130,192.168.11.132
在proxy2 proxy3上添加proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,在proxy01配置文件中注释掉,云服务器上打印
192.168.11.131,192.168.11.132
在proxy1 proxy2 proxy3上面的配置访问域名,云服务器上打印的日志为
192.168.11.130, 192.168.11.131, 192.168.11.132
总结:
1、通过以上几种情况我们可以了解到设置X-Forwarded-For是一个可叠加的过程,后面的代理会把前面代理的IP加入X-Forwarded-For
2、我们看到在三层代理情况下无论如何设置,云服务器不可能从$http_x_forwarded_for拿到与它直连的这台服务器的ip(proxy3 ip),此时我们可以使用$remote_addr(远程ip,表示直连的那台代理).一句话,当前服务器无法通过$http_x_forwarded_for获得上级代理或者客户端的ip,应该使用$remote_addr.
3、在代理过程中至少有一个代理设置了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;否则后面代理或者应用服务器无法获得相关信息.(除非没有经过代理)
4、想要获取客户端IP(必须要在proxy1代理设置了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;我们取第一IP就好了)
5、如果nginx代理到apache,apache的日志格式中X-Forwarded-For还是没有值,说明没有经过任何代理,外网直接访问服务器资源并且没有设置x-fordwarded-for的值。如果只有一个值,且是相同的,该值必为云服务器前一层代理ip.所以在apache中x-fordwarded-for的值一般在2个以上。
X-Real-IP
nginx配置
192.168.11.131
http {
.........
log_format main '"$http_x_real_ip"';
server{
location / {
proxy_pass http://192.168.11.132;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
192.168.11.132
http {
.........
log_format main '"$http_x_real_ip"';
server{
location / {
proxy_pass http://192.168.11.133;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
192.168.11.133
http {
.........
log_format main "$http_x_real_ip"';
server{
location / {
proxy_pass http://47.102.216.11;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
#云服务器方便起见在日志中设置打印$http_x_forwarded_for,进行观察
http {
.........
log_format main '$http_x_real_ip';
}
只在proxy1上设置X-Real-IP
192.168.11.130
只在proxy2上设置X-Real-IP
192.168.11.131
只在proxy3上设置X-Real-IP
192.168.11.132
只在proxy1和proxy2上设置X-Real-IP
192.168.11.131
所有代理均设置设置X-Real-IP
192.168.11.132
总结:
1、X-Real-IP只是一个变量,后面的设置会覆盖前面的设置(跟X-Forwarded-For的追加特性区别明显),
2、我们一般只在第一个代理设置proxy_set_header X-Real-IP $remote_addr;就好了,然后再应用端直接引用$http_x_real_ip就行.
3、X-Real-IP的值总为1个
8.11.131
所有代理均设置设置X-Real-IP
192.168.11.132
总结:
1、X-Real-IP只是一个变量,后面的设置会覆盖前面的设置(跟X-Forwarded-For的追加特性区别明显),
2、我们一般只在第一个代理设置proxy_set_header X-Real-IP $remote_addr;就好了,然后再应用端直接引用$http_x_real_ip就行.
3、X-Real-IP的值总为1个