CDN + WAF 联动防护实战:隐藏源站 IP 防绕过,Nginx 只放行 CDN 回源完整教程

很多站长花了真金白银买 WAF,结果网站还是被攻破、被勒索、被挂马。问题出在哪?答案往往只有一个:源站 IP 暴露了。黑客根本不碰你的 CDN 和 WAF,直接用真实服务器 IP 发起攻击,前面那一层防护形同虚设。

本文不讲空泛理论,直接上可落地的闭环打法:用 CDN 隐藏源站 + WAF 清洗应用层攻击 + Nginx 只放行 CDN 回源 IP,三层叠加形成”打不到源站”的防护闭环。整套方案在宝塔面板和纯命令行环境都能跑,照着做即可生效。

一、为什么单独上 WAF 还是被打穿?源站暴露的三种途径

WAF 的本质是”流量代理”,它只有当你把所有访问都强制经过它时才有效。只要源站 IP 还能被直连,WAF 就等于没穿。站长最容易在以下三个地方把源站 IP 漏出去:

  • 历史 DNS 解析残留:早期没接防护时,A 记录直接指向源站,后来虽然改了 CDN,但历史记录在各大被动 DNS 库里长期留存,搜索引擎和威胁情报平台一查便知。
  • 子域名/资源直连:主站走了 CDN,但 img.api.mail. 等子域名或对象存储回源地址仍直连源站,被逐一爆破。
  • 证书透明度日志反查:只要源站申请过 SSL 证书,crt.sh 等证书透明度(CT)日志就会记录该域名与 IP 的关联,任何人都能反查出真实 IP。

实战自检:用下面这条命令,拿你的域名去 crt.sh 反查历史证书,看暴露了哪些 IP;再用这些 IP 直接 curl 源站 80/443 端口,如果还能返回网站内容,说明源站已裸奔。

# 反查域名历史证书(含可能暴露的源站 IP 线索)
curl -s "https://crt.sh/?q=%25example.com&output=json" | python3 -c "import sys,json;d=json.load(sys.stdin);[print(x['name_value'],x['ip_addresses']) for x in d]"

# 用疑似源站 IP 直连测试(应返回拒绝/超时,而非网页)
curl -s -I --resolve example.com:443:1.2.3.4 https://example.com/

二、CDN + WAF 联动架构:流量必须先过清洗层

正确的联动逻辑是“用户 → CDN 边缘节点 → WAF 应用层清洗 → 源站”。CDN 负责隐藏源站 IP 并做传输层加速与 L3/L4 抗 DDoS,WAF 负责在应用层拦截 SQL 注入、XSS、恶意爬虫和扫描器。真正到达源站的流量,理论上 100% 来自 CDN 的回源节点。

速度网络这类同时提供 CDN 加速与高防 WAF 的服务,其价值正在于把源站 IP 藏在边缘节点之后:攻击者只能看到速度网络的 Anycast IP,永远摸不到你的真实服务器。但前提是——你必须在源站侧把”非 CDN 回源”的流量全部掐断,否则这套架构就被打回原形。

联动架构的关键参数,是 CDN 厂商公布的回源 IP 段(CIDR 列表)。只有这些 IP 段过来的请求才是合法回源,其余一律视为绕过攻击,直接丢弃。下面进入最关键的实战环节。

三、Nginx 实战:只允许 CDN 回源,封死一切直连

核心思路:在 Nginx 层用 allow/denygeo 模块,建立”白名单即 CDN 回源 IP 段,其余全部拒绝”的规则。下面给出命令行与宝塔面板两种落地方式。

方式 1:纯 Nginx 命令行(geo 模块,推荐)

geo 模块比逐个 allow/deny 更优雅,便于维护成百上千条 CIDR。先在 http 段定义白名单,再在 server 段统一拦截。

# /etc/nginx/conf.d/cdn-allowlist.conf
geo $cdn_allow {
    default        0;          # 默认不允许
    110.242.0.0/16 1;          # 示例:替换为速度网络/你所用 CDN 的回源段
    180.76.0.0/16  1;          # 示例:同上,务必以厂商官方公布为准
    2408:4000::/32 1;          # IPv6 回源段(如有)
}

# 站点配置 /etc/nginx/sites-enabled/example.com
server {
    listen 443 ssl;
    server_name example.com;

    # 仅放行 CDN 回源,其余直连一律 444 静默断开
    if ($cdn_allow = 0) {
        return 444;
    }

    location / {
        proxy_pass http://127.0.0.1:8080;
        # ... 其余反代/静态配置
    }
}

return 444 是 Nginx 特有的”不返回任何响应直接断连”,比 403 更省资源,也不会给攻击者任何报错线索。修改后检查并重载:

nginx -t && systemctl reload nginx

方式 2:宝塔面板可视化操作

  1. 登录宝塔面板 → 左侧网站 → 选中站点 → 设置配置文件
  2. server { } 块最上方加入上面的 if ($cdn_allow = 0) { return 444; } 逻辑;回源 IP 段建议单独存成 /www/server/nginx/conf/cdn-allowlist.confinclude 引入,方便批量更新。
  3. 点击保存,宝塔会自动检测语法;或在终端执行 nginx -t 验证。
  4. 如需在面板里做 IP 黑白名单,可走 安全禁止访问 面板,但白名单放行仍建议走上面的 Nginx 配置,粒度更细。

验证:直连源站必须失败

用源站真实 IP 直接请求,正确配置下应被 444 静默断开或 403 拒绝,而通过域名(经 CDN)访问则正常。

# 直连源站 IP(预期:连接被拒/超时,拿不到网页)
curl -s -o /dev/null -w "%{http_code}
" --resolve example.com:443:1.2.3.4 https://example.com/

# 经域名正常访问(预期:200)
curl -s -o /dev/null -w "%{http_code}
" https://example.com/

四、WAF 规则加固:在后台开启拦截,别用”观察”模式

堵住直连后,还要在 WAF 层拦截应用层攻击。如果你用速度网络这类集成 WAF 的后台,直接在”Web 防护 → 规则引擎”开启注入防御、跨站脚本防御、敏感文件扫描三类基础规则,并务必设为拦截模式——观察模式只记录不阻断,等于裸奔。语义级的注入与跨站攻击,交给专业 WAF 处理最稳妥。

若想在 Nginx 侧补充一道应用层防线(作为 WAF 之外的纵深防御),可加一段规则拦截对敏感配置文件的探测,挡掉最泛滥的备份文件与后台路径扫描:

# 在 server 段加入:拦截对备份文件与管理入口的探测
location ~* "(wp-config\.bak|phpmyadmin|/\.git/|backup\.zip)" {
    return 403;
}

注意:Nginx 正则规则只是补充,精细的语义级防护仍要交给专业 WAF。规则上线前务必在测试环境验证,避免误杀正常请求(比如带参数的搜索接口)。

总结:防护闭环的三条铁律

CDN + WAF 联动防护能不能真正生效,取决于三条铁律:第一,源站 IP 必须彻底隐藏,定期用 crt.sh 和直连测试复查暴露面;第二,源站 Nginx 必须只放行 CDN 回源段return 444 掐断一切直连;第三,WAF 规则要开拦截而非观察,并与 Nginx 正则形成纵深。

把这三步做扎实,攻击者就再也无法绕过防护直击源站。如果你的站点目前还在裸奔、源站 IP 随手可查,建议尽快接入速度网络的 CDN + WAF 联动防护,隐藏源站的同时把应用层攻击挡在边缘——安全不是买个产品就完事,而是把”打不到你”变成架构的默认状态。

给TA打赏
共{{data.count}}人
人已打赏
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
在线客服
在线客服
热线电话
QQ客服
电子邮箱
suduwangluo