DNSSEC(DNS Security Extensions) 是 DNS 的安全扩展,通过数字签名机制确保 DNS 数据的完整性和真实性,防止 DNS 欺骗、缓存投毒等攻击。
为什么需要 DNSSEC
传统 DNS 的安全问题
shell用户查询 www.bank.com ↓ DNS 查询(明文) ↓ 攻击者伪造响应 ↓ 用户访问钓鱼网站
主要威胁:
- DNS 缓存投毒
- 中间人攻击
- DNS 欺骗
DNSSEC 的解决方案
shell用户查询 www.bank.com ↓ DNS 查询(带签名验证) ↓ 验证数字签名 ↓ 签名验证失败 → 拒绝伪造响应 签名验证通过 → 返回正确 IP
DNSSEC 的工作原理
密钥体系
DNSSEC 使用非对称加密建立信任链:
shell根密钥(Root Key) ↓ 签名 顶级域密钥(TLD Key) ↓ 签名 域名密钥(Zone Key) ↓ 签名 DNS 记录
DNSSEC 记录类型
| 记录类型 | 作用 |
|---|---|
| DNSKEY | 存储公钥 |
| DS | Delegation Signer,将子域的公钥哈希存储在父域 |
| RRSIG | 资源记录签名 |
| NSEC | 否定存在证明(证明某个记录不存在) |
| NSEC3 | NSEC 的改进版本,防止区域遍历攻击 |
DNSSEC 验证流程
shell1. 用户查询 www.example.com + DNSKEY ↓ 2. 返回 A 记录和 RRSIG 签名 ↓ 3. 获取 DNSKEY 公钥 ↓ 4. 验证 RRSIG 签名 ↓ 5. 验证 DNSKEY 的 DS 记录(来自父域) ↓ 6. 沿信任链向上验证到根密钥 ↓ 7. 所有签名验证通过 → 接受响应
DNSSEC 记录详解
DNSKEY 记录
dns; 存储公钥 example.com. 3600 IN DNSKEY 256 3 8 ( AwEAAbX8qU... ) ; Base64 编码的公钥
字段说明:
- Flags: 256 表示区域签名密钥(ZSK),257 表示密钥签名密钥(KSK)
- Protocol: 3 表示 DNSSEC
- Algorithm: 8 表示 RSA/SHA256
RRSIG 记录
dns; 资源记录签名 www.example.com. 3600 IN RRSIG A 8 3 3600 ( 20240101000000 20240108000000 12345 example.com. oKx8j3... ) ; Base64 编码的签名
字段说明:
- Type Covered: 被签名的记录类型(A、AAAA 等)
- Algorithm: 加密算法
- Signature Expiration: 签名过期时间
- Signature Inception: 签名生效时间
- Key Tag: DNSKEY 的标识符
- Signer's Name: 签名者域名
- Signature: 数字签名
DS 记录
dns; 存储在父域,包含子域 DNSKEY 的哈希 example.com. 3600 IN DS 12345 8 2 ( 2BB183AF5F22588179A53B0A98631FAD1A2DD3475 )
作用:建立父域和子域之间的信任链
NSEC/NSEC3 记录
dns; 证明某个记录不存在 www.example.com. 3600 IN NSEC a.example.com. A AAAA ; NSEC3 提供更好的隐私保护
作用:
- 证明某个域名不存在
- 防止 DNS 欺骗
DNSSEC 的信任链
信任锚点
shell信任锚点(Root Key) ↓ 验证 .com TLD Key ↓ 验证 example.com Key ↓ 验证 DNS 记录
密钥类型
KSK(Key Signing Key)
- 作用:签名 DNSKEY 记录
- 特点:长期使用,变更需要更新父域的 DS 记录
- 密钥长度:通常 2048-4096 位
ZSK(Zone Signing Key)
- 作用:签名区域中的所有其他记录
- 特点:定期轮换,不影响信任链
- 密钥长度:通常 1024-2048 位
双密钥策略优势:
- ZSK 定期轮换,提高安全性
- KSK 长期稳定,减少 DS 记录更新
DNSSEC 部署步骤
1. 生成密钥
bash# 生成 KSK dnssec-keygen -f KSK -a RSASHA256 -b 2048 example.com # 生成 ZSK dnssec-keygen -a RSASHA256 -b 1024 example.com
2. 签名区域
bash# 签名区域文件 dnssec-signzone -K . -o example.com example.com.db
3. 上传 DS 记录到父域
bash# 查看 DS 记录 dnssec-dsfromkey Kexample.com.+008+12345 # 将 DS 记录添加到父域(如 .com)
4. 配置 DNS 服务器
bind; named.conf options { dnssec-validation auto; dnssec-lookaside auto; };
DNSSEC 的优势
安全性提升
| 威胁类型 | DNSSEC 防护效果 |
|---|---|
| DNS 缓存投毒 | ✅ 完全防护 |
| 中间人攻击 | ✅ 完全防护 |
| DNS 欺骗 | ✅ 完全防护 |
| 数据篡改 | ✅ 完全防护 |
信任机制
- 自上而下的信任链:从根密钥开始验证
- 数字签名:确保数据未被篡改
- 公钥加密:防止私钥泄露导致大规模攻击
DNSSEC 的挑战
1. 部署复杂度高
- 需要配置密钥管理
- 定期轮换密钥
- 维护信任链
2. 性能影响
- DNS 响应大小增加(包含签名)
- 需要额外的 DNS 查询获取 DNSKEY
- 验证签名需要计算资源
3. 兼容性问题
- 部分旧 DNS 客户端不支持
- 某些网络设备可能丢弃大型 DNS 响应
4. EDNS0 依赖
- DNSSEC 需要 EDNS0 支持
- 需要更大的 UDP 包(超过 512 字节)
DNSSEC 状态
全球部署情况
| 区域 | DNSSEC 支持情况 |
|---|---|
| 根域名 | ✅ 2010 年已签名 |
| .com | ✅ 已签名 |
| .org | ✅ 已签名 |
| .net | ✅ 已签名 |
| .cn | ✅ 已签名 |
| 部分二级域名 | ⚠️ 部分支持 |
检查 DNSSEC 状态
bash# 使用 dig 检查 dig +dnssec www.example.com # 使用 dnsviz 可视化 dnsviz www.example.com # 在线工具 - https://dnssec-debugger.verisignlabs.com/ - https://dnsviz.net/
DNSSEC 最佳实践
1. 密钥管理
bash# 定期轮换 ZSK(如每 90 天) # KSK 可以长期使用(1-2 年) # 安全存储私钥 # 使用 HSM(硬件安全模块) # 限制私钥访问权限
2. 签名策略
dns; 设置合理的签名有效期 RRSIG: 30 天有效期 NSEC/NSEC3: 与区域 TTL 相同
3. 监控和告警
- 监控签名过期时间
- 设置密钥轮换提醒
- 监控 DNSSEC 验证失败率
4. 测试验证
bash# 部署前充分测试 dnssec-verify example.com.db # 使用多个验证工具测试 dig +dnssec +adflag www.example.com
面试常见问题
Q: DNSSEC 能防止 DNS 劫持吗?
A: DNSSEC 可以防止传输过程中的 DNS 劫持和欺骗,但不能防止以下情况:
- 客户端本地 DNS 配置被篡改
- 攻击者控制了权威 DNS 服务器
- 本地 hosts 文件被修改
Q: 为什么 DNSSEC 需要 EDNS0?
A: DNSSEC 签名和密钥数据会增加 DNS 响应大小,传统 DNS 的 512 字节 UDP 包限制不够用。EDNS0 扩展了 DNS 协议,支持更大的包大小。
Q: KSK 和 ZSK 有什么区别?
A:
- KSK(密钥签名密钥):签名 DNSKEY 记录,长期使用,变更需要更新父域 DS 记录
- ZSK(区域签名密钥):签名区域中的其他记录,定期轮换,不影响信任链
Q: DNSSEC 会影响 DNS 性能吗?
A: 会有一定影响:
- DNS 响应大小增加(包含签名)
- 需要额外的 DNSKEY 查询
- 签名验证需要计算资源
- 但现代网络和硬件通常可以接受
总结
| 方面 | 说明 |
|---|---|
| 核心作用 | 确保 DNS 数据的完整性和真实性 |
| 技术基础 | 非对称加密、数字签名、信任链 |
| 关键记录 | DNSKEY、DS、RRSIG、NSEC/NSEC3 |
| 密钥类型 | KSK(长期)、ZSK(定期轮换) |
| 部署挑战 | 复杂度高、性能影响、兼容性 |
| 部署状态 | 根域名和主流 TLD 已支持 |