BIND 中 DNSSEC 密钥(KSK/ZSK)手动生成与全生命周期管理
在 BIND 中,DNSSEC 密钥分为KSK(密钥签名密钥) 和ZSK(区域签名密钥),前者用于签名 DNSKEY 记录(构建信任链核心),后者用于签名普通区域记录(如 A/AAAA/CNAME)。以下是从生成、配置、轮换到安全管理的完整手动操作指南。
一、准备工作
1. 确认 BIND 版本与环境
-
需 BIND 9.8 及以上版本(支持现代 DNSSEC 算法),检查版本:named -v
-
确保系统已安装dnssec-tools(包含dnssec-keygen/dnssec-signzone等工具):
bash
运行
# CentOS/RHELyuminstallbind-utils dnssec-tools# Debian/Ubuntuaptinstallbind9utils dnssec-tools
-
规划密钥策略(参考最佳实践):
|
密钥类型
|
推荐算法
|
密钥长度
|
轮换周期
|
用途
|
|
KSK
|
ECDSA P-256-SHA256(算法 13)
|
256 位
|
1-2 年
|
签名 DNSKEY 记录
|
|
ZSK
|
ECDSA P-256-SHA256
|
256 位
|
3-6 个月
|
签名 A/AAAA/NS 等记录
|
|
注:RSA 算法需更长密钥(2048 + 位),ECDSA 更轻量,优先选择。
|
|
|
|
|
2. 目录与权限准备
密钥文件需存储在 BIND 可访问且安全的目录(避免权限泄露):
bash
运行
# 创建密钥存储目录(与区域文件同目录)mkdir-p/var/named/keys/example.comchownnamed:named /var/named/keys/example.comchmod700/var/named/keys/example.com# 仅named用户可访问
二、手动生成 KSK 和 ZSK
使用dnssec-keygen工具生成密钥,核心参数说明:
-
-a:指定签名算法(如ECDSAP256SHA256/RSASHA256)
-
-b:密钥长度(ECDSA 固定 256/384 位,RSA 建议 2048+)
-
-f KSK:标记为 KSK(仅 KSK 需要)
-
-n ZONE:指定为区域密钥
-
最后参数为域名(如example.com)
1. 生成 KSK
bash
运行
cd/var/named/keys/example.com# ECDSA算法(推荐)dnssec-keygen-aECDSAP256SHA256-fKSK-nZONE example.com# RSA算法(兼容旧环境)# dnssec-keygen -a RSASHA256 -b 2048 -f KSK -n ZONE example.com
2. 生成 ZSK
bash
运行
# ECDSA算法dnssec-keygen-aECDSAP256SHA256-nZONE example.com# RSA算法# dnssec-keygen -a RSASHA256 -b 2048 -n ZONE example.com
3. 密钥文件解读
生成后会得到两类文件(以Kexample.com.+013+12345为例):
-
Kexample.com.+013+12345.key:公钥文件(需加入区域文件,对外发布)
-
Kexample.com.+013+12345.private:私钥文件(核心机密,仅用于签名,禁止对外)
-
+013:算法编号(13=ECDSAP256SHA256,8=RSASHA256)
-
12345:密钥指纹(唯一标识)
4. 密钥文件权限加固
bash
运行
chownnamed:named /var/named/keys/example.com/*chmod600/var/named/keys/example.com/*.private# 私钥仅读chmod644/var/named/keys/example.com/*.key# 公钥可读取
三、配置 BIND 使用密钥并签名区域
1. 将公钥加入区域文件
编辑域名的区域文件(如/var/named/example.com.db),添加 KSK 和 ZSK 的公钥记录:
zone
; 手动添加DNSKEY记录(从.key文件复制内容)
example.com. IN DNSKEY 257 3 13 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU= ; KSK
example.com. IN DNSKEY 256 3 13 AwEAAbWl6Lz9Xg6t2J9U2R0h8eXZ8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8X8= ; ZSK
; 注:257=KSK标识,256=ZSK标识;3=协议版本;13=算法编号
快捷方式:直接将.key 文件内容追加到区域文件:
bash
运行
cat/var/named/keys/example.com/Kexample.com.+013+*.key>>/var/named/example.com.db
2. 配置 named.conf 启用 DNSSEC
编辑/etc/named.conf,确保全局和区域配置启用 DNSSEC:
conf
options {
directory "/var/named";
dnssec-enable yes; # 启用DNSSEC支持
dnssec-validation yes; # 递归服务器启用验证(若作为递归服务器)
dnssec-lookaside auto;
allow-transfer { none; }; # 禁止区域传输,防止密钥泄露
};
# 配置区域并关联密钥
zone "example.com" IN {
type primary;
file "example.com.db";
key-directory "/var/named/keys/example.com"; # 密钥存储目录
# 手动签名需注释自动签名,自动签名见下文
// dnssec-policy default;
};
3. 手动签名区域文件
使用dnssec-signzone工具对区域文件签名(生成带 RRSIG 的新区域文件):
bash
运行
# 核心命令:dnssec-signzone -o 域名 -k KSK私钥文件 区域文件 ZSK私钥文件dnssec-signzone-oexample.com-k/var/named/keys/example.com/Kexample.com.+013+12345.private /var/named/example.com.db /var/named/keys/example.com/Kexample.com.+013+67890.private# 简化版(自动识别密钥)dnssec-signzone-A-NINCREMENT-oexample.com /var/named/example.com.db
参数说明:
-
-o:指定区域域名
-
-k:指定 KSK 私钥(可选,自动识别则省略)
-
-A:生成 NSEC3 参数(防区域枚举)
-
-N INCREMENT:序列号自动递增
签名后会生成新文件example.com.db.signed,需修改named.conf指向该文件:
conf
zone "example.com" IN {
type primary;
file "example.com.db.signed"; # 改为签名后的文件
key-directory "/var/named/keys/example.com";
};
4. 重载 BIND 配置
bash
运行
rndc reload# 平滑重载,无需重启服务rndc status# 检查是否加载成功
四、密钥轮换(全生命周期核心)
密钥需定期轮换以降低泄露风险,ZSK 和 KSK 轮换流程不同:
1. ZSK 轮换(高频,3-6 个月)
ZSK 仅签名普通记录,轮换不影响信任链,步骤:
-
生成新 ZSK:重复第二步的 ZSK 生成命令,得到新密钥对;
-
双签名过渡:用新旧 ZSK 同时签名区域文件(保留旧 ZSK,等待 TTL 过期):
bash
运行
dnssec-signzone-oexample.com-kKSK私钥 文件 旧ZSK私钥 新ZSK私钥
-
等待 TTL 过期:确保旧 ZSK 的签名记录在全网过期(通常等待区域 TTL 的 2 倍时间);
-
移除旧 ZSK:从区域文件删除旧 ZSK 的 DNSKEY 记录,仅用新 ZSK 签名;
-
验证:dig +dnssec example.com DNSKEY 确认仅显示新 ZSK。
2. KSK 轮换(低频,1-2 年)
KSK 签名 DNSKEY 记录,轮换需更新父域 DS 记录,步骤:
-
生成新 KSK:重复第二步的 KSK 生成命令;
-
双 KSK 过渡:将新 KSK 的 DNSKEY 加入区域文件,用新旧 KSK 同时签名 DNSKEY 记录;
-
生成新 DS 记录:从新 KSK 的公钥生成 DS 记录(用于父域 / 注册商):
bash
运行
dnssec-dsfromkey /var/named/keys/example.com/Kexample.com.+013+新指纹.key
-
更新注册商 DS 记录:将新 DS 记录提交给域名注册商(保留旧 DS 记录,双记录过渡);
-
等待信任链更新:约 48 小时后,全网递归服务器更新 DS 记录;
-
移除旧 KSK:删除旧 KSK 的 DNSKEY 和 DS 记录,完成轮换。
五、密钥安全管理
1. 存储安全
-
KSK 私钥:离线存储(如加密 U 盘、硬件安全模块 HSM),仅签名时接入服务器;
-
ZSK 私钥:存储在 BIND 服务器本地,开启文件系统加密(如 LUKS);
-
禁止将私钥文件上传至公共服务器 / 代码仓库。
2. 备份策略
-
密钥生成后立即备份(公钥 + 私钥),加密存储(如 GPG 加密);
-
备份文件分多地存储(本地 + 离线介质),避免单点丢失。
3. 废弃密钥销毁
-
轮换后销毁旧密钥文件(使用shred工具彻底删除,而非普通删除):
bash
运行
shred-u/var/named/keys/example.com/旧密钥.private
-
备份介质物理销毁(如 U 盘粉碎)。
六、验证密钥有效性
1. 检查 DNSKEY 记录
bash
运行
dig+dnssec example.com DNSKEY# 输出应包含KSK(257标识)和ZSK(256标识),且有RRSIG签名
2. 验证 DS 记录(提交注册商后)
bash
运行
digexample.com DS# 输出应匹配dnssec-dsfromkey生成的DS记录
3. 完整 DNSSEC 验证
bash
运行
dig+dnssec +multiline example.com# 检查是否有"ad"(Authenticated Data)标志,且RRSIG记录有效
七、常见问题排查
|
问题现象
|
原因
|
解决方法
|
|
签名后区域无法加载
|
密钥文件权限错误 / 区域文件语法错误
|
检查 named 日志(/var/log/messages),修复权限 / 语法
|
|
dig 查询无 RRSIG 记录
|
未指向签名后的区域文件
|
修改 named.conf 的 zone 配置为.db.signed 文件
|
|
KSK 轮换后验证失败
|
注册商 DS 记录未更新
|
重新提交 DS 记录,等待全网同步
|
|
私钥文件丢失
|
无备份则需重新生成 KSK/ZSK,更新 DS 记录
|
日常做好密钥备份,避免丢失
|
总结
BIND 中手动管理 DNSSEC 密钥的核心是严格区分 KSK/ZSK、控制密钥权限、遵循轮换策略。手动方式适合需要高度定制的场景,但需注意:
-
小型场景可优先使用 BIND 的dnssec-policy自动签名(减少手动操作);
-
密钥安全是核心,KSK 离线存储、定期备份、及时销毁旧密钥是关键;
-
轮换时必须留足过渡时间,避免服务中断。
|