【DNSSEC 02】域名总被劫持?在 VPS + Cloudflare 上开启 DNSSEC 防篡改

讲清 DNSSEC 是怎么防中间人改解析的,分别在自管 Bind/PowerDNS 和 Cloudflare 上开启,含 DS 记录、密钥轮转与常见“解析变慢”误区。

延伸阅读

更多相关攻略推荐:泛域名 SSL 证书自动化避坑:Acme.sh + DNS API BGP 是互联网的"高德地图":打开网页时,数据是这样找路的【优化线路 02】BGP / AS4837 常规线路年付 10 美元高级玩家玩出花:如何在 VPS 上广播自己的 IP 地址?BYOIP计算机科学两大难题之一:缓存失效与 CDN 瞬时刷新奥秘

一、域名为什么会被劫持?先搞懂 DNS 的"裸奔"隐患

你可能已经给网站上了 HTTPS、装了防火墙、密码也设得够复杂,但有一个最前置的环节一直"裸奔":域名解析(DNS)。用户在你之前先要问一句"这个域名对应的服务器 IP 是多少",而传统 DNS 的设计默认"你说啥我信啥"。递归 DNS 服务器向权威服务器要答案时,并不会验证这个答案到底是不是官方给的,这就给了中间人篡改的空间。

最常见的两种攻击是缓存投毒(Cache Poisoning)DNS 劫持。攻击者把伪造的 A 记录塞进你本地递归服务器或运营商 DNS 的缓存里,下一次你访问官网,解析出来的其实是个钓鱼 IP;更隐蔽的是中间人直接在链路上拦下查询、返回假答案。结果就是:用户浏览器地址栏挂着一把小绿锁(HTTPS),访问的却是黑客的服务器——因为 SSL 证书是钓鱼站自己申请的,绿锁只证明"这个连接加密了",根本证明不了你访问的是不是真官网

很多人以为"我用 8.8.8.8、1.1.1.1 公共 DNS 就安全了"。错。公共 DNS 本身也可能被污染,而且它和你之间还是明文传输。真正能从协议底层堵死"假解析"的,是给 DNS 答案加上数字签名——也就是 DNSSEC。2026 年 6 月 Cloudflare Radar 的数据很扎心:全网只有 8.11% 的域名完成了 DNSSEC 签名,真正实现端到端校验的请求占比仅 0.47%;独立测量机构 dnschkr 在 2026 年 2 月扫描了 2.4 亿个委托域名,只有 4.27% 在父域发布了可用的 DS 记录(7 月回升到 5.22%)。换句话说,绝大部分域名至今还在"裸奔"。

二、DNSSEC 到底是什么:给 DNS 查询结果"签名验真"

DNSSEC(Domain Name System Security Extensions,域名系统安全扩展)不是给 DNS 加密,而是给 DNS 记录加数字签名。它和 HTTPS 的关系可以这样理解:HTTPS 负责"传输过程不被偷看、不被改内容",DNSSEC 负责"你拿到的那个 IP 确实来自官方、没被半路掉包"。两者互补,互不替代。

原理上,域名所有者用一对私钥给区(zone)里的每一条记录签名,把签名连同公钥一起发布到 DNS 里。递归服务器拿到解析结果时,顺手用公钥验一下签名:签名对得上,说明记录没被改过,放心用;对不上,直接丢弃,宁可让用户解析失败,也不把假 IP 交出去。这样一来,缓存投毒和中间人伪造就彻底失效——假的记录没有对应的真签名,验不过。

需要澄清一个关键点:DNSSEC 解决的是真实性(Authentication)和完整性(Integrity),它不提供机密性。你的查询内容依然可能被旁人看到,要隐藏"你查了什么",得靠 DoT(DNS over TLS)或 DoH(DNS over HTTPS)。另外,DNSSEC 也不防 DDoS、不防域名被偷(registrar 账户被盗那种),它只守"解析结果不被篡改"这一亩三分地,但这块恰恰是最常被忽略的。

三、信任链怎么搭起来:RRSIG、DNSKEY 与 DS 记录

DNSSEC 的核心是信任链(Chain of Trust)。它引入了几个新记录类型,记住这四个就够用:

  • RRSIG:一条资源记录集(RRset)的数字签名。A、AAAA、MX 等记录被签过名后,就配一个 RRSIG。
  • DNSKEY:存放公钥。区里通常有两根公钥,一根 Zone Signing Key(ZSK,区签名密钥),一根 Key Signing Key(KSK,密钥签名密钥)。
  • DS(Delegation Signer):放在父域里的"指纹",是子域 KSK 公钥的哈希值,用来把信任从父域交给子域。
  • NSEC / NSEC3:用来"证明某个域名不存在"(认证的否定存在),顺便防止有人把整个区遍历抄走。

工作流程是分层的:你给自己的区签名用 ZSK,ZSK 公钥再用 KSK 签一遍,KSK 公钥的哈希(就是 DS)交给父域(比如 .com)发布。于是信任从根(root,2010 年起已签名)→ .com → 你的域名,一级一级传下来。递归服务器只要从根区的信任锚(trust anchor)出发,逐级验到你的区,整条链都通过,才算"验真成功"。

正因为信任是通过 DS 记录从父域"接"下来的,所以光在你自己的服务器上签名还不够,必须把 DS 记录填到注册商/父域那边,否则全世界都连不上你的信任链(RFC 4035 管这叫"孤岛式安全",谁也验不到)。这也是后面 Cloudflare 和自管方案都要"填 DS"的原因。

如果你打算在自己的 VPS 上跑 Bind9 或 PowerDNS 来签名(而不是用 Cloudflare 托管),KSK/ZSK 怎么生成、named.conf 怎么配 dnssec-policy、pdnsutil secure-zone 怎么用、delv 怎么验链——这些完整命令和排错都在系列第 01 篇:DNSSEC 01 · VPS 自建 DNS 并开启 DNSSEC。本篇聚焦"为什么会被劫持"以及"用 Cloudflare 一键开启"的最省心路径,自管命令不再重复展开。

四、在 Cloudflare 上开启 DNSSEC:开个开关再填一张 DS 表

如果你把 DNS 托管在 Cloudflare(绝大多数国人 VPS 站点都这么干),开启 DNSSEC 是最省心的——Cloudflare 帮你管密钥、自动签名、自动轮转,你只做两件事。

第一步,登录 Cloudflare 控制台,进入你的站点 → DNSSettings,找到 DNSSEC 那一项,点 Enable。几秒钟后状态变成"已启用"。

第二步,Cloudflare 会给你生成一段 DS 信息(Key Tag、Algorithm、Digest Type、Digest 四栏)。这段必须回到你的域名注册商那里填,因为 DS 记录在父域(.com / .cn 等)。具体位置各注册商不同,一般叫"DNSSEC / DS 记录管理",把四栏原样粘贴保存即可。填完等父域 TTL 生效(几分钟到几小时),整条信任链就接通了。

注意:Cloudflare 的 Universal DNSSEC 不需要你生成或保管任何密钥,KSK/ZSK 轮换它全包了,所以基本不会出现"自己轮密钥翻车"的事故,特别适合不想折腾的小站长。唯一要小心的就是换 DNS 服务商之前先关 DNSSEC,否则旧 DS 还在父域、新服务商的 KSK 对不上,整站解析会 SERVFAIL。

五、DS 记录从哪来、怎么填到域名注册商

不管你自管还是用 Cloudflare,DS 记录是连接你和父域信任的唯一桥梁,这一步漏了,DNSSEC 等于白开。DS 通常包含四段:

  • Key Tag(密钥标签):一把用来快速定位 KSK 的短整数。
  • Algorithm(算法):比如 13 代表 ECDSAP256SHA256,8 代表 RSASHA256。
  • Digest Type(摘要类型):常用 2(SHA-256)。
  • Digest(摘要):一长串十六进制哈希,就是 KSK 公钥的"指纹"。

自管 Bind/PowerDNS 用 dnssec-dsfromkeypdnsutil export-zone-ds 导出;Cloudflare 直接在面板里给。拿到后到注册商后台粘贴。这里最容易出手误:多一个空格、少一位、算法选错,都会导致父域的 DS 和你的 KSK 哈希对不上,验证器直接判定 BOGUS,域名"验真失败、无法解析"。填完建议用下面命令验一下父域是否真的收下了:

dig DS example.com +short

如果返回空,说明父域还没发布,或者你填错了;有内容且与你区里导出的摘要一致,才算接通。

六、密钥轮转(KSK/ZSK Rollover)怎么做才不翻车

密钥不能一把用一辈子。ZSK 轮换频繁(比如每月),KSK 轮换少(几年一次,根区 KSK 大约五年一换,ICANN 规划的下一轮 KSK 轮转在 2026/2027 年)。轮换做错,典型后果就是解析中断。核心原则是:新密钥先发布、等旧 DS 的 TTL 过期之后再撤旧密钥

ZSK 轮换最简单:因为 ZSK 公钥只在自己的 DNSKEY 里、不经父域 DS,Bind/PowerDNS 基本能自动平滑完成,你几乎无感。用 Cloudflare 的用户更省心——这套它后台默默做完,你连 KSK 长啥样都不用知道。

KSK 轮换就麻烦了,因为要动父域的 DS。标准顺序是:

  • T+0:用新旧两把 KSK 同时给 DNSKEY 集签名(双签)。
  • T+Y:把 KSK 的 DS 提交到父域(注册商),等待生效。
  • T+Z:等 DS 的 TTL 完全过期(这段必须算准,不能偷懒)。
  • T+Z+ε:停止用旧 KSK 签名,删除旧 DNSKEY 与旧 DS。

顺序一旦反了——比如先删旧 DS、新 DS 还没传开——链就断一截,全球验证器会认为你的区"签名无效"。所以 KSK 轮换最忌"快",宁可多等几个 TTL。用 Cloudflare 的用户最幸福:这整套它后台默默做完,你连 KSK 长啥样都不用知道。

七、常见误区:DNSSEC 会拖慢解析?会泄露隐私?会搞挂网站?

关于 DNSSEC 的误传特别多,挑三个最常见的拆一下。

误区一:开了 DNSSEC 解析会变慢。真相是:签名就多返几个 RRSIG 记录,体积很小,而且递归服务器会缓存。现代解析器普遍支持更大的 EDNS0 报文(1232 字节以上),一次往返就能拿全。DNSSEC 带来的延迟通常是亚毫秒级,用户根本感知不到。真正"慢"的锅,往往是你没开 EDNS0、防火墙还卡着 512 字节老上限,跟 DNSSEC 没关系。

误区二:DNSSEC 能加密我的查询、保护隐私。不能。它只签名不加密。要隐私请上 DoT/DoH。把 DNSSEC 当"加密"是新手最常犯的混肴。

误区三:开 DNSSEC 容易把网站搞挂。配置正确时几乎不会。出事的案例 99% 是:DS 填错、KSK 轮换顺序反了、签名过期没自动续(自管没开 inline-signing)。换句话说,"翻车"几乎都来自人为操作失误,不是协议本身。而且 2026 年还有个新 incentive:CA/B 论坛的 SC-085v2 规定证书颁发机构签发 TLS 证书前会验证 DNSSEC,配置错误的 DNSSEC 会直接挡掉证书签发(DCV 失败)。这反而逼着大家把 DNSSEC 配对,配对了还能防证书被钓鱼站冒领。

八、怎么验证你的 DNSSEC 真的生效了

开了不等于生效,建议你立刻验三步。

第一,看父域有没有 DS:

dig DS example.com +short

第二,看解析结果带不带 DNSSEC 标志,重点盯 flags 里的 ad(Authenticated Data)。有 ad 说明递归服务器验真通过了:

dig +dnssec example.com +multiline | grep -E "flags|RRSIG"

第三,用 Bind 自带的 delv 做端到端验证,它专跑完整信任链,没 ad 也强行验:

delv example.com +vtrace

也可以用在线可视化工具 DNSViz(dnsviz.net)看信任链哪里断。国内用户还要留意:部分运营商递归服务器不验证 DNSSEC,所以你这边验真通过,不代表所有用户侧都验;但至少 1.1.1.1、8.8.8.8、9.9.9.9 这几大公共 DNS 都默认验证,覆盖面已经够广。把 DNSSEC 配上,等于给你的域名加了把"官方防伪章",性价比极高。