域名被DNS泛解析攻击怎么办?解析层防护实战

很多站长遇到过这种情况:服务器本身好好的,用 IP 直接访问一切正常,但用域名就是打不开、解析超时。这时候不一定是服务器被打,而是域名解析层被打瘫了。DNS 攻击的特点是流量看着不大,杀伤力却足以让整个站点”消失”。本文用 8 个问答讲清 DNS Flood 与泛解析攻击的区别、如何判断故障出在解析层、以及权威 DNS 与源站各自该怎么加固。

Q:DNS Flood 和泛解析攻击有什么区别?

两者都发生在解析层,但攻击对象和放大方式不一样。

DNS Flood 是直接向你的权威 DNS 服务器灌海量查询请求,其中大量是随机域名或不存在的域名(NXDOMAIN)。DNS 服务器要逐个查表、逐条应答,CPU、带宽、并发连接被耗尽,正常用户的解析请求就排不上队。结果是:网站源站没被攻击,但全世界都打不开你的域名。

泛解析攻击则利用了配置缺陷。如果你的域名开启了泛解析(*.example.com 全部指向同一个 IP),攻击者可以随机生成海量子域名(a1、a2、a3……)去查询和访问。不存在的子域名也要走一遍完整的解析流程,查询压力被成倍放大;更麻烦的是,如果泛解析指向源站 IP,这些随机子域名还会直接命中源站,等于绕过了所有前端防护。

一句话区分:DNS Flood 打的是”解析服务”本身,泛解析攻击是”配置漏洞 + 查询放大”,还能顺带把源站暴露出去。

Q:怎么判断是解析层被打,还是源站被打?

看三个现象就能区分:

  • 解析层被打:域名解析超时或失败,但用源站 IP 直接访问正常;换不同公共 DNS 测试结果不一致;网站前台表现为”找不到服务器”而不是 502/超时。
  • 源站被打:解析正常(能 dig 出 IP),但请求返回 502、504 或长时间挂起,服务器负载、带宽明显异常。

用下面两条命令交叉验证,一条查自己的权威 NS,一条查公共 DNS:

dig @你的NS域名 example.com +short
dig @223.5.5.5 example.com +short

如果公共 DNS 能解析、你的权威 NS 超时,问题就出在权威 DNS 侧。再看权威 DNS 的查询量曲线:BIND 用 rndc stats 生成的统计文件看 QUERY 计数,托管云解析则在控制台看解析量/QPS 监控。

Q:泛解析为什么会成为攻击入口?怎么自查?

泛解析的初衷是方便:新开子域名不用逐条加记录。但代价是所有不存在的子域名都返回一个有效 IP,等于给攻击者开了后门——随机子域名查询要消耗解析资源,如果指向源站,还会让源站收到大量无意义请求,甚至被用于黑帽 SEO 泛解析垃圾站。

自查很简单,随便造一个不存在的子域名查一下:

dig @8.8.8.8 random9x8z7q.example.com +short
# 有 IP 返回 = 开启了泛解析
rndc reload   # 改完记录后重载

处理原则:没有业务需求就直接删掉 *.example.com 这条 A 记录;如果是多租户的 SaaS 业务必须保留,也要在源站配一个兜底的 default server 块把无效子域名拦掉,而不是让它进主站逻辑。

Q:域名解析正在被打,第一步做什么?

按顺序做三件事,先保可用性,再谈加固。

第一,确认攻击面。用不同公共 DNS 交叉 dig,判断是权威 DNS 被打还是递归链路异常,同时看解析量曲线确认是否异常放大。

第二,加备份 NS 或切换托管解析。如果只有一组自建 NS 且已经被打瘫,自建 BIND 只有自身带宽,很难扛住持续查询;尽快在域名注册商处增加有抗能力强的托管 DNS(云解析)作为 NS,这是恢复最快的路径。

第三,自建 BIND 立即限速止血。在 named.conf 的 options 块中加入响应速率限制:

options {
    rate-limit {
        responses-per-second 10;
        nxdomains-per-second 5;
        errors-per-second 5;
        window 5;
        slip 2;
        exempt-clients { 10.0.0.0/8; 192.168.0.0/16; };
    };
};

同时在系统层限制 UDP 53 的包速率,防止包量打满网卡:

iptables -I INPUT -p udp --dport 53 -m limit --limit 200/s --limit-burst 400 -j ACCEPT
iptables -I INPUT -p udp --dport 53 -j DROP

Q:权威 DNS 还有哪些必须做的加固?

  • 关闭递归:自建权威 DNS 一定要设 recursion no;。开放递归的 DNS 会被利用做 DNS 放大反射,替攻击者打别人,也会让自己被拉黑。
  • 多 NS、跨厂商冗余:至少两组 NS,最好一组自建、一组托管云解析,避免单点全挂。
  • TTL 别设太短:TTL 设成 5 秒、10 秒,等于把查询量放大好几倍。静态记录建议 600 秒以上,迁移前才临时调短。
  • 只对必要记录开放查询:内网域名用 allow-query 限制来源网段,避免内部记录被外部扫描。
  • DNSSEC 要权衡:DNSSEC 能防劫持,但响应包更大,理论上更容易被用于放大攻击,且运维复杂度高。小站优先解决可用性,再考虑签名。

Q:托管云解析是怎么扛住 DNS 攻击的?

核心是Anycast 集群 + 大带宽 + 就近调度。托管云解析在全国/全球有众多解析节点,同一时刻不同地区的用户请求会落到不同节点,单点被打只影响局部,整体还能正常回答;厂商侧还有流量清洗和自动限速,遇到异常查询会自动触发,不需要站长操作。

接入方式很简单:把域名注册商处的 NS 记录改成厂商提供的 NS 地址,等 NS 生效(一般几小时,最长 48 小时)。之后建议做两件事:开启解析量/QPS 告警,异常时能第一时间收到通知;开启单域名查询限速,防止某个子域名被集中刷。

需要提醒的是:换了托管 DNS 只解决了可用性,泛解析、子域名暴露这些配置问题还得自己清理。

Q:源站这边要做什么配合?

DNS 层防护挡不住”绕开解析直接打 IP”的攻击,源站该做的加固一个也不能少:

  • 回源白名单:源站只允许 CDN 回源段访问 80/443,其余来源直接丢弃。这样即使 IP 泄露,攻击流量也进不了 Web 端口。
  • 兜底 server 块:把无效子域名、直接 IP 访问的请求引导到 404,不要进主站业务流程。
  • 保留 CDN 缓存:DNS 短暂不可用期间,已有本地缓存或 CDN 缓存的用户仍能正常访问,这也是 CDN 顺带带来的抗解析故障收益。
# 只允许 CDN 回源段访问 443(示例段,按厂商实际段替换)
iptables -A INPUT -p tcp --dport 443 -s 162.62.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j DROP

# Nginx 兜底 server:无效子域名与直连 IP 一律 404
server {
    listen 80 default_server;
    server_name _;
    return 404;
}

Q:还有什么补充建议?

DNS 防护是典型的”平时没人管,出事全站挂”的环节,建议按下面顺序补齐:清理泛解析记录 → 关闭权威 DNS 递归 → 配置 rate-limit 与 UDP 限速 → 至少两组跨厂商 NS(其中一组托管云解析)→ TTL 恢复到 600 秒以上 → 配置解析量告警

要特别注意 DNS 攻击的投入产出比:攻击者几十 Mbps 的查询流量,就可能打死一台自建 BIND 服务器,而防御成本远低于流量型 DDoS 高防。对绝大多数中小站点来说,把权威解析交给托管云解析、偶尔检查一遍泛解析状态,是性价比最高的一步。