BIND DNS 服务器搭建完全教程 / 第 07 章:动态更新与 DDNS
本章概述
动态更新(Dynamic Update)允许运行时修改 DNS 区域数据,无需手动编辑区域文件。本章讲解 TSIG 认证、安全动态更新、DHCP 联动(DDNS)以及动态区域与 DNSSEC 的配合。
7.1 动态更新基础
7.1.1 什么是动态更新
动态更新(RFC 2136)允许通过 DNS 协议向权威服务器发送更新请求,添加、修改或删除资源记录。
# 传统方式:编辑区域文件 → 递增 Serial → 重载
vim /var/cache/bind/primary/example.com.zone
rndc reload example.com
# 动态更新:直接通过 nsupdate 命令发送更新
nsupdate -k Kexample.com.+013+12345.key
> update add test.example.com 3600 A 192.168.1.50
> send
7.1.2 支持的操作
| 操作 | 说明 | 示例 |
|---|---|---|
| 添加记录 | update add | 添加 A、AAAA、TXT 等 |
| 删除记录 | update delete | 删除指定记录 |
| 删除所有 | update delete name | 删除该名称的所有记录 |
| 条件添加 | update add + prerequisite | 仅在记录不存在时添加 |
| 条件删除 | update delete + prerequisite | 仅在记录存在时删除 |
7.2 TSIG(Transaction Signature)
TSIG 使用共享密钥对 DNS 消息进行签名认证。
7.2.1 生成 TSIG 密钥
# 使用 tsig-keygen 生成密钥(推荐)
tsig-keygen -a hmac-sha256 update-key > /etc/bind/update.key
# 查看生成的密钥
cat /etc/bind/update.key
输出:
key "update-key" {
algorithm hmac-sha256;
secret "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789=";
};
# 或者使用旧工具(不推荐)
dnssec-keygen -a HMAC-SHA256 -b 256 -n HOST update-key
7.2.2 在 named.conf 中引用 TSIG 密钥
// 引入 TSIG 密钥
include "/etc/bind/update.key";
zone "example.com" {
type primary;
file "primary/example.com.zone";
// 仅允许使用 TSIG 密钥的客户端进行动态更新
allow-update { key update-key; };
};
7.2.3 TSIG 算法选择
| 算法 | 安全性 | 性能 | 推荐 |
|---|---|---|---|
hmac-sha256 | 高 | 好 | ✅ 推荐 |
hmac-sha384 | 更高 | 稍慢 | 高安全需求 |
hmac-sha512 | 最高 | 一般 | 极高安全需求 |
hmac-sha1 | 中(已不推荐) | 快 | ❌ 不推荐新部署 |
hmac-md5 | 低(已不安全) | 最快 | ❌ 禁止使用 |
7.3 使用 nsupdate 发送动态更新
7.3.1 nsupdate 基本用法
# 交互模式
nsupdate -k /etc/bind/update.key
> server 127.0.0.1
> zone example.com.
> update add test.example.com 3600 A 192.168.1.50
> send
> quit
7.3.2 添加记录
# 添加 A 记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update add newhost.example.com 3600 A 192.168.1.60
send
EOF
# 添加 AAAA 记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update add newhost.example.com 3600 AAAA fd00::60
send
EOF
# 添加 MX 记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update add example.com 3600 MX 10 mail.example.com.
send
EOF
# 添加 TXT 记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update add _dmarc.example.com 3600 TXT "v=DMARC1; p=reject"
send
EOF
7.3.3 删除记录
# 删除特定记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update delete test.example.com A
send
EOF
# 删除该名称的所有记录
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
update delete test.example.com
send
EOF
7.3.4 前置条件(Prerequisites)
# 条件添加:仅当记录不存在时添加
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
prereq nxdomain newhost.example.com
update add newhost.example.com 3600 A 192.168.1.60
send
EOF
# 条件删除:仅当记录值匹配时删除
nsupdate -k /etc/bind/update.key <<EOF
server 127.0.0.1
zone example.com.
prereq yxrrset test.example.com A 192.168.1.50
update delete test.example.com A 192.168.1.50
send
EOF
| 前置条件 | 含义 |
|---|---|
prereq nxdomain name | 名称必须不存在 |
prereq yxdomain name | 名称必须存在 |
prereq nxrrset name class type | 记录必须不存在 |
prereq yxrrset name class type data | 记录必须存在且值匹配 |
7.4 动态更新后的区域文件
7.4.1 文件变化
# 动态更新后,BIND 会自动修改区域文件
# 原始文件:example.com.zone → 变为 example.com.zone.jnl(日志)
# 最终写入:example.com.zone(定期或冻结时合并)
# 查看日志文件
ls -la /var/cache/bind/primary/
# example.com.zone
# example.com.zone.jnl ← 动态更新日志
7.4.2 冻结和解冻区域
# 冻结区域(合并日志到区域文件,禁止动态更新)
sudo rndc freeze example.com
# 现在可以手动编辑区域文件
sudo vim /var/cache/bind/primary/example.com.zone
# 注意:需要手动更新 Serial!
# 解冻区域(重新启用动态更新)
sudo rndc thaw example.com
⚠️ 冻结期间动态更新将被拒绝,操作应尽快完成。
7.5 DHCP 联动(DDNS)
DDNS(Dynamic DNS)是指 DHCP 服务器在分配 IP 后自动向 DNS 服务器注册记录。
7.5.1 ISC DHCP 配置
# /etc/dhcp/dhcpd.conf
# TSIG 密钥
key dhcp-update-key {
algorithm hmac-sha256;
secret "dhcp-secret-key-here=";
}
# 区域定义
zone example.com. {
primary 127.0.0.1;
key dhcp-update-key;
}
zone 1.168.192.in-addr.arpa. {
primary 127.0.0.1;
key dhcp-update-key;
}
# 子网配置
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.10;
option domain-name "example.com";
# DDNS 设置
ddns-domainname "example.com.";
ddns-rev-domainname "in-addr.arpa.";
ddns-updates on;
update-static-leases on;
# 租约时间
default-lease-time 3600;
max-lease-time 86400;
}
7.5.2 BIND 侧配置
// named.conf
// DHCP 更新密钥
key dhcp-update-key {
algorithm hmac-sha256;
secret "dhcp-secret-key-here=";
};
// 正向区域
zone "example.com" {
type primary;
file "primary/example.com.zone";
allow-update { key dhcp-update-key; };
// 也可以限制来源 IP
// allow-update { key dhcp-update-key; 192.168.1.1; };
};
// 反向区域
zone "1.168.192.in-addr.arpa" {
type primary;
file "primary/192.168.1.rev";
allow-update { key dhcp-update-key; };
};
7.5.3 Kea DHCP(ISC 新一代 DHCP)
// /etc/kea/kea-dhcp4.conf
{
"Dhcp4": {
"interfaces-config": {
"interfaces": ["eth0"]
},
"lease-database": {
"type": "memfile"
},
"ddns-qualifying-suffix": "example.com",
"dhcp-ddns": {
"enable-updates": true,
"server-ip": "127.0.0.1",
"server-port": 53,
"sender-ip": "192.168.1.1",
"sender-port": 53,
"ncr-protocol": "UDP",
"ncr-format": "JSON"
},
"subnet4": [{
"subnet": "192.168.1.0/24",
"pools": [{"pool": "192.168.1.100 - 192.168.1.200"}],
"option-data": [
{"name": "routers", "data": "192.168.1.1"},
{"name": "domain-name-servers", "data": "192.168.1.10"}
]
}]
}
}
7.6 安全动态更新配置
7.6.1 基于 IP 的更新控制(不推荐)
zone "example.com" {
type primary;
file "primary/example.com.zone";
// 仅允许特定 IP 更新
allow-update { 192.168.1.1; }; // 仅 DHCP 服务器 IP
};
⚠️ 不推荐:IP 地址可以被伪造,安全性较低。
7.6.2 基于 TSIG 的更新控制(推荐)
key "update-key" {
algorithm hmac-sha256;
secret "...";
};
zone "example.com" {
type primary;
file "primary/example.com.zone";
// 仅允许持有 TSIG 密钥的客户端更新
allow-update { key update-key; };
};
7.6.3 多密钥场景
// 不同服务使用不同的 TSIG 密钥
key "dhcp-key" {
algorithm hmac-sha256;
secret "dhcp-secret...";
};
key "monitoring-key" {
algorithm hmac-sha256;
secret "monitoring-secret...";
};
key "devops-key" {
algorithm hmac-sha256;
secret "devops-secret...";
};
zone "example.com" {
type primary;
file "primary/example.com.zone";
// DHCP 可更新正向和反向
allow-update {
key dhcp-key;
};
};
zone "dev.example.com" {
type primary;
file "primary/dev.example.com.zone";
// 开发团队可更新 dev 子域
allow-update {
key dhcp-key;
key devops-key;
};
};
7.7 动态更新与 DNSSEC
7.7.1 自动签名模式
zone "example.com" {
type primary;
file "primary/example.com.zone";
// 动态更新 + DNSSEC 自动签名
inline-signing yes;
auto-dnssec maintain;
key-directory "primary/keys";
allow-update { key update-key; };
};
在这种模式下,BIND 会:
- 接收动态更新
- 修改区域数据
- 自动更新 RRSIG 签名
- 自动维护密钥轮转
💡 这是生产环境推荐配置:
inline-signing+auto-dnssec+allow-update完美配合。
7.7.2 手动签名模式
如果使用手动签名,动态更新后需要重新签名:
# 冻结 → 编辑 → 签名 → 解冻
rndc freeze example.com
# 手动编辑区域文件
dnssec-signzone -o example.com example.com.zone
rndc thaw example.com
7.8 动态更新日志与监控
7.8.1 启用动态更新日志
logging {
channel update_log {
file "/var/log/named/update.log" versions 10 size 50m;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
category update { update_log; };
category update-security { update_log; };
};
7.8.2 日志分析
# 查看更新日志
tail -f /var/log/named/update.log
# 典型日志条目:
# 10-Jan-2026 14:30:15.123 client @0x7f8b8c0d 192.168.1.1#12345/key dhcp-key: updating zone 'example.com/IN': adding an RR at 'newhost.example.com' A 192.168.1.60
# 查看更新统计
rndc stats
cat /var/cache/bind/named.stats
7.9 常见问题排查
7.9.1 更新被拒绝
# 症状:update failed: REFUSED
# 检查 allow-update 配置
named-checkconf
# 检查 TSIG 密钥是否匹配
# 客户端和服务器的密钥必须完全一致
# 查看安全日志
tail -f /var/log/named/security.log
# 测试更新
nsupdate -k update.key
> server 127.0.0.1
> zone example.com.
> update add test.example.com 3600 A 192.168.1.50
> send
# 检查返回的响应码
7.9.2 更新成功但解析不到
# 可能原因:日志未合并到区域文件
# 解决:rndc freeze → rndc thaw
# 检查日志文件
ls -la /var/cache/bind/primary/*.jnl
# 验证更新
dig @127.0.0.1 test.example.com A
7.9.3 区域文件被清空
# 罕见情况:动态更新可能导致区域文件损坏
# 解决:从备份恢复
sudo rndc freeze example.com
sudo cp /backup/example.com.zone /var/cache/bind/primary/
sudo rndc thaw example.com
7.10 本章小结
| 配置项 | 说明 | 推荐值 |
|---|---|---|
allow-update | 允许动态更新的客户端 | key tsig-key;(基于 TSIG) |
inline-signing | 自动签名 | yes(配合 DNSSEC) |
auto-dnssec | 自动密钥轮转 | maintain |
| TSIG 算法 | 事务签名算法 | hmac-sha256 |
| 前置条件 | 条件更新 | 用于防止冲突 |
💡 小技巧
- 始终使用 TSIG 认证:不要用
allow-update { any; };。 - 定期备份区域文件:动态更新可能导致数据丢失。
- 使用
inline-signing:让 BIND 自动处理 DNSSEC 签名。 rndc freeze操作要快:冻结期间所有更新都会被拒绝。- 每个 DHCP 服务器使用独立密钥:便于审计和撤销。