本页目录

DNSSEC 与 DNS 安全

DNS 设计时没有考虑安全——DNSSEC 用数字签名链给每一条 DNS 记录加上"不可伪造"的证明。它不加密(DNS over HTTPS 做加密),它防篡改——代价是签名链的维护和相关域名的放大效应。

概述

传统 DNS 没有密码学保护:任何中间节点都可以伪造应答(DNS spoofing)。DNSSEC 不加密查询,而是给每个 DNS 记录签名,形成从 root 到目标 domain 的信任链。resolver 可以验证"这个 A record 确实是 example.com 的 authoritative server 签发的"。代价是更大的响应包(RRSIG records)和更复杂的 zone 管理(KSK/ZSK 轮换)。DNSSEC 部署率约 30%(2024),部分原因在于其不能解决隐私问题——所以有 DoH/DoT 补充。

问题: DNS 没有认证

传统 DNS 响应没有任何密码学保证。攻击者可以:

  1. 缓存投毒 (Cache Poisoning): 发送伪造的 referral/glue → recursive resolver 缓存 poisoned RR
  2. 中间人攻击⁠: 在路径上伪造 DNS 响应 → 客户端收到假 IP

DNSSEC 解决: 对每个 zone 签名 → 形成从 root 到 leaf 的信任链 → resolver 可逐级验证。

注意: DNSSEC 不加密查询 (加密 = DoH/DoT/DoQ)。用户仍然暴露在: "ISP 看到你查了什么域名"。

记录类型

RRSIG (type 46):
  对一组 RRset 的签名 (不是对每个 RR 单独签名!)
  
  RDATA:
    Type Covered (2B): 被签的 RR type
    Algorithm (1B): 5=RSA/SHA1 (deprecated), 7=RSASHA1-NSEC3-SHA1, 8=RSA/SHA-256,
                    10=RSA/SHA-512, 13=ECDSA-P256-SHA256, 14=ECDSA-P384-SHA384,
                    15=ED25519, 16=ED448
    Labels (1B): original owner name 的 label 数
    Original TTL (4B): 原始 TTL (不是 RRSIG 自己的 TTL!)
    Signature Expiration (4B): 签名过期时间 (Unix timestamp)
    Signature Inception (4B): 签名生效时间
    Key Tag (2B): 用于标识 DNSKEY 的 numeric tag
    Signer's Name (label format): 产生此签名的 zone (通常是 zone 的 apex)
    Signature (variable): 实际签名 (对 RRset 的 canonical form)

DNSKEY (type 48):
  用于验证 RRSIG 的 zone 公钥

  RDATA:
    Flags (2B):
      bit 7 (Zone Key): 1 → 此密钥用于 DNSSEC
      bit 15 (Secure Entry Point): 1 → KSK (Key Signing Key),
        0 → ZSK (Zone Signing Key)
    Protocol (1B): always 3
    Algorithm (1B): same as RRSIG Algorithm
    Public Key (variable)

DS (type 43):
  KSK 的 hash, 存在 parent zone 中 → 形成跨 zone 信任链

  RDATA:
    Key Tag (2B): 匹配 DNSKEY 的 key tag
    Algorithm (1B): 与 DNSKEY 相同
    Digest Type (1B): 1=SHA-1 (deprecated), 2=SHA-256, 4=SHA-384
    Digest (variable): SHA-256(owner name + DNSKEY RDATA)

NSEC (type 47): authenticated denial of existence
  → "example.org A? — 不仅不存在, 而且能证明不存在"

信任链验证

Resolver 开始于: root DNSKEY hash (trust anchor, 预置在 resolver 中)

查 www.example.com A:
  1. 收到 A record + RRSIG (signer=example.com)
  2. 查 example.com DNSKEY → 用 DNSKEY 验证 RRSIG → OK (zone-level trust)
  3. 查 .com zone: DS (example.com) + RRSIG (signer=.com)
  4. 查 .com DNSKEY → 验证 DS 的 RRSIG → OK → DNSKEY hash matches DS → OK
  5. 查 root zone: DS (.com) + RRSIG → root DNSKEY → trust anchor match → OK
  → 完整信任链: root → .com → example.com → www.example.com

Key Signing Key (KSK) vs Zone Signing Key (ZSK):
  KSK: 只签名 DNSKEY RRset — 密钥长 (2048-bit RSA), 很少换 (1-2 年)
  ZSK: 签名 zone 中的所有 RRsets — 密钥短 (1024-bit RSA or ECDSA), 经常换 (月)
  → 分离 KSK/ZSK 原因: ZSK 频繁轮换 (DNSSEC signature 需要频繁换) 但 KSK
    换一次需要 parent zone 更新 DS → 父 zone 操作 + 传播延迟

NSEC3 (RFC 5155)

NSEC 的问题: 枚举 zone 中所有存在的 name (遍历 NSEC chain → 返回 next name)

NSEC3: 在证明 nonexistence 之前对 owner name 做 hash:

NSEC3 record:
  Hash Algorithm (1): SHA-1
  Flags (1): Opt-Out (bit 0)
  Iterations (2): hash iterations (0-65535, 高迭代 = DoS 风险)
  Salt Length + Salt: per-zone salt
  Hash Length + Hash (next hashed owner name)
  Type Bit Maps: 与 NSEC 相同

→ 遍历 NSEC3 chain 只看到 "hashed_abc → hashed_def" → 不能直接枚举 zone
  (但仍可 offline brute-force, NSEC3 只增加成本)

DANE (RFC 6698)

取代 CA (Certificate Authority) 为 TLS 证书提供信任:

TLSA record (_port._protocol.name):
  port: 443, 25, ...
  protocol: _tcp, _udp, ...

  RDATA:
    Cert Usage (1B):
      0: CA constraint (PKIX-TA)
      1: Service certificate constraint (PKIX-EE)
      2: Trust anchor assertion (DANE-TA) — 指定自己的 CA
      3: Domain-issued certificate (DANE-EE) — 直接指定本端的证书或公钥 → 最大安全!
    Selector (1B): 0=full certificate, 1=SubjectPublicKeyInfo (仅公钥)
    Matching Type (1B): 0=exact, 1=SHA-256, 2=SHA-512
    Certificate Association Data: hash or exact cert/pubkey

  验证: client 收到 TLS certificate → 查 TLSA record → hash matches? → 信任
  → 不需要 PKI/CA, 不需要 CT logs, certificate 有效与否只取决于 DNSSEC 签名
  → 问题: current adoption 几乎为零 (浏览器不支持)

参考

  • RFC: 4033-4035, 5155, 6698, 6840 (DNSSEC algorithm updates)
  • 工具⁠: dig +dnssec, delv @resolver, dnsviz.net

Keywords: DNSSEC, RRSIG, DNSKEY, DS, NSEC, NSEC3, DANE, trust anchor, zone signing, KSK, ZSK