配合 CDN(如 Cloudflare)建立边缘防护屏障,是目前企业级 Web 安全架构中最核心的防线之一。它的本质是将服务器彻底隐匿于公网之中,让 CDN 变成服务器唯一的 “肉盾” 和 “传话筒”

在传统架构中,服务器的 80/443 端口直接暴露给全世界,任何人都可以直接连接。而在 “CDN + 边缘防火墙” 的纵深防御架构中,我们要切断所有直连路径。

以下是这一方案的底层逻辑、潜在风险以及绝对安全的配置全流程:


# 一、 为什么要建立边缘防护?(源站 IP 泄露的致命风险)

当你把域名的 DNS 解析切换到 Cloudflare 并开启 “小黄云”(Proxy 代理)时,公网用户在解析你的域名时,只能看到 Cloudflare 的节点 IP。

然而,黑客可以通过各种手段绕过域名,直接获取你的 VPS 真实 IP(源站 IP)

  1. 历史 DNS 记录: 扫描工具(如 SecurityTrails)记录了你启用 CDN 之前该域名绑定过的真实 IP。
  2. 全网盲扫: 黑客使用超高速扫描工具(如 ZMap、Masscan)每天对全网 IPv4 进行 80/443 端口盲扫。如果你的服务器直接回应了特定的 Web 证书或网页内容,其 IP 就会被记录到 Censys 或 Shodan 等搜索引擎中。
  3. 出站流量泄漏: 如果你的服务器主动向外发送邮件、发起 API 请求或下载文件,且没有配置反向代理或 NAT,对方就能从接收到的数据包中直接看到你的源站 IP。

一旦源站 IP 泄露,黑客就可以绕过 CDN 所有的 WAF 防御规则、频率限制和高防五秒盾,直接对你的 VPS 实施高强度的 DDoS 攻击、漏洞扫描或暴力破解。


# 二、 核心防御机制:联动 UFW 锁死源站

为了消除上述风险,必须在服务器内部配置防火墙规则:只允许来自 CDN 节点的 IP 访问 Web 端口,拒绝其他一切 IP。

# 1. 获取 CDN 官方 IP 段

主流 CDN 厂商都会公开自己的节点 IP 范围,并且定期更新。例如:

  • Cloudflare IPv4 列表: https://www.cloudflare.com/ips-v4
  • Cloudflare IPv6 列表: https://www.cloudflare.com/ips-v6

# 2. UFW 动态白名单配置脚本

由于 CDN 的 IP 段数量较多,手动添加非常低效。我们可以编写一个自动化 Shell 脚本,一键下载最新的 IP 段并导入 UFW。

在服务器上创建脚本 /root/update_cdn_ipset.sh

#!/bin/bash
echo "=== 开始拉取 CDN IP: $(date) ==="
echo "正在初始化 ipset 集合..."
# 创建 IPv4 和 IPv6 集合 (如果已存在则清空旧数据,实现无缝更新)
sudo ipset create cf_v4 hash:net 2>/dev/null || sudo ipset flush cf_v4
sudo ipset create cf_v6 hash:net family inet6 2>/dev/null || sudo ipset flush cf_v6
echo "正在极速拉取 CloudFront & Cloudflare IP..."
# ==================== IPv4 加载 ====================
# 1. 加载 CloudFront IPv4
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq -r '.prefixes[] | select(.service=="CLOUDFRONT") | .ip_prefix' | while read ip; do
    if [ -n "$ip" ] && [ "$ip" != "null" ]; then
        sudo ipset add cf_v4 $ip
    fi
done
# 2. 加载 Cloudflare IPv4
curl -s https://www.cloudflare.com/ips-v4 | while read ip; do
    if [ -n "$ip" ]; then
        sudo ipset add cf_v4 $ip
    fi
done
# ==================== IPv6 加载 ====================
# 3. 加载 CloudFront IPv6
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq -r '.ipv6_prefixes[] | select(.service=="CLOUDFRONT") | .ipv6_prefix' | while read ip; do
    if [ -n "$ip" ] && [ "$ip" != "null" ]; then
        sudo ipset add cf_v6 $ip
    fi
done
# 4. 加载 Cloudflare IPv6
curl -s https://www.cloudflare.com/ips-v6 | while read ip; do
    if [ -n "$ip" ]; then
        sudo ipset add cf_v6 $ip
    fi
done
echo "所有 CDN 的 IPv4 和 IPv6 已瞬间加载至内存!"
# 将内存中的集合导出到系统配置文件中
sudo ipset save > /etc/ipset.conf
echo "=== 更新完成: $(date) ==="
# 安装 ipset jq 解析工具
sudo apt update
sudo apt install ipset jq -y

赋予执行权限并运行:

chmod +x /root/update_cdn_ipset.sh
sudo /root/update_cdn_ipset.sh

# 3. 让 UFW 读取这个哈希表 (核心)

现在内存里已经有了一份完整的 CDN IP 名单(名为 cf_v4)。我们需要告诉 UFW:如果 IP 在这个名单里,就允许访问 25566 和 8443 端口。

修改 UFW 的底层配置文件:

sudo nano /etc/ufw/before.rules

找到 # End required lines 这一行,在它的正下方,添加这两行指令:

# End required lines
# 允许 ipset 集合中的 IP 访问特定端口
-A ufw-before-input -m set --match-set cf_v4 src -p tcp --dport 25566 -j ACCEPT
-A ufw-before-input -m set --match-set cf_v4 src -p tcp --dport 8443 -j ACCEPT
# === 新增下面这两行,放行 Web 端口 ===
-A ufw-before-input -m set --match-set cf_v4 src -p tcp --dport 80 -j ACCEPT
-A ufw-before-input -m set --match-set cf_v4 src -p tcp --dport 443 -j ACCEPT
sudo nano /etc/ufw/before6.rules
# End required lines
# 允许 ipset 集合中的 IPv6 访问特定端口
-A ufw6-before-input -m set --match-set cf_v6 src -p tcp --dport 25566 -j ACCEPT
-A ufw6-before-input -m set --match-set cf_v6 src -p tcp --dport 8443 -j ACCEPT
# === 新增下面这两行,放行 Web 端口 ===
-A ufw6-before-input -m set --match-set cf_v6 src -p tcp --dport 80 -j ACCEPT
-A ufw6-before-input -m set --match-set cf_v6 src -p tcp --dport 443 -j ACCEPT

最后,重新加载 UFW 让所有的内核级规则生效:

sudo ufw reload

# 4. 恢复访客的 “真实 IP”(⚠️Web 建站必做核心坑位)

当你的网站套了 Cloudflare 后,公网用户的请求是先发给 Cloudflare,再由 Cloudflare 转发给你的 Nginx/Apache。

这会带来一个致命问题: 你的 Nginx 访问日志里,所有访客的 IP 全变成了 Cloudflare 的节点 IP!
如果这个时候有人恶意爆破你的网站后台,你的 Fail2ban 会把 Cloudflare 的节点给封印掉,导致整个网站彻底断网。

解决方法:让 Nginx 认出 Cloudflare 请求头里的真实 IP。

一段极速命令,它会自动下载 Cloudflare 的 IP 段,并生成一个 Nginx 配置文件:

# 1. 创建 Nginx 的 Cloudflare 真实 IP 配置文件
echo "# 自动生成的 Cloudflare 真实 IP 配置" | sudo tee /etc/nginx/conf.d/cloudflare_real_ip.conf
# 2. 写入 IPv4 规则
curl -s https://www.cloudflare.com/ips-v4 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' | sudo tee -a /etc/nginx/conf.d/cloudflare_real_ip.conf
# 3. 写入 IPv6 规则
curl -s https://www.cloudflare.com/ips-v6 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' | sudo tee -a /etc/nginx/conf.d/cloudflare_real_ip.conf
# 4. 告诉 Nginx 使用哪个请求头来获取真实 IP
echo "real_ip_header CF-Connecting-IP;" | sudo tee -a /etc/nginx/conf.d/cloudflare_real_ip.conf
# 5. 测试 Nginx 语法并重启
sudo nginx -t && sudo systemctl reload nginx

执行完这段命令后,你去查看网站的访问日志(如 tail -f /var/log/nginx/access.log),就会发现访客的真实 IP(如来自北京、纽约的 IP)神奇地恢复了!你的 Fail2ban 也能准确地拉黑真正的坏人了。

# 4. 解决重启丢失问题:

ipset 运行在内存中,一旦 VPS 重启就会清空。如果开机时 UFW 找不到 cf_v4 这个集合,UFW 防火墙会直接启动失败,导致服务器断网!
我们要创建一个系统服务,告诉 Linux:“每次开机时,在启动 UFW 之前,先把 /etc/ipset.conf 里的内容塞进内存。”
创建一个新的服务文件:

sudo nano /etc/systemd/system/ipset-custom.service

将下面这段配置完整粘贴进去:

[Unit]
Description=Custom IPSET Restore Service
# ⚠️ 核心点:强制要求在 UFW 和网络服务启动之前运行!
Before=ufw.service network.target
# 只有当配置文件存在且不为空时才执行
ConditionFileNotEmpty=/etc/ipset.conf
[Service]
Type=oneshot
RemainAfterExit=yes
# 启动时执行的命令:从文件中恢复 ipset 表
ExecStart=/sbin/ipset restore -! -f /etc/ipset.conf
[Install]
WantedBy=multi-user.target

激活该服务并恢复 UFW
告诉系统重新加载服务列表,并把我们刚写的服务设为开机自启:

# 1. 重载 Systemd 守护进程
sudo systemctl daemon-reload
# 2. 设置我们的 ipset 服务开机自启
sudo systemctl enable ipset-custom.service
# 3. 立刻启动它测试一下(如果没有报错说明完美)
sudo systemctl start ipset-custom.service
sudo systemctl status ipset-custom.service

# 5. 配置自动化定时任务:

让服务器在夜深人静的时候,自动去拉取最新 IP 并更新防火墙。
输入以下命令编辑 root 用户的定时任务列表:

sudo crontab -e

(如果是第一次运行,系统可能会让你选择编辑器,输入 1 选择 nano 即可。)

在打开的文件最末尾,新起一行,粘贴以下代码:

22 23 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" >> /root/.acme.sh/acme_cron.log 2>&1
0 4 */3 * * /root/cdn/update_cdn_ipset.sh >> /root/cdn/cdn_update.log 2>&1

# 三、 进阶防护:Authenticated Origin Pulls(源站基础认证)

仅仅限制 IP 段其实还有一个极小概率的盲区:如果黑客同样使用 Cloudflare,并且在他的 Cloudflare 控制台里将他的恶意域名解析指向你的 VPS 真实 IP,由于他的请求同样来自于 Cloudflare 的官方节点 IP,你的 UFW 防火墙会误将其放行。

为了堵住这个漏洞,我们需要开启 Authenticated Origin Pulls(源站认证拉取)

# 原理:

它基于双向 TLS 认证(mTLS)。当 Cloudflare 节点向你的源站(Nginx)转发请求时,必须向 Nginx 出示一张由 Cloudflare 官方签发的客户端证书。Nginx 验证证书无误后才提供服务。

# 配置步骤:

  1. 下载 Cloudflare 官方客户端证书:
    在 VPS 上下载 Cloudflare 的公共证书并保存到安全目录:
sudo mkdir -p /etc/nginx/certs
sudo curl -s https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem -o /etc/nginx/certs/cloudflare.crt
  1. 修改 Nginx 站点配置文件:
    在你的 Nginx 虚拟主机配置( server 块内)中,加入以下两行:
server {
    listen 443 ssl;
    server_name yourdomain.com;
    # 开启源站认证拉取
    ssl_client_certificate /etc/nginx/certs/cloudflare.crt;
    ssl_verify_client on;
    # ... 其他正常的 SSL 证书和反向代理配置 ...
}
  1. 在 Cloudflare 后台开启开关:
    登录 Cloudflare 控制台,进入 SSL/TLS -> Authenticated Origin Pulls,将开关切换为 On
  2. 重启 Nginx:
sudo nginx -t && sudo systemctl restart nginx

做了这一步之后,即使有人能伪造 IP 或者通过其他 Cloudflare 域名盗刷你的源站,由于他们没有合法的 mTLS 客户端证书,Nginx 会直接返回 400 Bad Request 拒绝服务。