Nginx服务(4)——Nginx 反向代理获取真实的客户端ip

一、前言

1、Nginx反向代理获取客户端的真实IP原理

我们访问互联网的服务时,大多数时,客户端并不是直接访问到服务端的,而是客户端首先请求到反向代理,反向代理再转发到服务端实现服务访问。

客户端访问服务端的数据流走向
Client(172.25.0.1) --> ADSL( 192.168.0.1) --> cdn(10.0.0.1) --> SLB(反向代理)11.0.0.1 --> server(nginx)12.0.0.1

可以看出,nginx的反向代理实现跨域的同时也彻底改变了服务器的请求来源,隔离了用户和服务器的连接,服务端获取不到真实的客户端ip,只能获取到反向代理服务的ip,那么nginx怎样才能获取到真实的ip呢?

利用Nginx中的realip模块获取用户的真实ip 。将各层代理的IP排除在外,就取到了真实的用户IP,这个可以使用nginx的一个模块realip_module 来实现从XFF中抛弃指定的代理层 IP,得到一个符合规则的就是用户IP 。nginx的 realip_module 模块需要在编译nginx的时候加上参数–with-http_realip_module。

2、nginx中的几个变量?

(1)remote_addr
代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的
当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)
就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站
这样web服务器就会把remote_addr设为这台代理机器的IP,除非代理将你的IP附在请求header中一起转交给web服务器

(2)X-Forwarded-For(简称XFF)
X-Forwarded-For 是一个 HTTP 扩展头部,HTTP协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入
用来表示 HTTP 请求端真实 IP,如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用
并被写入 RFC 7239(Forwarded HTTP Extension)标准之中
XFF的格式为X-Forwarded-For: client, proxy1, proxy2

XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP
(注意:如果未经严格处理,可以被伪造)
如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0
那么按照 XFF 标准,服务端最终会收到以下信息
X-Forwarded-For: IP0, IP1, IP2
Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求
列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得

(3)X-Real-IP
这又是一个自定义头部字段,通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP
这个设备可能是其他代理,也可能是真正的请求端,这个要看经过代理的层级次数或是是否始终将真实IP一路传下来
(注意:如果未经严格处理,可以被伪造)

二、实现Nginx 反向代理获取源地址

实验环境

主机名 ip 功能
server1 172.25.1.1 nginx服务器
server2 172.25.1.2 nginx代理服务器
真机 172.25.1.250 客户端,用来测试

实验

1、获取客户端ip

在server1(服务端):

步骤一:进入解压目录,重新编译,添加realip_module模块,并进行make编译

cd nginx-1.17.8
./configure --prefix=/usr/local/nginx --with-file-aio --with-http_realip_module   # 添加了一个获取realip的模块
make

步骤二:覆盖ngins文件

cd objs/
cp -f nginx /usr/local/nginx/sbin/nginx 

步骤三:添加虚拟主机

写到配置文件最后边

vim /usr/local/nginx/conf/nginx.conf

server {   \
        listen 80;
        server_name server1.example.com; # 添加域名
 
        location / {
                return 200 "client real ip: $remote_addr\n";
        }
}

在这里插入图片描述

$remote_addr:代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,并不是真实客户端IP;
当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP,,除非代理将你的IP附在请求header中一起转交给web服务器

重启服务:

nginx -s reload

步骤四:测试虚拟主机是否添加成功

 curl -I server1.example.com

在这里插入图片描述

200 ok表示添加成功
步骤五:测试让其回应real ip

curl server1.example.com

在这里插入图片描述

步骤六:从X-Forwarded-For中获取到真实客户端IP

vim /usr/local/nginx/conf/nginx.conf

server {   \
        listen 80;
        server_name server1.example.com; # 添加域名
        set_real_ip_from 172.25.1.1; # 真实服务器上一级代理的IP地址或者IP段,可以写多行
        real_ip_header X-Forwarded-For; # 告知Nginx真实客户端IP从哪个请求头获取
        real_ip_recursive on;  # 是否递归解析,off表示默认从最后一个地址开始解析,on表示从第一个地址解析

        location / {
                return 200 "client real ip: $remote_addr\n";
        }
}

重启服务

nginx -s reload

步骤七:测试real_ip_recursive作用
当real_ip_recursive 为on时,服务端从X-Forwarded-For中获取第一个地址

在这里插入图片描述

curl -H "X-Forwarded-For:1.1.1.1,172.25.1.1" server1.westos.org

在这里插入图片描述

当real_ip_recursive 为off时,服务端从X-Forwarded-For中获取到的最后一个地址

在这里插入图片描述

curl -H "X-Forwarded-For:1.1.1.1,172.25.1.1" server1.example.com

在这里插入图片描述

测试完,将参数改为on

步骤八:编辑默认发布页面

vim /usr/local/nginx/html/index.html 
<h1>server1 page</h1>
nginx -s reload

在这里插入图片描述

步骤九:修改配置文件,注释掉测试内容,并添加默认发布页面内容。

vim /usr/local/nginx/conf/nginx.conf
        #location / {
        #        return 200 "client real ip: $remote_addr\n";
        #}

在这里插入图片描述

注意:将文件http大括号中的server大括号中的内容全部注释掉,写成图中所示内容

步骤十:语法检测并重启

nginx -t
nginx -s reload

步骤十一:将server1上编译好的nginx的目录发送给server2

scp -r /usr/local/nginx/ root@server2:/usr/local/

在这里插入图片描述

在server2(代理服务器)上:

步骤一:修改配置文件中对server1服务器的相关配置

        upstream westos {
                server 172.25.1.1:80;
        }

server {
        listen  80;
        server_name  www.westos.org;
        set_real_ip_from 172.25.1.2;

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

        }
}

注意:将文件http大括号中的server大括号中的所有内容注释掉,写成图中所示内容

在这里插入图片描述

步骤二:创建nginx用户

useradd nginx

步骤三:清空nginx默认发布文件

cd /usr/local/nginx/html/
> index.html 

步骤四:检查语法,并启动nginx服务

/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx 

在这里插入图片描述

在真机上(客户端):

步骤一:添加serever2解析

vim /etc/hosts
172.25.1.2  www.westos.org

在这里插入图片描述

步骤二:curl访问server域名

curl www.westos.org

在这里插入图片描述

可以查看到server1默认发布页面内容,说明nginx反向代理配置成功

在server1(服务端)上:
cd /usr/local/nginx/logs
cat access.log

在这里插入图片描述

可以看出nginx服务器可以直接得到客户端的ip

2、获取代理ip

步骤一:修改配置文件

在刚才配置的基础上,注释掉nginx服务器的这两行时,获取到的ip就是代理服务器的ip

#real_ip_header X-Forwarded-For;
#real_ip_recursive on; 

在这里插入图片描述

步骤二:检测语法规范,并开启服务

nginx -t
nginx -s reload

在这里插入图片描述

在真机上(客户端):

curl访问server域名

curl www.westos.org

在这里插入图片描述

在server1(服务端)上:
cd /usr/local/nginx/logs
cat access.log

在这里插入图片描述

此时nginx服务器得到的是代理的ip

发布了99 篇原创文章 · 获赞 3 · 访问量 1610

猜你喜欢

转载自blog.csdn.net/weixin_45784367/article/details/104590588