DDoS防护的核心逻辑其实就两件事:一是把你的源站IP藏起来,让攻击者找不到真实入口;二是在必须暴露源站的场景下,通过回源IP白名单机制,只允许可信的CDN节点或代理节点访问你的服务器。这两件事做不好,防护形同虚设。很多企业花了大价钱买高防,结果源站IP被直接探测到,攻击者绕过高防节点直接打源站,防护瞬间崩溃。所以,源站隐藏和回源IP白名单设计,是DDoS防护体系中最基础也最关键的一环。
下面我从原理、架构设计、具体实施步骤、常见坑点和最佳实践几个维度,把这件事彻底讲透。
一、为什么源站IP必须隐藏
在DDoS攻击中,攻击者的第一步永远是探测目标的真实IP地址。一旦源站IP暴露,攻击者可以直接绕过CDN、高防IP等中间层,对源站发起直连攻击。这种攻击方式有几个致命特点:第一,流量不经过任何清洗设备,直接打到你的服务器;第二,源站带宽通常远小于高防节点,很容易被打满;第三,即使你有高防,如果回源链路没有做IP白名单限制,攻击者伪造CDN节点IP也能回源到你的服务器。
所以,源站隐藏不是可选项,是必选项。隐藏的本质就是让互联网上任何直接查询都无法获取到你源站的真实IP地址。
二、源站隐藏的三种主流方案
方案一:CDN/高防回源 + 源站不做任何DNS解析
这是最基础的做法。你的域名只解析到CDN或高防IP,源站服务器不绑定任何公网域名,也不做A记录解析。攻击者通过DNS查询只能拿到CDN的IP,拿不到源站IP。但这个方案有个漏洞:如果攻击者通过历史DNS记录、邮件头、子域名泄露等方式拿到源站IP,防护就失效了。所以这个方案必须配合其他手段使用。
方案二:使用Anycast网络 + 源站仅对内网暴露
高防节点使用Anycast技术,同一个IP在全球多个节点同时广播。攻击者看到的IP是高防节点的IP,而你的源站只在内部网络中,通过内网IP与高防节点通信。这种方式下,源站IP完全不暴露在公网,安全性最高。但成本也高,通常需要与云厂商深度合作。
方案三:域名CNAME多级代理 + 源站防火墙策略
通过多级CNAME指向,让最终解析的IP始终是代理节点的IP。同时在源站防火墙上,只允许来自已知代理节点IP段的流量通过。这种方案灵活度高,适合中小企业自建防护体系。
三、回源IP白名单设计的核心逻辑
回源IP白名单的本质是:你的源站服务器只接受来自特定IP地址的请求,拒绝其他所有来源。这听起来简单,但实际操作中有大量细节需要处理。
1. 白名单IP从哪里来
如果你使用的是云厂商的CDN或高防服务,厂商通常会提供一个IP段列表,这些IP是他们所有边缘节点和回源节点的出口IP。你需要把这些IP全部加入白名单。注意,这个IP列表不是固定的,厂商会不定期更新,你必须建立定期同步机制。
2. 白名单粒度怎么定
粒度太粗,比如直接放行整个CDN厂商的IP段(可能是几万个IP),风险较大,因为一旦厂商某个节点被入侵,攻击者就能利用该节点IP回源。粒度太细,比如只放行几个固定IP,又会导致CDN节点扩容或迁移时回源失败。最佳实践是:按厂商提供的IP段做白名单,同时结合业务场景做二次限制。
3. 如何防止伪造回源IP
这是最关键的一点。攻击者可以伪造TCP连接的源IP地址,伪装成CDN节点来访问你的源站。单纯靠IP白名单无法防御这种伪造。解决方案有两个层面:
第一层:在网络层使用防火墙的连接状态检测(stateful inspection),只允许已建立的、来自白名单IP的TCP连接。大多数现代防火墙默认支持这个功能。
第二层:在应用层增加Token验证机制。CDN节点回源时携带一个加密Token,源站验证Token通过后才处理请求。这样即使攻击者伪造了IP,没有Token也无法访问。
# Nginx层面的回源IP白名单 + Token验证示例
# 1. 定义CDN回源IP白名单段
geo $cdn_ip {
default 0;
103.21.244.0/22 1;
103.22.200.0/22 1;
103.31.4.0/22 1;
# ... 更多CDN IP段
}
# 2. 验证来源IP是否在白名单中
map $cdn_ip $is_cdn {
0 "denied";
1 "allowed";
}
# 3. 验证回源Token(假设通过Header传递)
map $http_x_cdn_token $token_valid {
default 0;
"your-secret-token-here" 1;
}
server {
listen 80;
server_name origin.example.com;
# 组合验证:IP白名单 + Token
if ($is_cdn = "denied") {
return 403;
}
if ($token_valid = 0) {
return 403;
}
location / {
proxy_pass http://backend;
}
}四、源站防火墙的具体配置策略
光靠应用层的白名单不够,必须在操作系统防火墙和硬件防火墙层面同步做限制。下面以Linux iptables和云安全组为例,给出具体配置思路。
1. iptables规则示例
# 只允许CDN IP段访问80和443端口 iptables -A INPUT -p tcp --dport 80 -s 103.21.244.0/22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -s 103.22.200.0/22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -s 103.31.4.0/22 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -s 103.21.244.0/22 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -s 103.22.200.0/22 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -s 103.31.4.0/22 -j ACCEPT # 拒绝其他所有入站流量 iptables -A INPUT -p tcp --dport 80 -j DROP iptables -A INPUT -p tcp --dport 443 -j DROP # 允许本地回环和已建立连接 iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
2. 云安全组配置要点
如果你的源站在云上,安全组规则要和iptables配合。安全组层面只放通CDN IP段的80/443端口,其他端口全部关闭。同时,安全组不要对0.0.0.0/0开放任何端口,这是最基本的安全底线。
3. 特殊场景处理:健康检查和运维访问
源站做了严格白名单后,运维人员怎么访问?健康检查怎么做?建议单独开一个管理端口(比如2222),只允许公司办公网IP或跳板机IP访问,和业务流量完全隔离。健康检查可以通过CDN的主动探测功能实现,CDN节点会定期回源探测,不需要额外开放端口。
五、常见踩坑点和解决方案
坑点一:IP列表不及时更新导致回源失败
CDN厂商扩容或调整节点时,IP段会变化。如果你的白名单没有同步更新,合法的CDN回源请求会被拦截,导致用户访问异常。解决方案:写一个自动化脚本,每周拉取厂商最新IP列表,自动更新防火墙规则和Nginx配置。很多云厂商提供API接口可以获取最新IP段。
坑点二:源站IP通过其他渠道泄露
即使你做了DNS隐藏,源站IP仍可能通过以下方式泄露:网站源代码中的注释、邮件服务器的邮件头、SSL证书的历史记录、子域名的DNS记录、第三方服务的回调地址等。解决方案:定期做源站IP泄露扫描,使用工具检测自己域名关联的所有IP,发现非预期暴露的IP立即处理。
坑点三:回源链路被中间节点劫持
如果你的源站和CDN节点之间的通信走公网,中间的网络设备(比如运营商的路由器)理论上可以劫持或篡改流量。解决方案:使用专线或云厂商的内网回源通道,让回源流量走私有网络,不经过公网。如果必须走公网,启用TLS加密回源,确保链路安全。
坑点四:白名单配置过于宽松
有些运维为了省事,直接把整个云厂商的IP段(比如/8或/12)都放进去了。这样做等于没做防护。必须精确到厂商提供的具体回源IP段,通常是/22或/24级别的细分段。
六、进阶方案:多层防护架构设计
对于高安全要求的业务,建议采用以下多层架构:
第一层:DNS层面,域名只解析到高防CDN的IP,源站不做任何公网解析。
第二层:网络层面,源站防火墙只允许CDN回源IP段访问,拒绝其他一切入站。
第三层:传输层面,回源链路使用TLS加密,防止中间人攻击。
第四层:应用层面,CDN回源携带Token,源站验证Token合法性。
第五层:监控层面,实时监控源站访问日志,一旦发现非白名单IP的访问尝试,立即告警并自动封禁。
这五层叠加下来,攻击者想要绕过防护直接打到源站,难度呈指数级上升。
七、总结与建议
DDoS防护不是买一个高防产品就完事了,源站隐藏和回源IP白名单是整个防护体系的地基。地基不牢,上面建再高的楼都会塌。具体建议:第一,永远不要让源站IP直接暴露在公网DNS中;第二,白名单IP要精确、要定期更新;第三,IP白名单只是第一道锁,必须配合Token验证和链路加密;第四,建立自动化运维机制,避免人为疏忽导致防护失效;第五,定期做攻防演练和泄露扫描,验证防护体系的有效性。
做好这几点,你的DDoS防护才算真正到位。不要等到被打了才想起来补漏洞,那时候已经晚了。
