Nignx获取Cloudflare的真实IP

#Cloudflare #Zerotrust #Nginx

Table of Contents

网站流量通过 Cloudflare 网络路由时,Cloudflare 作为反向代理来处理用户请求。Cloudflare 能够更有效地路由数据包并缓存静态资源(如图像、JavaScript、CSS 等),从而加快页面加载时间。然而由于Cloudflare充当中间层,原始服务器在响应请求并记录日志时通常只能看到Cloudflare的IP地址,而非访问者的真实IP地址。

为了获取真实IP,需要对Nginx进行一些配置,

默认情况下会记录 Cloudflare IP 地址。原始访问者 IP 地址出现在附加的 HTTP 标头中,称为 CF-Connecting-IP

下面这个图很好的说明了,是否经过Cloudflare,以及是否设置远程IP 头的后端获取IP结果。

该图说明了使用和不使用 Cloudflare 处理 IP 地址的不同方式。

CF-Connecting-IP OR X-Forwarded-For

XFF X-forward-for 这个头可能大家也不陌生,但是在 Cloudflare 接入后,CF-Connecting-IPX-Forwarded-For 两个 HTTP 头字段都可以用于识别原始客户端的 IP 地址。

对于选择哪个IP作为后端的真实IP 需要对这两个头进行对比。

属性CF-Connecting-IPX-Forwarded-For
头字段的设置由 Cloudflare 设置由每一层代理服务器设置或追加
包含的 IP 地址单一的原始客户端 IP 地址一个包含原始 IP 和代理链的 IP 地址列表
可信度高,Cloudflare 独有,不易伪造低,易被伪造或修改,依赖于所有代理的正确设置
适用场景适用于经过 Cloudflare 的流量适用于多层代理时,且所有代理都可信

### 推荐使用哪个?

综上在使用 Cloudflare 的情况下,推荐使用 CF-Connecting-IP 来获取客户端的真实 IP 地址

  1. 唯一性和简洁性CF-Connecting-IP 总是表示原始客户端的单一 IP 地址,简单直接,不会有多个 IP 地址链的问题
  2. 可信度高:由于 CF-Connecting-IP 是由 Cloudflare 直接提供的,它更可信,且不会被客户端伪造或修改。

正文

前面知道了 CF 传递的特有的 CF-Connecting-IP 头之后,我们就可以修改 Nginx 配置。让它把 CF-Connecting-IP 这个头包含的 IP 作为用户的真实IP。

下面是具体的配置过程

配置生成

我们编写脚本来进行配置文件的生成, 具体的逻辑是curl获取cloudflare 的边缘节点的IP列表。之后使用 set_real_ip_from 的配置,来信任这些源IP,来避免IP伪造的问题。

#!/bin/bash

CLOUDFLARE_FILE_PATH=/etc/nginx/conf.d/cloudflare.conf

echo "#Cloudflare" > $CLOUDFLARE_FILE_PATH;
echo "" >> $CLOUDFLARE_FILE_PATH;

echo "# - IPv4" >> $CLOUDFLARE_FILE_PATH;
for i in `curl -s -L https://www.cloudflare.com/ips-v4`; do
    echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH;
done

echo "" >> $CLOUDFLARE_FILE_PATH;
echo "# - IPv6" >> $CLOUDFLARE_FILE_PATH;
for i in `curl -s -L https://www.cloudflare.com/ips-v6`; do
    echo "set_real_ip_from $i;" >> $CLOUDFLARE_FILE_PATH;
done

echo "" >> $CLOUDFLARE_FILE_PATH;
echo "real_ip_header CF-Connecting-IP;" >> $CLOUDFLARE_FILE_PATH;

#test configuration and reload nginx
nginx -t && nginx -s reload

在我们运行这个脚本之后,会在 /etc/nginx/conf.d/cloudflare.conf 生成下面的配置。信任所有的cloudflare的边缘IP,并且设置 realip 为 CF-Connecting-IP 的头所标注的IP。

# 设置Real IP头
#Cloudflare ip addresses

# - IPv4
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

# - IPv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;

# 设置使用的头字段
real_ip_header CF-Connecting-IP;

更新 Nginx 配置

  1. 打开 Nginx 配置文件

    Nginx的主配置文件通常位于 /etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf,根据您的环境找到并编辑该文件。

  2. 添加 Cloudflare 真实IP头支持

    http 块或 server 块中,添加以下配置:

    include /etc/nginx/conf.d/cloudflare.conf;
    
  3. 保存并重启 Nginx

    保存配置文件,然后通过以下命令重启Nginx服务:

    sudo systemctl restart nginx
    

验证真实 IP 获取

查看访问日志

默认情况下,Nginx将访问日志保存在/var/log/nginx/access.log。可以使用以下命令查看日志:

tail -f /var/log/nginx/access.log

通过配置Nginx来正确识别Cloudflare传递的真实IP地址,在使用安全上可以有较大的提升。

而且应该是使用docker来部署的wp获取IP这种方式也是更加推荐的。不需要对容器内的内容进行修改。