DNS动态更新
- 什么是DNS动态更新
- DNS动态更新与BIND软件的关系
- 如何使用DNS动态更新
- bind9环境nsupdate工具动态更新权威区数据举例
- nsupdate入门
- nsupdate使用细节
- 实现基于TSIG的DNS动态更新
什么是DNS动态更新
RFC 2136描述了这样一种机制:它允许通过授权的更新者updater对权威DNS服务器的区数据动态的增加、删除资源记录。它给DNS系统日常运维带来了一种更加方便的变更区数据手段,管理员不再通过手工修改配置文件的方式变更数据。同时,它也提供了DHCP服务器分配IP地址后可通过DNS动态更新的机制自动在DNS权威区中添加IP与域名的对应记录(DDNS)的手段。
DNS动态更新与BIND软件的关系
BIND8和BIND9都支持RFC 2136所描述的DNS动态更新功能,但不是BIND软件独有,Windows Server作为DNS服务器时也是支持这个机制的。
如何使用DNS动态更新
- 一些程序内部已经具备此功能的函数调用,例如dhcpd这个软件它会通过ns_update()创建更新消息。
- 命令行工具nsupdate(此程序已经包含在BIND软件包中,安装后在bin目录下)可实现手动通过nsupdate命令创建更新消息,这个在DNS系统运维的时候比较常用。在对DNS系统的二次开发时可调用包装这个工具。
bind9环境nsupdate工具动态更新权威区数据举例
nsupdate入门
nsupdate工具是一个交互式的命令工具,在服务器上执行nsupdate然后Enter进入,先尝试一下如下:
[root@localhost ~]# nsupdate
> server 127.0.0.1
> update add xxx.test.com 300 A 3.3.3.3
> send
update failed: REFUSED
>quit
上面执行结果显然是失败了,但通过这些命令我们可以看到大概使用的思路:通过server制定DNS服务器的IP地址、通过update add命令向test.com区新增一个域名xxx.test.com、通过send命令提交、通过quit命令退出。
当然,这个失败的原因是named.conf文件中没有开启update,需要在对应的区配置部分显示的配置allow-update语句,简单的举例如下:
zone "test.com" {
type master;
allow-update { any; };
file "test.com.zone";
};
重新测试一遍上面失败的nsupdate命令,没有报错。
[root@localhost ~]# nsupdate
> server 127.0.0.1
> update add xxx.test.com 300 A 3.3.3.3
> send
> quit
bind的相关日志打印如下:19-Jun-2020 22:09:51.370 update: info: client @0x7f22a400a2b0 127.0.0.1#26718: updating zone 'test.com/IN': adding an RR at 'xxx.test.com' A 3.3.3.3
使用dig命令测试解析正常。
[root@localhost bind]# dig @192.168.3.160 xxx.test.com +short
3.3.3.3
查看test.com.zone文件内容发现没有这个xxx.test.com域名。
[root@localhost run]# cat test.com.zone
$TTL 3h
@ IN SOA dns1.test.com. manager.test.com. (
1 ;Serial
3h ;Refresh after 3 hours
1h ;Retry after 1 hour
1w ;Expire after 1 week
1h) ;Negative caching TTL of 1 hour
;
@ IN NS dns1.test.com.
@ IN NS dns2.test.com.
;server domain
;
dns1 3600 IN A 111.10.10.10
dns2 3600 IN A 111.10.10.20
www 300 IN A 101.10.10.10
hello 20 IN A 101.10.10.20
a 20 IN CNAME hello
mail 300 IN A 101.10.10.30
time IN A 2.2.2.2
而存放zone文件的目录下多了一个test.com.zone.jnl 的文件,文件内容是乱码,无法查看。
综上,nsupdate的入门使用貌似不难,但有一些现象和配置我们还是没有根本了解,下面我们就来详细的说说这些细节。
nsupdate使用细节
- 关于jnl文件的细节
动态更新的区变化会保持在jnl文件中,此文件是二进制格式,不能手动编辑。更新的数据会定期的从jnl文件转存到zone文件中,但这个转存不是更新后立即执行,因为如果是立即执行那么一个大的区在频繁更新时候会导致服务器变动很慢。经测试,bind9这个转存的默认时间是15分钟,转存过程中可能还能临时看到jnw和jbk文件,但这些都不需要我们关注。
在上面的test.com例子中,如果我们希望将目前jnl文件中的数据先转存到zone文件中,可以执行rndc sync test.com
命令,此时会立即转存。
- 转存后zone文件的格式会变
动态更新成功且jnl配置转存成功后,我们再查看原来的zone文件会发现文件的内容格式变了,貌似给我们大扫除了一遍。真是让人激动,上面test.com的例子中转存后的zone文件内容如下,大家可自己对比看看。
[root@localhost run]# cat test.com.zone
$ORIGIN .
$TTL 10800 ; 3 hours
test.com IN SOA dns1.test.com. manager.test.com. (
3 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
604800 ; expire (1 week)
3600 ; minimum (1 hour)
)
NS dns1.test.com.
NS dns2.test.com.
$TTL 3600 ; 1 hour
MX 10 mail.test.com.
$ORIGIN test.com.
$TTL 20 ; 20 seconds
a CNAME hello
$TTL 50 ; 50 seconds
b A 1.1.1.1
$TTL 3600 ; 1 hour
dns1 A 111.10.10.10
dns2 A 111.10.10.20
$TTL 20 ; 20 seconds
hello A 101.10.10.20
$TTL 300 ; 5 minutes
mail A 101.10.10.30
$TTL 10800 ; 3 hours
time A 2.2.2.2
$TTL 300 ; 5 minutes
www A 101.10.10.10
xxx A 3.3.3.3
- nsupdate命令参考
nsupdate命令有很多,它还具备判断类命令,例如先判断这个要添加的域名是不是存在,如果不存在则添加。
命令 | 功能介绍 |
prereq nxdomain domain name | 执行更新前,必须满足指定的domain name不存在 |
prereq yxdomain domain name | 执行更新前,指定的domain name必须存在 |
prereq nxrrset domain name type | 执行更新前,指定的domain name的type类型的记录(RRset)必须不存在 |
prereq yxrrset domain name type [rdata] | 执行更新前,指定的domain name的type类型的记录(RRset)必须存在,如果指定了rdata,那么也必须存在。 |
update add domain name ttl [class] type rdata | 在区域中增加指定的记录,处理type和rdata之外还必须包含ttl,class类是可选的默认是IN |
update delete domain name [type] [rdata] | 删除指定的域名,例如 |
实现基于TSIG的DNS动态更新
上面test.com区数据动态更新举例时配置文件有allow-update { any; };
这个配置,这any肯定是不安全的。虽然allow-update这里也可以添加基于IP的ACL来实现动态更新源地址的控制,但还是不够安全,因为这种基于UDP的更新很容易伪装源IP造成系统风险。所以BIND建议通过事物签名(TSIG)来加密和认证所进行的更新。举例说明如下。
首先,bind安装完毕后,在sbin目录下有tsig-keygen命令,通过这个命令对一个密钥名称进行计算得到共享密钥,如下:
[root@localhost sbin]# ./tsig-keygen --help
tsig-keygen: invalid argument --
Usage:
tsig-keygen [-a alg] [keyname]
-a alg: algorithm (default hmac-sha256)
[root@localhost sbin]# ./tsig-keygen -a hmac-md5 mytest > mytest.key
[root@localhost sbin]# cat mytest.key
key "mytest" {
algorithm hmac-md5;
secret "7fDlWke7zAvqD+I6ubgXwA==";
};
将上面生成的密钥信息配置到named.conf文件中
key "mytest" {
algorithm hmac-md5;
secret "7fDlWke7zAvqD+I6ubgXwA==";
};
zone "test.com" {
type master;
allow-update { key mytest; };
file "test.com.zone";
};
再使用nsupdate工具举例如下:
[root@localhost etc]# nsupdate -y mytest:7fDlWke7zAvqD+I6ubgXwA==
> server 127.0.0.1
> zone test.com
> update add xxx3.test.com 3000 A 6.6.6.6
> send
> quit
[root@localhost etc]# dig @192.168.3.160 xxx3.test.com
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> @192.168.3.160 xxx3.test.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37724
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;xxx3.test.com. IN A
;; ANSWER SECTION:
xxx3.test.com. 3000 IN A 6.6.6.6
;; Query time: 0 msec
;; SERVER: 192.168.3.160#53(192.168.3.160)
;; WHEN: Fri Jun 19 23:13:34 EDT 2020
;; MSG SIZE rcvd: 58
19-Jun-2020 23:13:16.323 update: info: client @0x7ff39000eef0 127.0.0.1#51058/key mytest: updating zone 'test.com/IN': adding an RR at 'xxx3.test.com' A 6.6.6.6
nsupdate工具实现DNS动态更新本文就介绍到这,实际系统运维过程中面对集群架构的DNS系统还是要涉及一些细节,这个我们后面再针对性的介绍。