首页 > 系统相关 >Nginx多级反向代理下的IP透传

Nginx多级反向代理下的IP透传

时间:2023-01-09 15:22:21浏览次数:66  
标签:10.0 set http IP 透传 Nginx proxy server

透传IP

为何要做透传IP

在使用了CDN做加速站点静态资源加速后,当用户请求的静态资源没能命中,此时CDN会到源站请求内容,那么此时访问源站的IPCDN节点的IP,不仅如此,可能经我们的WAF防火墙和前端的负载均衡(SLB)后更不容易获取到真实的用户IP信息,我们如果要统计用户的访问IP和地区就变得比较麻烦,因为可能不是真实的IP,必须使用一个什么机制将用户IP传递到最终后端的应用服务器才行。

实验环境

访问流程

liucheng-img

主机IP配置备注
Chrome 10.0.0.1 Windows浏览器
LB-01 10.0.0.5 一级代理
LB-02 10.0.0.6 二级代理
LB-03 10.0.0.7 三级代理
WEB 10.0.0.8 WEB主机

常见的几种方式

X-Real-IP

描述

在每个HTTP请求头中加入X-Real-IP信息,若只存在1级的代理服务器,则该参数的确就是客户端的真实IP,但若是存在多级代理时,此信息为上级代理的IP信息,并不能获取到真实的用户IP,故此法目前已弃用。

nginx配置
#LB-01一级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.6;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
#LB-02二级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.7;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
#LB-03三级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.8;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
#WEB主机配置
server {
    listen 80;
    server_name ip.test.com;
    
    root /wwwroot;
    index index.php;
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
    }
}
WEB主机测试脚本
#文件名:index.php
#放到测试目录/wwwroot内
<?php
    $IP_ADDRESS = getenv("HTTP_X_REAL_IP");
	echo "SOURCE IP ADDRESS: $IP_ADDRESS";
?>

注:配置完成后保存所有配置文件,然后启动所有的nginx服务。如果在windows下测试一定要在C:\Windows\System32\drivers\etc\hosts文件内加入本地解析的记录,如下:

10.0.0.5	ip.test.com
Wireshark抓包信息

Wireshark-pack

HTTP报头信息
GET / HTTP/1.1
Host: ip.test.com
X-Real-IP: 10.0.0.6
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=16afc8d323f94-0360d7ebcc9bae-3d644509-18e414-16afc8d324063f
chrome打开测试

X-Real-IP

结论:Wireshark追踪流和Chrome的测试可见,X-Real-IP并不能获取到真实的客户端IP地址,如果时单级代理情况下,可以获取到正确的客户端IP,若存在多级代理就歇菜了。


X-Forwarded-For

描述

在每个HTTP请求头中加入X-Forwarded-For信息,若只存在1级的代理服务器,则该参数为客户端的真实IP,若是存在多级代理时,每经过一级代理服务器,则追加上级代理服务的IP,可以获取到真实的用户IP,但若是遇到伪造的X-Forwarded-For信息或第一级代理未启用X-Forwarded-For都不能获取到真实用户IP,此法是目前比较常用的方法,但更推荐使用nginx_http_realip_module模块添加可信代理的方法。

nginx配置
#LB-01一级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.6;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #可以尝试注释此处的,看看最终能否获取到真实客户端IP
    }
}
#LB-02二级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.7;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
#LB-03三级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.8;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
#WEB主机配置
server {
    listen 80;
    server_name ip.test.com;
    
    root /wwwroot;
    index index.php;
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
    }
}
WEB主机测试脚本
#文件名:index.php
#放到测试目录/wwwroot内
<?php
    $IP_ADDRESS = getenv("HTTP_X_FORWARD_FOR");
	echo "SOURCE IP ADDRESS: $IP_ADDRESS";
?>

注:记得重载nginx配置。

Wireshark抓包信息

Wireshark-pack-x-forward-for.png

HTTP报头信息
GET / HTTP/1.1
Host: ip.test.com
X-Forwarded-For: 10.0.0.1, 10.0.0.5, 10.0.0.6
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=16afc8d323f94-0360d7ebcc9bae-3d644509-18e414-16afc8d324063f
chrome打开测试

x-forward-for-php.png
结论:Wireshark追踪流和Chrome的测试可见,X-Forwarded-For可以获取到真实的客户端IP地址,即便是在多级代理下,也可以获取到正确的客户端IP,但如果某台代理未设置X-Forwarded-For,后端应用服务器可能并不能获取到正确的客户端IP


nginx_http_realip_module

描述

通过预定义可信任的代理主机的IP的方式(可信代理主机默认都会加入X-Forwarded-For信息),根据些X-Forwarded-For的信息,从右到左,滤除掉这些可信代理的IP信息,最终获取到的就是真实客户端IP信息,此信息替换$remote_addr这个变量,使最终客户端IPWEB后端应用服务器的access.log第一列显示,方便取值分析。

nginx官方描述

nginx配置
#LB-01一级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.6;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #此为可信任的代理服务器,故需要加入这条配置
    }
}
#LB-02二级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.7;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #此为可信任的代理服务器,故需要加入这条配置
    }
}
#LB-03三级代理配置
server {
    listen 80;
    server_name ip.test.com;
    
    location / {
        proxy_pass http://10.0.0.8;
        proxy_http_version 1.1;
        Proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #此为可信任的代理服务器,故需要加入这条配置
    }
}
#WEB主机配置,使用此模块是在后端WEB应用服务器添加参数
server {
    listen 80;
    server_name ip.test.com;
    #定义可信任的代理服务器地址
	set_real_ip_from  10.0.0.5;
	set_real_ip_from  10.0.0.6;
	set_real_ip_from  10.0.0.7;
    #指定从哪个HTTP报头里检索IP信息
	real_ip_header    X-Forwarded-For;
    #递归排除每个代理服务器的IP
	real_ip_recursive on;
    
    root /wwwroot;
    index index.php;
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
    }
}
WEB主机测试脚本
#文件名:index.php
#放到测试目录/wwwroot内
<?php
    $IP_ADDRESS = getenv("HTTP_X_FORWARD_FOR");
	echo "SOURCE IP ADDRESS: $IP_ADDRESS";
?>

注:记得重载nginx配置。

Wireshark抓包信息

Wireshark-pack-x-forward-for-nginx-module.png

HTTP报头信息
GET / HTTP/1.1
Host: ip.test.com
X-Forwarded-For: 10.0.0.1, 10.0.0.5, 10.0.0.6
Connection: close
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: UM_distinctid=16afc8d323f94-0360d7ebcc9bae-3d644509-18e414-16afc8d324063f
chrome打开测试

nginx-http-realip-module

WEB应用服务器的访问LOG

nginx-accesslog

结论:为了解决X-Forwarded-For可能存在伪装IP的问题,我们在后端使用了nginx_http_realip_module模块的set_real_ip_from关键字来添加可信IP并从X-Forwarded-For头中筛选出去,最终成功获取到了客户端IP,并且也对格式日志做了一定的替换,使客户端IP显示于access.log的第一列,方便最终的取值分析,这里需要注意的是,一定要添加正确且绝对可信的代理服务器IP,否则最终结果还是存在问题。

标签:10.0,set,http,IP,透传,Nginx,proxy,server
From: https://www.cnblogs.com/gaoyanbing/p/17037166.html

相关文章

  • DML-(Data Manipulation Language)
    DML(DataManipulationLanguage):数据操作语言,用来对数据库中表的数据记录进行增、删、改操作。添加数据(insert)修改数据(update)删除数据(delete)添加数据给指定字段添加......
  • nginx 配置443 域名
    1申请域名(公有云)2下载证书pemkey并上传服务器指定目录3公有云上做A记录解析(解析到代理的nginx)4nginx配置443模块配置内容:server{listen80;......
  • vue-awesome-swiper与vue2的版本对应关系
    1.安装  注意:这里一定要对应swiper 和vue-awesome-swiper版本,如果不对应,vue就会各种报错  2.引入2.1全局引入main.js  2.2局部引入    3......
  • P7114 [NOIP2020] 字符串匹配 解题报告
    ~~NOIP的蓝题果然还是好难啊啊啊啊~~前言:作为一道NOIP的真题,这道题放在T2难度并不是特别大,不过考点还是比较偏的,扩展KMP和树状数组的组合,并且还带有一定的思维难度,......
  • echarts tooltip pie {b}展示不全
    echartstooltippie{b}展示不全tooltip:{show:true,trigger:'item',formatter:'{b}:{c}{d}%'},原因:后端......
  • javascript将文本转语音功能
    通过jiavascript将文本内容转化为语音播放,代码如下:<body><buttononclick="start()">点击</button><script>vartext='语音输入开始'var......
  • 【跨屏建站网】kpvip模板2023.1.6发布更新
    跨屏建站网kpvip模板2023.1.6发布更新,修复了已知bug,优化了代码,调整了新闻版块,之前的新闻缩略图有图的时候会显示图片,没有图片则显示一张占位图,而调整以后,我们去掉了缩略图......
  • 基于 Arcaea v4.1.9 ipa 制作的自制谱 | 壳子
    "一个很好的逆向入门的练习"首先需要准备IDAPro7.7以及Sideloadlyv0.28两个软件,前者能帮助你魔改ipa内容,后者能将ipa导入ios设备.Hash校验这是逆向......
  • rails snippets
    snippetartassert_redirected_to${1:action}:'${2:index}'snippetartnpassert_redirected_to${1:parent}_${2:child}path(${3:@$1},${0:@$2})snippetartnppass......
  • ruby snippets
    snippetenc#encoding:utf-8snippetfrozen#frozen_string_literal:truesnippet#!#!/usr/bin/envrubyNewBlocksnippet=b=beginrdoc${0}=endsnippetpr......