HTTP请求头中的X-Forwarded-For介绍

摘要:
XFF的请求格式非常简单,如下所示:X-Forwarded-For:client,proxy1,proxy2。如上所述,XFF的内容由[IP+英文逗号+空格]组成。初始客户端是客户端的IP,proxy1和proxy2分别是主代理和辅助代理的IP。类似地,proxy3的日志中只有IP0和IP1,proxy2的日志中仅有IP0,proxy1的日志中没有IP。

概述

我们在做nginx方向代理的时候,为了记录整个代理过程,我们往往会在配置文件中加上如下配置:

location ^~ /app/download/ {
    ...
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    ...
    proxy_pass http://10.1.10.203:8080;
}

proxy_set_header就是记录整个代理过程的配置。其中X-Forwarded-For(XFF)位于HTTP请求头,已经成为事实上的标准。
XFF的请求格式很简单,如下:

X-Forwarded-For: client, proxy1, proxy2

由上面可以看到XFF的的内容由[IP+英文逗号+空格]组成(如果有多个代理的话),最开始的client是客户端的IP,proxy1和proxy2分别是一级代理和二级代理的IP。
假设代理如下:
image.png
如上,proxy1、proxy2和proxy3都用NG做反代,并且在它们的配置上都加上如下配置:

proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

那么在Real Server(NG的WEB容器)上打印的日志(日志里带$http_x_forwarded_for)就会带有IP0,IP1,IP2的HTTP头,可以看到没有IP3,因为IP3是直连服务器,它会给XFF追加IP2的地址,表示它是帮proxy2做转发的,Real Server要获取IP3的地址,需通过remote Address字段获得。
同理,在proxy3上日志里只会有IP0和IP1,proxy2上日志里只有IP0,proxy1上没有IP。

测试

测试拓扑如下:
image.png
在proxy1上的配置如下:

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://192.168.169.130/;
        }
    }

在proxy2上的配置如下:

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://192.168.169.131/;
        }
    }

在proxy3的配置如下:

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://xxx.xxx.xxx.xxx:8888/;
        }
    }

proxy1,proxy2,proxy3上的日志格式如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

Real Server日志格式如下:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent $upstream_cache_status "$http_referer" '
                    '"$http_user_agent" "==$http_x_forwarded_for" "--$http_x_real_ipi"';

我在本机浏览器输入:http://192.168.169.128/,然后分别在proxy1-3还有Real Server上抓取nginx日志,proxy1-3日志最后一个字段是$http_x_forwarded_for,Real Server倒数二个字段是$http_x_forwarded_for如下:
proxy1日志:

192.168.169.1 - - [04/Jun/2019:10:57:06 +0800] "GET / HTTP/1.1" 200 20 "-" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/74.0.3729.169 Safari/537.36" "-"

proxy2日志:

192.168.169.128 - - [04/Jun/2019:10:57:06 +0800] "GET / HTTP/1.0" 200 10 "-" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/74.0.3729.169 Safari/537.36" "192.168.169.1"

proxy3日志:

192.168.169.130 - - [29/Mar/2019:23:29:36 +0800] "GET / HTTP/1.0" 200 10 "-" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/74.0.3729.169 Safari/537.36" "192.168.169.1, 192.168.169.128"

Real Server日志:

183.66.224.50 - - [04/Jun/2019:10:57:03 +0800] "GET / HTTP/1.0" 200 10 - "-" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/74.0.3729.169 Safari/537.36" "==192.168.169.1, 192.168.169.128, 192.168.169.130" "---"

从上面的日志可以知道:
(1)、设置X-Forwarded-For是一个可叠加的过程;
(2)、后端服务器XFF获取不到直连服务器IP。比如Real-Server的日志中XFF字段没有proxy3的IP地址,依次类推;
(3)、代理中要配置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

免责声明:文章转载自《HTTP请求头中的X-Forwarded-For介绍》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇php使用curl方法请求java接口2-5 Sass 的 @ 规则下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

HTTP协议中GET请求方法中的请求头内容 : If-Modified-Since

问题背景 HTTP协议中GET请求方法中的请求头内容 : If-Modified-Since 具体描述 HTTP请求头的IMS(If-Modified-Since):浏览器缓存记录的该文件的最后服务器修改时间。 浏览器发送HTTP请求时,把If-Modified-Since一起发到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行比较。 如...

Java学习|HTTP请求头

https://www.cnblogs.com/honghong87/articles/6941436.html 常见http请求报文头属性      Accept:告诉服务端,客户端接受什么类型的响应,例如:           Accept:text/plan      表示纯文本           Accept的值可以是一个或多个midia typ...

常用的HTTP请求头与响应头

HTTP消息头是指,在超文本传输协议( Hypertext Transfer Protocol ,HTTP)的请求和响应消息中,协议头部分的那些组件。HTTP消息头用来准确描述正在获取的资源、服务器或者客户端的行为,定义了HTTP事务中的具体操作参数。 关于HTTP消息头 常用的HTTP请求头 常用的HTTP响应头 1. 关于HTTP消息头 HTTP...

HTTP请求行、请求头、请求体详解

    HTTP请求行、请求头、请求体详解 文本引用:https://blog.csdn.net/u010256388/article/details/68491509/ HTTP请求报文解剖  HTTP请求报文由3部分组成(请求行+请求头+请求体): 下面是一个实例  ①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、...

http扩展请求头中的x-Forwarded-For

X-Forwarded-For格式:   X-Forwarded-For: client-ip, proxy1-ip, proxy2-ip 客户端请求服务器的过程中没经过一个代理层(代理中使用了xff)那么 代理会把 请求过来的上一级的ip  追加到xff的最后面。 正常情况下xff请求的示意图: 上图是客户端请求时不带xff请求的头的情况! 客户端可以...

HTTP 请求头中的 X-Forwarded-For

转自:https://imququ.com/post/x-forwarded-for-header-in-http.html HTTP 请求头中的 X-Forwarded-For 我一直认为,对于从事 Web 前端开发的同学来说,HTTP 协议以及其他常见的网络知识属于必备项。一方面,前端很多工作如 Web 性能优化,大部分规则都跟 HTTP、HTTPS、...