Linux 运营干货,关于如何在使用 Content Delivery Network (CDN) 内容分发网络后服务器既后端能正常获取客户端的真实IP。本篇文章以CloudFlare为例子实例讲解获取前端客户端真实IP的方法,万事开头难相信你会了这一招应该会举一反三吧!

0x01 前提条件

PS:像我就只能用得起这些免费的CDN服务了,所以我也就举了两个免费的“荔枝”

0x02 获取节点IP

在开始前需要取得CDN服务商的节点IP,这个CDN服务商都会提供。

例如 CloudFlare 的节点地址 https://www.cloudflare.com/ips/

1
#CloudFlare IPv4
2
103.21.244.0/22
3
103.22.200.0/22
4
103.31.4.0/22
5
104.16.0.0/12
6
108.162.192.0/18
7
131.0.72.0/22
8
141.101.64.0/18
9
162.158.0.0/15
10
172.64.0.0/13
11
173.245.48.0/20
12
188.114.96.0/20
13
190.93.240.0/20
14
197.234.240.0/22
15
198.41.128.0/17
16
#CloudFlare IPv6
17
2400:cb00::/32
18
2405:8100::/32
19
2405:b500::/32
20
2606:4700::/32
21
2803:f800::/32
22
2c0f:f248::/32
23
2a06:98c0::/29

0x03 配置 Nginx

编辑 Nginx 主配置文件 nginx.conf 添加代码,里面的注释不要更改,后面自动更新地址列表会用到

1
#cfip4
2
set_real_ip_from 103.21.244.0/22; #cfipv4
3
set_real_ip_from 103.22.200.0/22; #cfipv4
4
set_real_ip_from 103.31.4.0/22; #cfipv4
5
set_real_ip_from 104.16.0.0/12; #cfipv4
6
set_real_ip_from 108.162.192.0/18; #cfipv4
7
set_real_ip_from 131.0.72.0/22; #cfipv4
8
set_real_ip_from 141.101.64.0/18; #cfipv4
9
set_real_ip_from 162.158.0.0/15; #cfipv4
10
set_real_ip_from 172.64.0.0/13; #cfipv4
11
set_real_ip_from 173.245.48.0/20; #cfipv4
12
set_real_ip_from 188.114.96.0/20; #cfipv4
13
set_real_ip_from 190.93.240.0/20; #cfipv4
14
set_real_ip_from 197.234.240.0/22; #cfipv4
15
set_real_ip_from 198.41.128.0/17; #cfipv4
16
#cfip6
17
set_real_ip_from 2400:cb00::/32; #cfipv6
18
set_real_ip_from 2405:8100::/32; #cfipv6
19
set_real_ip_from 2405:b500::/32; #cfipv6
20
set_real_ip_from 2606:4700::/32; #cfipv6
21
set_real_ip_from 2803:f800::/32; #cfipv6
22
set_real_ip_from 2c0f:f248::/32; #cfipv6
23
set_real_ip_from 2a06:98c0::/29; #cfipv6
24
#lock
25
#使用以下任意一个即可
26
#eal_ip_header CF-Connecting-IP; 
27
real_ip_header X-Forwarded-For;

这里的 CF-Connecting-IP (CloudFlare额外提供) 是根据 CDN 服务商提供的返回IP地址的请求头而决定的,正常选择第二段即可,具体需要看 CDN 服务商的文档。

关于 CF-Connecting-IP 在这里有说明 https://support.cloudflare.com/hc/en-us/articles/200170986

1
CF-Connecting-IP
2
3
To provide the client (visitor) IP address for every request to the origin, Cloudflare adds the CF-Connecting-IP header.
4
"CF-Connecting-IP: A.B.C.D"
5
Where A.B.C.D is the client's IP address, also known as the original visitor IP address.

经过这样的简单配置,后端NGINX应该就可以正常获取IP地址了,但是 CDN 服务商增加或者更换节点节点地址都是会变动的怎么办呢?别急往下看

0x04 自动获取节点列表

上面说过每个 CDN 服务商都会在某个页面提供节点地址,例如 CloudFlare v4 节点地址 CloudFlare V6 节点地址 CloudFlare比较实在提供了纯文本版的节点列表,如果不是纯节点地址网页就要写正则匹配了。好了条件都有了,我们来写个脚本定时GET页面并抓到节点列表自动写到 Nginx 的配置文件上。

1
#/bin/sbin
2
3
#变量设定
4
#Nginx配置文件
5
nginx=/etc/nginx/conf/nginx.conf
6
#临时文件夹
7
mude=/home/data/shell/dat/cloudflare
8
#日志文件
9
log=/home/data/shell/log/cloudflare.log
10
11
#初始化
12
oneup4=0
13
oneup6=0
14
updata=0
15
if [ ! -d "$mude" ]; then
16
  sudo mkdir $mude
17
fi
18
19
#获取最新IPV4、IPV6地址
20
sudo wget -q https://www.cloudflare.com/ips-v4 -O $mude/ipv4.cf > $log
21
sudo wget -q https://www.cloudflare.com/ips-v6 -O $mude/ipv6.cf > $log
22
23
#判断是否第一次执行脚本
24
if [ ! -e "$mude/ipv4" ]; then
25
  oneup4=1
26
  sudo cp $mude/ipv4.cf $mude/ipv4 > $log
27
fi
28
if [ ! -e "$mude/ipv6" ]; then
29
  oneup6=1
30
  sudo cp $mude/ipv6.cf $mude/ipv6 > $log
31
fi
32
33
#更新动作
34
diff -q $mude/ipv4 $mude/ipv4.cf > $log
35
if [ $? != 0 -o $oneup4 == 1 ]; then
36
    sudo sed -i 's/^/        set_real_ip_from &/g' ${mude}/ipv4 > $log
37
    sudo sed -i 's/$/; #cfipv4&/g' $mude/ipv4 > $log
38
    sudo sed -i '/#cfipv4/d' ${nginx} > $log
39
    # 此处手动更改
40
    sudo sed -i '/#cfip4/r /home/data/shell/dat/cloudflare/ipv4' ${nginx} > $log
41
    updata=1
42
fi
43
diff -q $mude/ipv6 $mude/ipv6.cf > $log
44
if [ $? != 0 -o $oneup6 == 1 ]; then
45
    sudo sed -i 's/^/        set_real_ip_from &/g' ${mude}/ipv6 > $log
46
    sudo sed -i 's/$/; #cfipv6&/g' ${mude}/ipv6 > $log
47
    sudo sed -i '/#cfipv6/d' ${nginx} > $log
48
    # 此处手动更改
49
    sudo sed -i '/#cfip6/r /home/data/shell/dat/cloudflare/ipv6' ${nginx} > $log
50
    updata=1
51
fi
52
53
#文件更新后重载Nginx服务器
54
if [ $updata == 1 ]; then
55
    sudo /etc/init.d/nginx force-reload > $log
56
fi
57
58
#重新归档数据已备下次判断
59
sudo cp $mude/ipv4.cf $mude/ipv4 > $log
60
sudo cp $mude/ipv6.cf $mude/ipv6 > $log
61
exit 0

简单介绍一下脚本流程: