0

0

如何在两层服务器的第二层Nginx上获取用户IP

php中文网

php中文网

发布时间:2016-08-08 09:31:04

|

1505人浏览过

|

来源于php中文网

原创

如何在两层服务器的第二层nginx上获取用户ip

一.之前在做nginx的服务器配置的时候遇到了一个问题,在之前服务器有用到一个限制客户端最大并发连接的功能,而且这个功能的实现是依靠在服务器中做

$remote-addr

这样的配置来达到的。但在增加了前端一层(负载、CDN、防火墙、安全服务)服务器之后,拿到的客户端IP就都变成了前端服务器的IP,而并非真是的用户IP地址。

二.这样的问题下,我又重新看了几次nginx官网的介绍,也发现其中另外一个特别重要的变量

$proxy_add_x_forwarded_for

这个变量是客户端访问请求中的X-forwarded-for 字段的值,如果请求中不包含这个字段,则自动用这个变量会等价于remote-addr这个变量。这允许我们获取HTTP请求中通常情况下前端服务器保存的客户真实IP地址的字段,通常就是我们说的X_FORWARDED_FOR字段,然后通过这样的方法,我们就可以实现各种各样的功能了。

三.下面我来实际给大家做一个简单演示。诸多不足,欢迎指正。

首先我们先搭建好Nginx的环境,这里我们使用1.7 系列的最新版本 1.7.9为例,(关于版本的问题参见FAQ 1)

下载、WGET所需地址 http://nginx.org/download/nginx-1.7.9.tar.gz

1.      下载Nginx

[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz

2.      解压

[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz

3.      直接编译(需要考虑是否需要openssl等插件的支持)

[lugt@localhost mysql]$cd nginx-1.7.9

[lugt@localhost nginx-1.7.9]$ ./configure

[lugt@localhost nginx-1.7.9]$ make

[lugt@localhost nginx-1.7.9]$ su

[lugt@localhostnginx-1.7.9]$ make install

4.      然后接下来修改nginx.conf配置文件

[lugt@localhost nginx-1.7.9]$ su

[lugt@localhost nginx-1.7.9]$cd /usr/local/nginx

[lugt@localhostnginx]$ vi conf/nginx.conf

然后在nginx.conf 中找到这里,加入来设置负载均衡,模仿CDN

upstream dnsnginx1 {
        server[*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名
}
server {
        listen       80;
        server_name 
#access_log  logs/host.access.log  main
        location /{
           proxy_pass          http://dnsnginx1;
            proxy_set_header    Host             $host;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
            proxy_redirect      default;
}
}

在设置一个虚拟服务器在8080端口,

limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m;  # 并发设置 空间10M
server {
        listen       8080;
        server_name  [*.*.*.*/yourhostname]:8080 weight=10000; #填IP、域名
        limit_conn addr 1; #限制客户端最大并发连接数为 1
            location / {
            root   html;
            index  index.html index.htm;
        }
}

保存。接着测试配置文件语法

    [lugt@localhostnginx]$  ./sbin/nginx –t

启动服务器

    [lugt@localhostnginx]$  ./sbin/nginx

四.使用ab 工具查看效果。

 [lugt@localhost nginx]$ ab –c 10 –n 100 –v 4 http://127.0.0.1/ | grep HTTP/1.1

这行的意思:通过AB测试工具访问地址,并发连接数为30,总测试300次,显示HTTP返回头信息

通过ab 工具可以测出无论同时发送多少连接,最后成功返回200的只有之前限制nginx的最大并发连接数,所以可以证明对于IP的限制功能已经可以使用了。参考数据见FAQ2

FAQ 1 版本问题

如果当前正在使用的Nginx版本没有达到1.7.1版本,很可能nginx还不支持这个功能,

这时候就需要通过一段代码夹在limit_conn_handler函数中来从request中取得x_forwarded_for 的值。

以1.6.1版本为例,代码增加如下。 src/http/modules/ngx_http_limit_conn.c  第184行

hash =ngx_crc32_short(key.data, key.len);                                                                              
If(“” == &ctx->key){                                                             
<span style="white-space:pre">	</span>If(NULL!= r->main->headers_in->x_forwarded_for->elts){                       
           key.data= *(char*)r->main->headers_in->x_forwarded_for->elts;             
         key.len = 4;                                                                                                                               
hash =ngx_crc32_short(key.data, key.len);                                                                     
<span style="white-space:pre">	</span>}                                                                                                                                                 }          

                                                                                                                                                    

FAQ 2 参考数据

这里是一份参考数据, 获取

[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1


HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

English Version

悦灵犀AI
悦灵犀AI

一个集AI绘画、问答、创作于一体的一站式AI工具平台

下载

How to retrievethe true ip of the client user if there are two layers of servers

Days before, wehave been faced such a difficulty which is we can’t use the variable $remote_addr for gathering the clients’ip address. This problem surfaces when we used a proxy server between the trueserver and client, which is actually a cdn. And that makes our functions oflimiting the maximum connections a client can make to a server at a time. Thissituation can also found if the load balance or any anti-spam service are inuse. So that’s why we can’t use remote_addr variable further.

After I did someresearch on the documentation and the code , I found out that this problem canbe solved by replacing the  

 $remote_addr 

 variable with the  

$proxy_add_x_forwarded_for

  variable. As this variable allows to retrievethe data from the column X_forwarded_for from the request, we can use thisvariable functioning in many ways.

And now I shall makean easy example to practically use this method.

First of all,build up a Nginx server.

Here, I will usethe 1.7.9 version (latest to the written time) for instance, therefore, thereexist some differences between older versions than 1.7.1 (see FAQ 1)

1.      Download A Nginx Copy:

[lugt@localhostmysql]$ wget http://nginx.org/download/nginx-1.7.9.tar.gz

2.      Decompress the file

[lugt@localhostmysql]$ tar zxvf nginx-1.7.9.tar.gz

3.      Compile The Code

[lugt@localhostmysql]$ cd nginx-1.7.9

[lugt@localhostnginx-1.7.9]$ ./configure

[lugt@localhostnginx-1.7.9]$ make

[lugt@localhostnginx-1.7.9]$ su

[lugt@localhostnginx-1.7.9]$ make install

4.      And edit the config file nginx.conf

[lugt@localhost nginx-1.7.9]$ su

[lugt@localhostnginx-1.7.9]$ cd /usr/local/nginx

[lugt@localhostnginx]$ vi conf/nginx.conf

There add suchdirectives to the server1 for emulate for an CDN server

upstream dnsnginx1 {
        server[*.*.*.*/yourhostname]:8080 weight=1000; #fill in your ip/hostname
}
server {
        listen       80;
        server_name  [hostname]   #fill your ip/ hostname here
#access_log  logs/host.access.log  main
        location /{
           proxy_pass          http://dnsnginx1;
            proxy_set_header    Host             $host;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
            proxy_redirect      default;
}
}
 
 

After the end ofone server directive, and in the http directive, add so to function the sever2

limit_conn_zone $proxy_add_x_forwarded_for zone=addr:10m;  # sample setting
server {
        listen       8080;
        server_name  [*.*.*.*/hostname]:8080 weight=10000; #fill in ip/hostname here
        limit_conn addr 1; # Enablethe limitation of connection per ip at a time to 1.
 
            location / {
            root   html;
            index  index.html index.htm;
        }
}

And then you cansave , test the config file and run nginx

Test your configfile:

    [lugt@localhostnginx]$  ./sbin/nginx –t

Start the nginx server

    [lugt@localhostnginx]$  ./sbin/nginx

Now, the serverhas been set and you can run a test at instance.

/* This CommandMeans to run a tool to connect to server as 10conn/once and 10 conns in total*/

[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1

FAQ 1

There is actuallysome little malfunctions when using elder versions than 1.7.1 (Probably the newversion has it for a new feature).So to use this directive in earlier versions,some code need to be added.

As a Example inthe version 1.6.1

In filesrc/http/modules/ngx_http_limit_conn.c Line around 184

hash =ngx_crc32_short(key.data, key.len);                                                                             
If("" == &ctx->key){                                                             
    If(NULL!= r->main->headers_in->x_forwarded_for->elts){                       
           key.data= *(char*)r->main->headers_in->x_forwarded_for->elts;             
         key.len = 4;                                                                                                                               
hash =ngx_crc32_short(key.data, key.len);                                                                     
    }
}<span style="font-family: Arial, Helvetica, sans-serif;">           </span>

                                                                                                                                                    

FAQ 2 TestingResults

[lugt@localhost~]$ ab -c 10 -n 100 -v 4 http://127.0.0.1/ | grep HTTP/1.1

 

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1503 Service Temporarily Unavailable

HTTP/1.1 200 OK

以上就介绍了如何在两层服务器的第二层nginx上获取用户ip,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

797

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

272

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

144

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

25

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

92

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

53

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

717

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

64

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号