【CF 防护 01】Cloudflare + VPS 防 DDoS 实战:DNS 橙色云、WAF、速率限制与源站只放行 Cloudflare IP 完整配置

手把手教你用 Cloudflare 给 VPS 建站做防 DDoS 与攻击防护:开启 DNS 代理(橙色云)、设置 SSL/TLS Full Strict、用 nginx 只允许 Cloudflare 回源 IP、配置 WAF 规则与速率限制、隐藏真实 IP,附真实可执行命令。

延伸阅读

更多相关攻略推荐:2026 独立站防 DDoS 与防爬:Cloudflare+WAF 【发行版选型 10】如何选择合适的 Linux 发行版VPS 装什么系统好?Ubuntu、Debian、CentOS 大白【安全基线 01】加固 SSH 与 Fail2ban【API 中转 02】ChatGPT/Claude API 中转 V

为什么一台 VPS 需要 Cloudflare 才敢对外建站

把网站直接架在一台 VPS 上、把域名 A 记录指向服务器真实 IP,是当前被攻击得最惨的建站方式。攻击者有太多手段拿到你的源站 IP:证书透明度日志(ct logs)、历史 DNS 记录、邮件头、甚至是网页里写死的图片或接口地址。一旦真实 IP 暴露,对方就可以绕过 CDN 直接用流量打你的 80/443 端口,Cloudflare 的 DDoS 防护在这里完全失效。

Cloudflare 的免费套餐就提供不限量(unmetered)的 L3/L4/L7 DDoS 缓解,依托 209+ Tbps 的网络容量,官方曾成功缓解超过 7100 万请求/秒 的攻击。再加上 WAF、Bot Fight Mode、速率限制,几乎把小站的安全水位从"裸奔"拉到"行业平均线以上"。本文给你一套从接入到源站锁死的完整配置,全部命令可直接复制执行。

第一步:接入 Cloudflare 并开启 DNS 代理(橙色云)

把域名 NS 改成 Cloudflare 提供的两枚 NS,等待全球生效(用 dig NS 你的域名 验证)。然后在 DNS 面板里,对需要保护的记录开启代理——也就是那朵橙色云

类型   名称        值             是否代理
A      www        203.0.113.10   开启(橙色云)
A      @          203.0.113.10   开启(橙色云)
CNAME  static     cdn.example.com 开启(橙色云)
A      origin     203.0.113.10   关闭(灰色云,仅内网/加白使用)

关键原则:所有对外提供 Web 服务的记录必须开橙色云,邮件(MX)保持灰色云(邮件不走代理),源站直连域名绝不要公开。橙色云开启后,访客先到 Cloudflare 边缘节点,再由 Cloudflare 回源到你的 VPS。

第二步:SSL/TLS 模式为什么必须是 Full (strict)

Cloudflare 的 SSL/TLS 有四种模式,最坑的是 Flexible:浏览器到 Cloudflare 是加密的,但 Cloudflare 回源用的是明文 HTTP。如果你的网站或程序又强制 HTTPS 跳转,就会出现著名的"重定向次数过多"死循环

  • Off:全程不加密,已淘汰。
  • Flexible:浏览器→CF 加密,CF→源站明文。会导致重定向循环,严禁使用
  • Full:两端都加密,但源站证书可以是自签/无效的。
  • Full (strict):两端都加密,且源站必须持有有效、可信的证书。这是唯一推荐模式。

最省心的做法是在 Cloudflare 控制台 SSL/TLS → Origin Server 里申请一张Cloudflare Origin CA 证书(最长 15 年、免续费、只被 Cloudflare 信任),装到 nginx 上,然后把模式拨到 Full (strict)。有 Let's Encrypt 也行。装好后在源站自测:

curl -vI https://你的域名 --resolve 你的域名:443:203.0.113.10

能直接返回 200 说明源站证书有效,再切模式就不会出现 526 错误。

第三步:源站隐藏——只放行 Cloudflare 回源 IP

这是整套方案里最重要的一步。橙色云只挡"走 DNS 来的流量",但攻击者如果拿到了真实 IP,会直接打 IP。解决办法:在源站只接受 Cloudflare 的 IP 段,其余一律拒绝。Cloudflare 官方维护的 IP 段如下(以 cloudflare.com/ips 为准)。

方案 A:nginx 只允许 Cloudflare 回源

把 Cloudflare 的 IP 段写进独立文件 /etc/nginx/cloudflare_allow.conf

# /etc/nginx/cloudflare_allow.conf  (Cloudflare IPv4 + IPv6)
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;
allow 2400:cb00::/32;
allow 2606:4700::/32;
allow 2803:f800::/32;
allow 2405:b500::/32;
allow 2405:8100::/32;
allow 2a06:98c0::/29;
allow 2c0f:f248::/32;
deny all;

在站点配置里 include 它,并注意顺序——allow 在前,deny all 在后

server {
    listen 80;
    listen 443 ssl http2;
    server_name example.com www.example.com;

    include /etc/nginx/cloudflare_allow.conf;

    ssl_certificate     /etc/nginx/certs/origin.pem;
    ssl_certificate_key /etc/nginx/certs/origin.key;

    root /var/www/example.com;
    index index.html index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}
nginx -t && systemctl reload nginx

方案 B:系统防火墙(ufw)只放行 Cloudflare IP(更彻底)

推荐在防火墙层直接拦,这样连 nginx 都省了处理非法请求。用脚本循环拉取官方列表:

for net in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
  ufw allow proto tcp from $net to any port 80,443 comment 'Cloudflare'
done
ufw reload

然后务必删掉之前遗留的"Anywhere"放行规则:

ufw status numbered
# 找到 80/tcp ALLOW Anywhere 那条,记下序号后删除
ufw delete 序号

从任意一台非 VPS 的机器验证,超时即成功(说明源站不再搭理陌生人):

curl -m 5 http://你的真实IP/

方案 C:iptables 直写(无 ufw 时)

iptables -N CLOUDFLARE 2>/dev/null
for net in $(curl -s https://www.cloudflare.com/ips-v4); do
  iptables -A CLOUDFLARE -s $net -p tcp -m multiport --dports 80,443 -j ACCEPT
done
iptables -A CLOUDFLARE -p tcp -m multiport --dports 80,443 -j DROP
iptables -I INPUT -j CLOUDFLARE

三处警告:① 千万不要把 SSH 端口也限制成只允许 Cloudflare,否则会把自己锁死,SSH 永远不走代理;② Cloudflare IP 段极少变动,但建议半年复查一次,否则某天会出现 521 错误(源站拒绝连接);③ 邮件别和 Web 放同一台 VPS,否则邮件头会泄露源站 IP。

第四步:恢复真实访客 IP(real_ip)

开代理后,nginx 日志里看到的全是 Cloudflare 节点 IP,这会导致 fail2ban 误封整个节点、速率限制把正常用户一起限掉。Cloudflare 在每次请求里通过 CF-Connecting-IP 头带来真实访客 IP,nginx 的 realip 模块可以还原它——但只在连接确实来自 Cloudflare 时才信任该头,否则任何人都能伪造。

# /etc/nginx/conf.d/cloudflare-realip.conf
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;
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 -t && systemctl reload nginx
tail -f /var/log/nginx/access.log   # 应看到真实、分散的访客 IP

一个常见坑:在 Cloudflare 后面用 nginx 速率限制时,限流 key 必须基于真实 IP。先还原 real_ip,再用 $binary_remote_addr 作为 key,否则所有用户会被归到一个桶里、几秒就触发全站限流。完整限流配置:

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    server {
        limit_req zone=one burst=20 nodelay;
        location /api/ {
            limit_req zone=one burst=5 nodelay;
        }
    }
}

第五步:WAF 规则与速率限制

Cloudflare 的 WAF 在所有套餐都可用。免费版自带Cloudflare Free Managed Ruleset(覆盖 SQL 注入、XSS、高危漏洞利用类),但不含 OWASP 全规则集,且自定义规则数量有限;Pro($20/月)开放 OWASP + 托管规则集 + 5 条自定义规则;Business($200/月)给到 20 条。即便免费版,自定义规则也够做几件实事:

  • /wp-login.php/admin 来自陌生国家的流量做挑战(challenge)。
  • 封禁明文探测 /.env/wp-config.php 等不该公开路径的请求。
  • 对只发攻击流量的 ASN/网络做挑战。

仪表盘路径:Security → WAF → Custom rules,表达式示例(Challenge 登录爆破):

(http.request.uri.path contains "/wp-login.php") and (cf.threat_score gt 10)

速率限制(Rate Limiting rules)建议在登录接口上加一条:同一客户端每分钟只允许个位数请求,专治爆破和滥用爬虫。免费版的速率限制额度随年份有调整,以你控制台 Security 区显示为准。

第六步:Cloudflare 仪表盘里还要开的几把锁

  • Bot Fight Mode(免费,一键开):挑战已知爬虫特征流量,挡掉扫描器和凭证填充。开启后留意日志,避免误伤正常 API/监控。
  • Security Level:攻击高峰期把怀疑阈值调高,平时调回中。
  • Email Address Obfuscation:把页面里公开的邮箱打乱,防爬虫收集。
  • Turnstile:Cloudflare 免费的 reCAPTCHA 替代,保护表单又不影响体验。
  • IP Access rules:手动封单个 IP/网段/C ASN。

排错要点:521=Cloudflare 连不上源站(源站宕机/防火墙挡了 CF IP/Web 没起);526=源站证书无效(模式别用 Flexible,确认装了有效证书);重定向过多=Flexible + 强制 HTTPS 冲突,改 Full(strict)。

实战推荐:适合挂 Cloudflare 的 VPS 服务商

源站稳不稳,取决于 VPS 本身。下面四家都在 Cloudflare 防护体系下表现可靠,且都支持 KVM、独立 IPv4、支付宝/信用卡等支付方式:

  • RackNerd:主打低价年付 KVM,2026 年 LA DC03 机房年付低至约 $10.28 起(1 核/1G/24G SSD/2-4TB 流量/1Gbps),支持 SolusVM、支付宝、自定义 ISO,适合预算敏感型建站。
  • BandwagonHost(搬瓦工)CN2 GIA 优质线路代表,E-Commerce 套餐 $49.99/季度起(1 核/1G/20G SSD/1TB/1Gbps),支持多机房免费切换、自动备份快照,国内访问体验好。
  • DMITCN2 GIA "毕业线路",1 核/1G/10G/1TB 年付约 $49.9,网络质量顶级,适合同时面向全球与中国的高价值站点。
  • Vultr:按小时计费、可随意换 IP、支持支付宝/微信,高频(High Frequency)套餐 3GHz+ CPU + NVMe,最低约 $3.5/月起,全球 16+ 机房,灵活性最高。

选型建议:纯海外用户选 RackNerd 够用;需要做中国优化选 Bandwagon 或 DMITCN2 GIA;要随时换 IP、按量计费选 Vultr。无论哪家,配上本文的 Cloudflare 源站锁死方案,安全性都上一个台阶。

完整加固流程复盘

把以上步骤串成一条可执行清单:① 改 NS 接入 Cloudflare,Web 记录开橙色云;② 源站装有效证书,SSL/TLS 拨到 Full (strict);③ 防火墙或 nginx 层只放行 Cloudflare IP 段、deny all;④ 配置 real_ip 还原真实访客 IP;⑤ 开启 Bot Fight Mode、写好 WAF 自定义规则与登录限流;⑥ 用外部机器 curl 真实 IP 验证超时、tail 日志确认真实 IP 回归。六步做完,你的 VPS 才算真正躲在 Cloudflare 身后,真实 IP 暴露面降到最低,DDoS 与常见 Web 攻击基本被挡在边缘之外。

💡 延伸阅读:关于架构与基础设施的更多深潜指南,请前往 VPS 主题导读中心 (Hub) 获取全盘策略。