使用 CDN|CloudFlare|腾讯云|加速乐等|情况下如何获取访客真实 IP|

cera cera

问题分析

网站使用了 CloudFlare 或自建的 CDN 方案,以加快网站的加载速度,但在观察日志发现,服务端获取到的访客 IP 全都是 CDN IP,而不是访客的真实 IP,这就导致无法实现分流或防护方案等高级功能。

技术背景

remote_addr

表示客户端的 IP,需要注意的是它的值是由连到服务器的客户端提供的,也就是说,当你的浏览器直接访问网站时,这个 IP 就是你电脑的 IP,当你使用了代理,那么你的电脑就会先访问这个代理,然后再由这个代理转发请求到网站,此时对于服务器来说,连到服务器的客户端是这个代理,所以这个 IP 就会变成代理的 IP,而不是你电脑的 IP。开启 CDN 后,服务器只记录到 CDN IP 的原因也就是这个。

X-Forwarded-For

这是一个 HTTP 的扩展头部,HTTP/1.1 协议并没有对它定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端的真实 IP。如今已经成为事实上的标准,被各大 HTTP代理、负载均衡等转发服务广泛使用,并已写入标准之中。

XFF(X-Forwarded-For)的格式为:

X-Forwarded-For: client, proxy1, proxy2

由 英文逗号+空格 隔开的多个部分组成,最开始的是离服务器最远的设备 IP(可以认为是真实客户端),然后经过每一级的 IP(中间内容是可以被伪造)。

X-Real_IP

同样是一个自定义头部字段,通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是代理 IP,也可能是用户 IP。

环境模拟

192.168.1.100(用户内网 IP) ⇌ 192.168.1.1/1.1.1.1(局域网的网关 IP 与路由器的公网 IP) ⇌ 2.2.2.2(负载均衡或者 CDN 服务器 IP) ⇌ 3.3.3.3(服务器 IP)

以上基本上就是使用 CDN 后的整个浏览网站行为路线,这种情况下,如果 2.2.2.2 会把 1.1.1.1 的 IP 信息添加到附加信息传递给服务器 3.3.3.3(实际情况中很少会关注内网 IP 是什么,这里不做介绍),服务取得的 IP 就是 1.1.1.1;如果 2.2.2.2 没有把 1.1.1.1 附加传递给服务器 3.3.3.3,则服务器就只能获取到其上一级的 IP 2.2.2.2。

获取真实 IP

根据技术背景中提到的,

① 当我们的服务器直接暴露在公网上,并未使用 CDN 和代理服务器时,是可以直接使用 remote_addr 参数来获取用户 IP。比如 PHP 中可以直接使用 '$_SERVER['REMOTE_ADDR']' 参数。

② 当我们使用了 CDN 之后,一般 CDN 的厂商都会把访客真实 IP 添加到 XFF 中一层层传递下去,接下来我们要做的就是解决这种情况下,怎么获得访客真实 IP。

思路

上面说到 XFF 与 X-Real-IP 是可以伪造的,但 remote_addr 是客户端与服务器的握手 IP,是无法伪造的。我们可以使用 curl 伪造 XFF 与 X-Real-IP 先来测试下,客户端 IP 为 192.168.1.6, 服务端 IP 为192.168.1.135:

curl http://192.168.1.135 -H 'X-Forwarded-For: unkonw, <alert>aa,1.1.1.1</alert>" 1.1.1.1' -H 'X-Real-IP: 2.2.2.2, <a>'

在服务器中使用 tcpdump 抓包, 然后打开 Wireshark 分析请求头部信息,可以看到:

Hypertext Transfer Protocol
    GET / HTTP/1.1\r\n
    User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2\r\n
    Host: 192.168.1.135\r\n
    Accept: */*\r\n
    X-Forwarded-For: unkonw, <alert>aa,1.1.1.1</alert>" 1.1.1.1\r\n
    X-Real-IP: 2.2.2.2, <a>\r\n
    \r\n
    [Full request URI: http://192.168.1.135/]
    [HTTP request 1/1]

可以看出,它记录了我们伪造的信息,所以 XFF 与 X-Real-IP 是不可以直接拿来用的。我们可以把各个代理层的 IP 使用排除法排除在外,那么剩下的便是用户的真实 IP 了。

配置

Nginx

使用 Nginx 的 RealIP 模块来实现自动排除,在编译时(或重新编译)加上 -with-http_realip_module 就可以了,具体方法可以参考《建站系列之为 Nginx 安装 GeoIP 模块实现分流或屏蔽某个地区访问》,然后在 Nginx 配置中加入:

......
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 37.0.121.100;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
......

说明:

  • set_real_ip_from: 后面是可信 IP,如果是使用 CDN,则是 CDN IP;
  • real_ip_header: 表示从哪个 header 中获取 IP 信息;
  • real_ip_recursive: 递归排除 IP,IP 串从右到左开始排除。

Nginx 与代理 IP 有关的两个变量:

  • $proxy_add_x_forwarded_for:会累加代理层的 IP 向后传递;
  • $http_x_forwarded_for 仅仅是上层传过来的值;

Apache

Apache 有两个模块来获取真实 IP:

  • mod_rpaf:Apache-2.2 支持,apache-2.4 不支持
  • mod_remoteip:Apache-2.4 自带模块,apache-2.2 支持

mod_rpaf 实际使用已经过测试,mod_remoteip 还未实际测试,如遇到有问题会再修改。

配置 mod_rpaf 模块(需要自行安装)
LoadModule rpaf_module        modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 10.8.0.110  #代理服务器的 IP 地址
RPAFheader X-Forwarded-For

备注:RPAFproxy_ips 后面添加代理服务器的 IP,有多少个写多少个。

配置 mod_remoteip 模块
# vim /usr/local/apache/conf/extra/httpd-remoteip.conf
......
LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1
......

附录

各大 CDN 的节点 IP 段

腾讯云 CDN

58.250.143.0/24
58.251.121.0/24
59.36.120.0/24
61.151.163.0/24
101.227.163.0/24
111.161.109.0/24
116.128.128.0/24
123.151.76.0/24
125.39.46.0/24
140.207.120.0/24
180.163.22.0/24
183.3.254.0/24
223.166.151.0/24

加速乐 CDN

113.107.238.0/24 
106.42.25.0/24
183.222.96.0/24 
117.21.219.0/24 
116.55.250.0/24
111.202.98.0/24 
111.13.147.0/24
122.228.238.0/24
58.58.81.0/24
1.31.128.0/24
123.155.158.0/24
106.119.182.0/24
180.97.158.0/24
113.207.76.0/24
117.23.61.0/24 
118.212.233.0/24 
111.47.226.0/24 
219.153.73.0/24 
113.200.91.0/24 
1.32.240.0/24 
203.90.247.0/24 
183.110.242.0/24 
202.162.109.0/24 
182.23.211.0/24
1.32.242.0/24
1.32.241.0/24
202.162.108.0/24
185.254.242.0/24
109.94.168.0/24 
109.94.169.0/24 
1.32.243.0/24 
61.120.154.0/24 
1.255.41.0/24 
112.90.216.0/24 
61.213.176.0/24 
1.32.238.0/24 
1.32.239.0/24 
1.32.244.0/24

百度云 CDN

111.32.135.0/24 
111.32.136.0/24
125.39.174.0/24
125.39.239.0/24
112.65.73.0/24 
112.65.74.0/24 
112.65.75.0/24 
119.84.92.0/24 
119.84.93.0/24 
113.207.100.0/24 
113.207.101.0/24 
113.207.102.0/24
180.163.188.0/24 
180.163.189.0/24 
163.53.89.0/24 
101.227.206.0/24 
101.227.207.0/24
119.188.97.0/24 
119.188.9.0/24 
61.155.149.0/24 
61.156.149.0/24 
61.155.165.0/24 
61.182.137.0/24 
61.182.136.0/24 
120.52.29.0/24 
120.52.113.0/24 
222.216.190.0/24 
219.159.84.0/24 
183.60.235.0/24 
116.31.126.0/24 
116.31.127.0/24 
117.34.13.0/24 
117.34.14.0/24 
42.236.93.0/24 
42.236.94.0/24 
119.167.246.0/24 
150.138.149.0/24 
150.138.150.0/24 
150.138.151.0/24 
117.27.149.0/24 
59.51.81.0/24 
220.170.185.0/24 
220.170.186.0/24 
183.61.236.0/24 
14.17.71.0/24 
119.147.134.0/24 
124.95.168.0/24 
124.95.188.0/24 
61.54.46.0/24 
61.54.47.0/24 
101.71.55.0/24 
101.71.56.0/24 
183.232.51.0/24 
183.232.53.0/24 
157.255.25.0/24 
157.255.26.0/24 
112.25.90.0/24 
112.25.91.0/24 
58.211.2.0/24 
58.211.137.0/24 
122.190.2.0/24
122.190.3.0/24 
183.61.177.0/24 
183.61.190.0/24 
117.148.160.0/24 
117.148.161.0/24 
115.231.186.0/24 
115.231.187.0/24

牛盾 CDN

113.31.27.0/24
222.186.19.0/24
122.226.182.0/24
36.99.18.0/24
123.133.84.0/24
221.204.202.0/24
42.236.6.0/24
61.130.28.0/24
61.174.9.0/24
223.94.66.0/24
222.88.94.0/24
61.163.30.0/24
223.94.95.0/24
223.112.227.0/24
183.250.179.0/24
120.241.102.0/24
125.39.5.0/24
124.193.166.0/24
122.70.134.0/24
111.6.191.0/24
122.228.198.0/24
121.12.98.0/24
60.12.166.0/24
118.180.50.0/24
183.203.7.0/24
61.133.127.0/24
113.7.183.0/24
210.22.63.0/24
60.221.236.0/24
122.227.237.0/24

360 CDN

123.6.13.0/24
202.102.85.0/24
61.160.224.0/24
182.140.227.0/24
221.204.14.0/24
222.73.144.0/24
61.240.144.0/24
36.27.212.0/24
125.88.189.0/24
120.52.18.0/24
119.84.15.0/24
180.163.224.0/24

CloudFlare CDN

103.21.244.0/22 
103.22.200.0/22 
103.31.4.0/22 
104.16.0.0/12 
108.162.192.0/18 
131.0.72.0/22 
141.101.64.0/18 
162.158.0.0/15 
172.64.0.0/13 
173.245.48.0/20 
188.114.96.0/20 
190.93.240.0/20 
197.234.240.0/22 
198.41.128.0/17 
2400:cb00::/32 
2405:b500::/32 
2606:4700::/32 
2803:f800::/32 
2c0f:f248::/32 
2a06:98c0::/29

cera cloudiplc tengxunyun

相关推荐