在两层或更多代理的情况下,nginx透传配置方案:

1.   第一层代理将用户的真实 IP 放在 X-Real-IP 中传递下去,后面的每一层都使用 X-Real-IP 继续往下传递。配置为:

proxy_set_header X-Real-IP $remote_addr;     # 针对首层代理,拿到真实IP
  proxy_set_header X-Real-IP $http_x_real_ip;  # 针对非首层代理,一直传下去

2、从首层开始,将用户的真实IP 放在 X-Forwarded-For 中,而不是累加各层服务器的 IP,但这样也不够合理,因为丢掉了整个链路信息。配置为:

proxy_set_header X-Forwarded-For $remote_addr; # 针对首层代理

       针对非首层代理,则可以用逐步累加的方法,配置为:

proxy_set_header X-Forwarded-For $http_x_forwarded_for; # 针对非首层代理

       从 X-Forwarded-For 中获取的用户真实IP,排除掉所有代理IP,取最后一个符合IP规则的,注意不是第一个,因为第一个可能是被伪造的(除非首层代理使用了握手会话 IP 做为值向下传递)。

注意:nginx配置的这两个变量:
* $proxy_add_x_forwarded_for 会累加代理层的IP向后传递
* $http_x_forwarded_for 仅仅是上层传过来的值

3.配合nginx realip模块获取用户真实IP

       nginx的一个模块 realip_module ,能够将各层代理的IP排除在外,取到了真实的用户IP。原理是从XFF中抛弃指定的代理层IP,那么最后一个符合规则的就是用户IP,nginx realip_module 模块需要在编译nginx的时候加上参数--with-http_realip_module,然后在nginx配置中增加以下配置(可以在http,server或location段中增加):

# set user real ip to remote addr
    set_real_ip_from   10.200.21.0/24;
    set_real_ip_from   10.100.23.0/24;
    real_ip_header     X-Forwarded-For;
    real_ip_recursive on;

       set_real_ip_from 后面是可信 IP 规则,可以有多条。如果启用CDN,知道CDN的溯源IP,也要加进来,除排掉可信的,就是用户的真实IP,会写入 remote addr这个变量中。
        比如在PHP中可以使用$_SERVER['REMOTE_ADDR'] 来获取。而WEB SERVER 不使用任何反向代理时,也是取这个值,这就达到了我们之前所说的原则。
        real_ip_recursive 是递归的去除所配置中的可信IP。如果只有一层代理,也可以不写这个参数。

----------------------------------------------------------

-----------------------------------------------------------

我目前是用第一种测试可以

nginx根据ip获取mac nginx获取本机ip_IP


#知识背景

1.1. 前提知识点:

还有nginx中的几个变量:

  • remote_addr

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

X-Forwarded-For(简称XFF)

X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 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 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。但是在正常情况下,web服务器获取Remote Address只会获取到上一级的IP,本例里则是proxy3 的 IP3,这里先埋个伏笔。

X-Real-IP

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