Linux 运营干货,关于如何在使用 Content Delivery Network (CDN) 内容分发网络后服务器既后端能正常获取客户端的真实IP。本篇文章以CloudFlare为例子实例讲解获取前端客户端真实IP的方法,万事开头难相信你会了这一招应该会举一反三吧!
0x01 前提条件
- nginx 模块 ngx_http_realip_module
- CDN 服务商有返回真实IP地址
PS:像我就只能用得起这些免费的CDN服务了,所以我也就举了两个免费的“荔枝”
0x02 获取节点IP
在开始前需要取得CDN服务商的节点IP,这个CDN服务商都会提供。
例如 CloudFlare 的节点地址 https://www.cloudflare.com/ips/
#CloudFlare IPv4 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 #CloudFlare IPv6 2400:cb00::/32 2405:8100::/32 2405:b500::/32 2606:4700::/32 2803:f800::/32 2c0f:f248::/32 2a06:98c0::/29
0x03 配置 Nginx
编辑 Nginx 主配置文件 nginx.conf 添加代码,里面的注释不要更改,后面自动更新地址列表会用到
#cfip4 set_real_ip_from 103.21.244.0/22; #cfipv4 set_real_ip_from 103.22.200.0/22; #cfipv4 set_real_ip_from 103.31.4.0/22; #cfipv4 set_real_ip_from 104.16.0.0/12; #cfipv4 set_real_ip_from 108.162.192.0/18; #cfipv4 set_real_ip_from 131.0.72.0/22; #cfipv4 set_real_ip_from 141.101.64.0/18; #cfipv4 set_real_ip_from 162.158.0.0/15; #cfipv4 set_real_ip_from 172.64.0.0/13; #cfipv4 set_real_ip_from 173.245.48.0/20; #cfipv4 set_real_ip_from 188.114.96.0/20; #cfipv4 set_real_ip_from 190.93.240.0/20; #cfipv4 set_real_ip_from 197.234.240.0/22; #cfipv4 set_real_ip_from 198.41.128.0/17; #cfipv4 #cfip6 set_real_ip_from 2400:cb00::/32; #cfipv6 set_real_ip_from 2405:8100::/32; #cfipv6 set_real_ip_from 2405:b500::/32; #cfipv6 set_real_ip_from 2606:4700::/32; #cfipv6 set_real_ip_from 2803:f800::/32; #cfipv6 set_real_ip_from 2c0f:f248::/32; #cfipv6 set_real_ip_from 2a06:98c0::/29; #cfipv6 #lock #使用以下任意一个即可 #eal_ip_header CF-Connecting-IP; real_ip_header X-Forwarded-For;
这里的
CF-Connecting-IP
(CloudFlare额外提供) 是根据 CDN 服务商提供的返回IP地址的请求头而决定的,正常选择第二段即可,具体需要看 CDN 服务商的文档。关于
CF-Connecting-IP
在这里有说明 https://support.cloudflare.com/hc/en-us/articles/200170986CF-Connecting-IP To provide the client (visitor) IP address for every request to the origin, Cloudflare adds the CF-Connecting-IP header. "CF-Connecting-IP: A.B.C.D" 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 的配置文件上。
#/bin/sbin #变量设定 #Nginx配置文件 nginx=/etc/nginx/conf/nginx.conf #临时文件夹 mude=/home/data/shell/dat/cloudflare #日志文件 log=/home/data/shell/log/cloudflare.log #初始化 oneup4=0 oneup6=0 updata=0 if [ ! -d "$mude" ]; then sudo mkdir $mude fi #获取最新IPV4、IPV6地址 sudo wget -q <https://www.cloudflare.com/ips-v4> -O $mude/ipv4.cf > $log sudo wget -q <https://www.cloudflare.com/ips-v6> -O $mude/ipv6.cf > $log #判断是否第一次执行脚本 if [ ! -e "$mude/ipv4" ]; then oneup4=1 sudo cp $mude/ipv4.cf $mude/ipv4 > $log fi if [ ! -e "$mude/ipv6" ]; then oneup6=1 sudo cp $mude/ipv6.cf $mude/ipv6 > $log fi #更新动作 diff -q $mude/ipv4 $mude/ipv4.cf > $log if [ $? != 0 -o $oneup4 == 1 ]; then sudo sed -i 's/^/ set_real_ip_from &/g' ${mude}/ipv4 > $log sudo sed -i 's/$/; #cfipv4&/g' $mude/ipv4 > $log sudo sed -i '/#cfipv4/d' ${nginx} > $log # 此处手动更改 sudo sed -i '/#cfip4/r /home/data/shell/dat/cloudflare/ipv4' ${nginx} > $log updata=1 fi diff -q $mude/ipv6 $mude/ipv6.cf > $log if [ $? != 0 -o $oneup6 == 1 ]; then sudo sed -i 's/^/ set_real_ip_from &/g' ${mude}/ipv6 > $log sudo sed -i 's/$/; #cfipv6&/g' ${mude}/ipv6 > $log sudo sed -i '/#cfipv6/d' ${nginx} > $log # 此处手动更改 sudo sed -i '/#cfip6/r /home/data/shell/dat/cloudflare/ipv6' ${nginx} > $log updata=1 fi #文件更新后重载Nginx服务器 if [ $updata == 1 ]; then sudo /etc/init.d/nginx force-reload > $log fi #重新归档数据已备下次判断 sudo cp $mude/ipv4.cf $mude/ipv4 > $log sudo cp $mude/ipv6.cf $mude/ipv6 > $log exit 0