您当前的位置:首页 > 计算机 > 服务器 > Nginx

HTTP协议中的X-Real-IP, X-Forwarded-For和remote_addr头

时间:03-21来源:作者:点击数:

一、概述

X-Forwarded-For,X-Real-IP,remote_addr是http协议中用来表示客户端地址的请求头。

X-Forwarded-ForX-Real-IP只有请求存在代理时才有值,而remote_addr一直存在。

  • X-Forwarded-For:记录代理服务器的地址,每经过一个代理,该字段会加上一个记录。格式形如:1.1.1.1, 2.2.2.2
  • X-Real-IP:也是用来记录服务器的地址,但是和上面的不同,它不把记录添加到结尾,而是直接替换
  • remote_addr:上一个客户端连接的地址,不存在代理就表示客户端的地址,存在代理就表示最后一个代理服务器的地址

以下使用三个nginx服务器来测试以上三个请求头在不同条件组合下的值

本机地址:192.168.234.1

server1:https://192.168.234.13

server2:https://192.168.234.128

server3:https://test.cdsy.xyz

server1的代理配置

server {
    listen 80;
    server_name _;
    location / { 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass https://192.168.234.131;
    }   
}

server2的代理配置

server {
    listen 80;
    server_name _;
    location / { 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass https://test.cdsy.xyz;
    }   
}

server3为web服务端

server{
    listen 80;
    server_name test.cdsy.xyz;
    location / {
        root /data/html;
        index index.html;
    }
    access_log /data/wwwlogs/test.cdsy.xyz/access.log test;
}

日志格式test分别打印出三个请求头的内容:

log_format test "$http_x_forwarded_for | $http_x_real_ip | $remote_addr";

在不使用代理直接访问https://test.cdsy.xyz的情况下日志信息为:

- | - | 223.73.59.254

因为不存在代理,所以前面两个值是不存在的。而server3是公网地址,记录的remote_addr是本机公网地址223.73.59.254

二、请求说明

X-Forwarded-For就像是vector中的push_back,每经过一个代理服务器就把该请求的来源地址加在记录的后面(由于是记录来源地址,所以该字段不会保存最后一个代理服务器的地址)。

在本机访问server1,请求会被转发到server3,此时server3的日志为:

192.168.234.1, 192.168.234.128 | 192.168.234.128 | 223.73.59.254

X-Forwarded-For192.168.234.1, 192.168.234.128,说明经过了两次转发,但并没有记录server2的地址。

X-Real-IP会替换代理服务器的地址,请求头会在经过server2时被设置位server1的地址。

三、不记录转发请求

如果把server2proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;注释掉,即server2在转发时不添加该请求头,X-Forwarded-For就不会加上server1的地址:

192.168.234.1 | 192.168.234.128 | 223.73.59.254

如果再把server2proxy_set_header X-Real-IP $remote_addr;也注释掉,请求在server2时也不会替换X-Real-IP的值。

192.168.234.1 | 192.168.234.1 | 223.73.59.254

但是不管怎样,remote_addr是永远不会变的,它永远都是上一个请求客户端的地址,也就是server2的地址。

四、伪造请求头

请求头是可以伪造的,如果客户端伪造了请求头地址,X-Forwarded-ForX-Real-IP将会收到影响。

# server2上请求服务,并手动构造请求头
> curl 127.0.0.1 -H "X-Forwarded-For: 1.1.1.1" -H "X-Real-IP: 2.2.2.2"

收到的日志信息:

1.1.1.1 | 2.2.2.2 | 223.73.59.254

tips:对于X-Real-IP来说,如果存在一级以上的代理,它也不会收到影响,因为每经过一次代理,它就会被覆盖

remote_addr这个地址不管怎样伪造都是无用的:

# 在server2上直接请求server3
> curl https://test.cdsy.xyz -H "remote_addr:1.1.1.1"
# 得到的日志信息
- | - | 223.73.59.254

因为remote_addr字段不是通过请求头来决定的,而是服务端在建立tcp连接时获取的的客户端地址。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门