下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 50 | postread阶段:获取真实客户端地址的realip模块
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

Nginx核心知识100讲

共155讲 · 155课时,约1300分钟
18593
免费
01 | 课程综述
免费
02 | Nginx适用于哪些场景?
免费
03 | Nginx出现的历史背景
免费
04 | 为什么用Nginx:它的 5 ...
免费
05 | Nginx的四个主要组成部分
06 | Nginx的版本发布历史
07 | 选择哪一个Nginx发行版本...
08 | 编译出适合自己的Nginx
09 | Nginx配置文件的通用语法...
10 | Nginx命令行及演示:重载...
11 | 用Nginx搭建一个可用的静...
12 | 用Nginx搭建一个具备缓存...
13 | 用GoAccess实现可视化并实...
14 | 从网络原理来看SSL安全协...
15 | 对称加密与非对称加密各自...
16 | SSL证书的公信力是如何保...
17 | SSL协议握手时Nginx的性能...
18 | 用免费SSL证书实现一个HTT...
19 | 基于OpenResty用Lua语言...
20 | Nginx的请求处理流程
21 | Nginx的进程结构
22 | Nginx的进程结构实例演示
23 | 使用信号管理Nginx的父子...
24 | reload重载配置文件的真相
25 | 热升级的完整流程
26 | 优雅地关闭worker进程
27 | 网络收发与Nginx事件间的...
28 | Nginx网络事件实例演示
29 | Nginx的事件驱动模型
30 | epoll的优劣及原理
31 | Nginx的请求切换
32 | 同步&异步、阻塞&非阻塞...
33 | Nginx的模块究竟是什么?
34 | Nginx模块的分类
35 | Nginx如何通过连接池处理...
36 | 内存池对性能的影响
37 | 所有worker进程协同工作的...
38 | 用好共享内存的工具:Slab...
39 | 哈希表的max_size与bucke...
40 | Nginx中最常用的容器:红...
41 | 使用动态模块来提升运维效...
免费
42 | 第三章内容介绍
43 | 冲突的配置指令以谁为准?
44 | Listen指令的用法
免费
45 | 处理HTTP请求头部的流程
46 | Nginx中的正则表达式
47 | 如何找到处理请求的server...
48 | 详解HTTP请求的11个阶段
49 | 11个阶段的顺序处理
50 | postread阶段:获取真实客...
51 | rewrite阶段的rewrite模块...
52 | rewrite阶段的rewrite模块...
53 | rewrite阶段的rewrite模块...
54 | find_config阶段:找到处...
55 | preaccess阶段:对连接做...
56 | preaccess阶段:对请求做...
57 | access阶段:对ip做限制的...
58 | access阶段:对用户名密码...
59 | access阶段:使用第三方做...
60 | access阶段的satisfy指令
61 | precontent阶段:按序访问...
62 | 实时拷贝流量:precontent...
63 | content阶段:详解root和a...
64 | static模块提供的3个变量
65 | static模块对url不以斜杠...
66 | index和autoindex模块的用...
67 | 提升多个小文件性能的conc...
68 | access日志的详细用法
69 | HTTP过滤模块的调用流程
70 | 用过滤模块更改响应中的字...
71 | 用过滤模块在http响应的前...
72 | Nginx变量的运行原理
73 | HTTP框架提供的请求相关的...
74 | HTTP框架提供的其他变量
75 | 使用变量防盗链的referer...
76 | 使用变量实现防盗链功能实...
77 | 为复杂的业务生成新的变量...
78 | 通过变量指定少量用户实现...
79 | 根据IP地址范围的匹配生成...
80 | 使用变量获得用户的地理位...
81 | 对客户端使用keepalive提...
82 | 反向代理与负载均衡原理
83 | 负载均衡策略:round-rob...
84 | 负载均衡哈希算法:ip_has...
85 | 一致性哈希算法:hash模块
86 | 最少连接算法以及如何跨wo...
87 | upstream模块提供的变量
88 | proxy模块处理请求的流程
89 | proxy模块中的proxy_pas...
90 | 根据指令修改发往上游的请...
91 | 接收用户请求包体的方式
92 | 与上游服务建立连接
93 | 接收上游的响应
94 | 处理上游的响应头部
95 | 上游出现失败时的容错方案
96 | 对上游使用SSL连接
97 | 用好浏览器的缓存
98 | Nginx决策浏览器过期缓存...
99 | 缓存的基本用法
100 | 对客户端请求的缓存处理...
101 | 接收上游响应的缓存处理...
102 | 如何减轻缓存失效时上游...
103 | 及时清除缓存
104 | uwsgi、fastcgi、scgi指...
105 | memcached反向代理的用法
106 | 搭建websocket反向代理
107 | 用分片提升缓存效率
108 | open file cache提升系...
109 | HTTP/2协议介绍
110 | 搭建HTTP/2服务并推送资...
111 | gRPC反向代理
112 | stream四层反向代理的7个...
113 | proxy protocol协议与r...
114 | 限并发连接、限IP、记日...
115 | stream四层反向代理处理S...
116 | stream_preread模块取出S...
117 | stream proxy四层反向...
118 | UDP反向代理
119 | 透传IP地址的3个方案
120 | 性能优化方法论
121 | 如何高效使用CPU
122 | 多核间的负载均衡
免费
123 | 控制TCP三次握手参数
免费
124 | 建立TCP连接的优化
125 | 滑动窗口与缓冲区
126 | 优化缓冲区与传输效率
127 | 慢启动与拥塞窗口
128 | TCP协议的keepalive功能
129 | 减少关闭连接时的time_wa...
130 | lingering_close延迟关闭...
131 | 应用层协议的优化
免费
132 | 磁盘IO的优化
133 | 减少磁盘读写次数
134 | 零拷贝与gzip_static模...
135 | 用tcmalloc优化内存分配
136 | 使用Google PerfTools分...
137 | 使用stub_status模块监控...
138 | 第三方模块源码的阅读
139 | Nginx的启动流程
140 | HTTP第三方模块的初始化
141 | if指令是邪恶的吗?
142 | 解读Nginx的核心转储文件
143 | 通过debug日志定位问题
144 | OpenResty概述
145 | OpenResty中的Nginx模块...
146 | 如何在Nginx中嵌入Lua代...
147 | OpenResty中Lua与C代码...
148 | 获取、修改请求与响应的S...
149 | 工具类型的SDK
150 | 同步且非阻塞的底层SDK:...
151 | 基于协程的并发编程SDK
152 | 定时器及时间相关的SDK
153 | share.DICT基于共享内存...
154 | 子请求的使用方法
155 | 基于OpenResty的WAF防火...

精选留言(20)

  • 2019-05-23
    老师你好,还有一个问题,我们公司目前打算上kong,kong有个限流插件,是根据X-Forwarded-For判断IP,我们公司架构是CDN-->KONG-->后端真实服务,这显然是获取不到用户真实IP的,所以我使用real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    set_real_ip_from 一堆CDN IP;
    获取到了用户真实IP,但是如果再有一层代理(不知道代理IP),或者,边缘CDN没有请求的资源,向上一级CDN请求,该如何获取用户真实IP呢

    作者回复: 这样的话,realip模块做不到,因为它基于trust ip address设计的,你可以直接用http_X-Forwarded-For变量取到所有的值,再做字符串处理,取第一个IP

    2
  • 2019-04-13
    老师您好,我执行curl http://gx.com:666/ -H "X-Forwarded-For: 167.156.88.199,127.0.0.1,1.1.1.1"
    为什么$remote_addr变量是1.1.1.1,按照X-Forwarded-For: client_ip,proxy_ip1,proxy_ip2...的格式,期望的输出应该是167.156.88.199才对。
    这是我的配置:
    1 server {
      2 listen 127.0.0.1:666;
      3 server_name gx.com;
      4 set_real_ip_from 127.0.0.1;
      5 real_ip_header X-Forwarded-For;
      6 real_ip_recursive off;
      7
      8 location / {
      9 return 200 "Your Client Ip: $remote_addr, $realip_remote_addr\n";
     10 }
     11 }

    望老师解答,感谢。
    展开

    作者回复: 你要这么配置:
    real_ip_recursive on;
    set_real_ip_from 1.1.1.1;
    set_real_ip_from 127.0.0.1;
    Nginx的设计思想就是这样,参见http://nginx.org/en/docs/http/ngx_http_realip_module.html,明确写着last address。Nginx做这种设定更多是从trust ip角度出发的。

    2
  • 2018-12-12
    你好,老师,这一部分我有几个问题一直不是很理解,希望您能给解答一下:
    1、例如 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 作用是将$proxy_add_x_forwarded_for的值赋值给前面的变量 X-Forwarded-For 吗? 那变量X-Forwarded-For名称是否可以随意进行定义?该变量的用处是什么,因为nginx的日志定义log_format中并未使用到X-Forwarded-For这个变量
    2、如果是多层nginx代理,nginx01+nginx02 nginx02如何获取到客户端的真实ip地址
    3、proxy_set_header中的定义,在log_format中并未应用到,各变量的作用在此次视频中也未讲解到
    展开

    作者回复: 1、proxy_set_header是设置发向上游服务的请求头部的指令,第4部分课程会详细介绍。
    X-Forwarded-For是RFC7239定义的头部,所有各大web服务都支持,你改了后就只能自己处理,不能依赖nginx之类的服务自动处理了。这一节课介绍的realip模块,也必须通过这个名称来修改remote_addr变量。
    2、通过X-forwarded-for或者x-realip头部。
    3、proxy反向代理在第4部分介绍。咱们课程后面内容还很多:-)

    2
  • 2019-08-25
    陶老师好。用X-Real-IP来获取客户端IP不是最简单吗? 例子里用X-Forwarded-For 来获取有什么优点吗?

    作者回复: X-Real-IP是Nginx独有的,不是RFC规范,所以与client间如何还有其他非Nginx软件实现的代理,将取不到X-Real-IP头部

    1
  • 2019-08-13
    为什么视频里明明是取X-Forward-For最右边的ip,留言里也有两位同学已经指出这个问题了,老师取仍然坚持说是最左边呢?我测试后也发现取的是最右边的ip作为remote_add 的值。准确的说当real_ip_recursive 为on时,是从XFF最右边的ip开始遍历,找到第一个不等于所有set_real_ip_from的ip,将这个ip作为remote_addr的值;当real_ip_recursive为off时,取的是XFF最右边的那个ip。能给个解释吗

    作者回复: 1、你说的对。
    2、视频里要表达的意思是,最左边是客户端的真实地址,也是我们真正需要的地址,右边的是代理服务器地址。为了能够取到最左边地址,依赖于set_real_ip_from设置好可信代理地址。你可以参见无菇朋友的例子。

    1
    1
  • 2019-05-10
    代理服务器设置最好下面两行都设置
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    阿里云 SLB 转发的 HTTP 请求不会设置 x-real-ip 头部,但设置了 x-forwared-for 头部,该字段中只有客户端的 IP,没有 SLB 的 IP。ECS 上看到 remote-ip 是 slb 的 IP。
    展开
    1
  • 2019-05-10
    要注意 realip 模块是如何从 x-forwarded-for 列表中获取真实 IP 的。
    按照 real_ip_recursive 的官网解释:

         If recursive search is disabled, the original client address that matches one of the trusted addresses is replaced by the last address sent in the request header field defined by the real_ip_header directive. If recursive search is enabled, the original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field.
    翻译:
    如果禁用递归搜索,匹配其中一个可信地址的原始客户端地址,将替换为 real_ip_header 指令定义的请求头字段中发送的最后一个地址。 如果启用了递归搜索,则匹配其中一个可信地址的原始客户端地址,将替换为请求头字段中发送的最后一个非信任地址。

    结论:realip模块并不是获取 x-forwared-for 的第一个 IP 作为 client ip。
    展开
    1
  • 2019-05-09
    陶老师
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
    这个指令是什么意思呢?是把$proxy_add_x_forwarded_for的值赋值给X-Forwarded-For这个变量了吗?

    作者回复: 不是,是传递X-Forwarded-For头部给上游,但这个头部的值是什么呢?就用proxy_add_x_forwarded_for变量的值吧。proxy_add_x_forwarded_for变量的值是什么呢?参考http://nginx.org/en/docs/http/ngx_http_proxy_module.html#variables

    1
  • 2019-03-18
    real_ip_header到底是取X-Forwarded-For最右边的IP作为client真实IP,还是取XFF最左边的?看视频里面是取得最右边IP。但根据https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For的解释:X-Forwarded-For: <client>, <proxy1>, <proxy2>,最左边的才是真实IP吧?

    作者回复: 是最左边,视频里也是最左边啊,第一页PPT里举的例子里,115.204.33.1就是最左边

    1
    1
  • 2019-02-03
    我有一点不明白:在 nginx 配置 realip 模块,为什么能够影响到 CDN 服务器或者代理服务器,将真实 ip 添加到请求头部信息中,并发送到最终的上游服务 nginx ?
    我想到的解释就是:其实客户端的真实 ip 本来就已经存在于 它的请求连接中,无论有没有配置 realip 模块。
    当配置了 realip 模块,只是让 nginx 能通过 X-Forwarded-For ,remote_addr 这些参数取出来而已。当没有配置 realip ,只是影响到 X-Forwarded-For ,remote_addr 这些参数的作用而已。
    可以这样理解吗?
    展开

    作者回复: nginx与下游间只要有反向代理,那么就无法从IP报文头部取出客户端地址了。通常,符合规范的反向代理会把客户端地方放在X-Forwarded-For头部中。所以,realip模块负责把这些头部中的值,替换掉remote_addr等变量的值

    1
  • 2019-01-17
    set_real_ip_from设置可控的来源,但是CDN的IP比较多,不太可能把所有的CDN IP都添加进去吧?

    作者回复: 可以用子网掩码,把一段IP设为可信地址的。

    1
  • 2019-11-07
    通过以上的回答,在 X-Forward-For 的最左边才是真实用户的地址,右边都是代理地址,当我们把 real_ip_header 设置为 X-Forward-For 时,如果没有启用 环回地址 real_ip_recursive,我们取到的 $remote_addr 是 X-Forward-For 中最右边的 ip,无论是否设置了 set_real_ip_from;如果启用了环回地址 real_ip_recursive on,那么就获取最左边的 ip,也就是排除设置了 set_real_ip_from(可信地址外的)。老师,我的理解对吗

    作者回复: 完全正确!
    如果启用了环回地址,不一定是最左边的IP,而是从右边开始数,第一个非可信地址的IP

  • 2019-10-23
    ➜ conf cat nginx.conf
     server {
         listen 8080;
         server_name localhost; location /
         {
        #set_real_ip_from 192.168.0.0/24;    
         set_real_ip_from 127.0.0.1;
        #real_ip_header X-Forwarded-For;
         real_ip_header X-Real-IP;    
        return 200 " remote_addr:$remote_addr realip_remote_addr:$realip_remote_addr realip_remote_port:$realip_remote_port ";
      }
     }
    ➜ conf curl -H 'X-Forwarded-For:192.168.0.1' -H 'X-Real-IP:192.168.0.1' -i 127.0.0.1:8080
     remote_addr:127.0.0.1
     realip_remote_addr:127.0.0.1 realip_remote_port:58012
     老师,请问下我的配置如上,为什么remote_addr一直都是127.0.0.1呢
    展开

    作者回复: 把set_real_ip_from 127.0.0.1放在server{}下,不要放在location{}中,realip工作在find_config阶段之前

    1
  • 2019-10-06
    6:52 说的是 从X-Forwarded-For最后一个ip取? 怎么前后矛盾的?

    作者回复: 从后向前取,没错。你可以看下无菇朋友的留言,这个例子很有代表性

    2
  • 2019-05-29
    老师你好:
    1. 为什么realip 的指令的 Context 包括 location 指令块,确定 location 指令块不是在 find-config 阶段发生的吗?
    2. 我看视频是在 server 块中配置的。我在 server 块中配置$remote_addr变量确实生效了。但是我在location 块中配置的时候没有生效。这个如果用 location 块中 已经进入find-config 阶段。此时 $remote_addr 变量已经确定下来来解释是可以解释通的。但是我看 realip 的相关指令中 Context 都是包括 location 块的,为什么?
    谢谢。
    展开

    作者回复: 1、没有任何http模块会在find-config阶段生效,因为此阶段仅供Nginx框架使用;
    2、变量与HTTP阶段无关,当你取变量值的时候,才是计算出变量的时候,所以,你要考虑你在什么阶段使用变量。

  • 2019-03-05
    老师,如果是nginx1反向代理给nginx2,nginx2配置realip模块,nginx2可以通过remote_addr直接获取客户端真实ip么? 老师,我这里好像有些问题,您能看下么?

    nginx 1 配置,openresty/1.13.6.1
    server {
            listen 80;
            server_name localhost;
            location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                # include proxy_params;
                proxy_pass http://10.141.128.6:81;
            }
        }

    nginx2 配置,nginx/1.14.2,编译了realip模块
        server {
            listen 81;
            server_name localhost;
            real_ip_header X-Real-IP;

            location /{
                return 200 "Client real ip: $remote_addr";
            }
        }

    客户端CURL返回
    C:\Users\> curl 123.206.25.230:80
    Client real ip: 10.141.128.6
    展开

    作者回复: 你需要把nginx1的IP,加入到nginx2中的可信地址中,即在nginx2的nginx.conf中加入set_real_ip_from指令

  • 2019-02-28
    real_ip_header设置为X-Forwarded-For 为什么会从倒数第一个ip开始取?这不会渠道代理层的ip吗?

    作者回复: 不是倒数第一个,是正数第一个。该头部格式为:X-Forwarded-For: client1, proxy1, proxy2

  • 2019-02-08
    启用realip模块后$realip_remote_port和$remote_port变量表示什么?,realip_remote_port通过什么头部获取呢?

    作者回复: 当realip模块替换了原来remote_port、remote_addr变量的值时(由IP报文头部中获得),为了不让原变量值丢失,才用realip_remote_port来存放原变量值的。

  • 2018-12-29
    请问老师,Nginx有办法获取IP的请求端口吗?就是发起HTTP请求连接的客服端端口。

    作者回复: 如果nginx与客户端之间没有其他反向代理,可以用remote_port获取到。如果存在其他反向代理,就无法用通用的办法获取到了。

  • 2018-12-20
    postread阶段 可以拿到原始的header头

    作者回复: :-)