HTTP請求頭中的X-Forwarded-For介紹


概述

我們在做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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM