DNS反向区
DNS域名解析过程通常是通过域名找到对应的IP地址,而有一些情况下我们希望通过IP找到对应的域名,这里涉及到以地址为域名命名空间即in-addr.arpa域,就是我们熟知的方向区。
下面我们用dig命令查询一下202.106.0.20这个公网IP对应的域名如下:
C:\Users\test>dig -x 202.106.0.20 @8.8.8.8
; <<>> DiG 9.7.2rc1 <<>> -x 202.106.0.20 @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53479
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;20.0.106.202.in-addr.arpa. IN PTR
;; ANSWER SECTION:
20.0.106.202.in-addr.arpa. 21511 IN PTR gjjline.bta.net.cn.
;; Query time: 150 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Jul 12 22:22:52 2020
;; MSG SIZE rcvd: 75
可见反向区中的域名都是以.in-addr.arpa为后缀,而.in-addr.arpa最多可以有256个子域。下面是一个反向区的zone文件举例:
[root@localhost bind]# cat var/run/db.111.10.0
$TTL 3h
0.10.111.in-addr.arpa. IN SOA dns.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
0.10.111.in-addr.arpa. IN NS dns.test.com.
1.0.10.111.in-addr.arpa. IN PTR www.test.com.
named.conf主配置文件相关内容如下:
zone "0.10.111.in-addr.arpa" {
type master;
file "db.111.10.0";
};
解析测试111.10.0.1地址的域名结果如下:
[root@localhost bind]# dig -x 111.10.0.1 @192.168.3.160
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> -x 111.10.0.1 @192.168.3.160
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51578
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;1.0.10.111.in-addr.arpa. IN PTR
;; ANSWER SECTION:
1.0.10.111.in-addr.arpa. 10800 IN PTR www.test.com.
;; Query time: 0 msec
;; SERVER: 192.168.3.160#53(192.168.3.160)
;; WHEN: Sun Jul 12 10:46:11 EDT 2020
;; MSG SIZE rcvd: 78
在实际使用过程中要注意地址在域名中是反过来的,虽然看起来有点别扭~
BIND内置反向区
当我们正常启动一个bind实例后,如果未创建任何的反向区,可动手做如下实验,通过反向解析测试10.10.10.1这个地址的对应的域名。正常来讲因为我们没有创建这个反向区,所以这个查询肯定是会触发程序到互联网做迭代,而如果所在的设备到互联网的网络不可达,那么解析结果肯定是失败的,但真实的情况如下:
[root@localhost bind]# dig -x 10.10.10.1 @192.168.3.160
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> -x 10.10.10.1 @192.168.3.160
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 40993
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;1.10.10.10.in-addr.arpa. IN PTR
;; AUTHORITY SECTION:
10.IN-ADDR.ARPA. 86400 IN SOA 10.IN-ADDR.ARPA. . 0 28800 7200 604800 86400
;; Query time: 0 msec
;; SERVER: 192.168.3.160#53(192.168.3.160)
;; WHEN: Sun Jul 12 10:52:45 EDT 2020
;; MSG SIZE rcvd: 102
解析结果并没有失败,而是直接应答NXDOMAIN,这个就奇怪了,难道bind程序内置了什么反向区?答案是:确实内置!
在bind源码的bin/named/server.c文件中能找到相关代码,如下:
/*
* These zones should not leak onto the Internet.
*/
const char *empty_zones[] = {
/* RFC 1918 */
"10.IN-ADDR.ARPA", "16.172.IN-ADDR.ARPA", "17.172.IN-ADDR.ARPA",
"18.172.IN-ADDR.ARPA", "19.172.IN-ADDR.ARPA", "20.172.IN-ADDR.ARPA",
"21.172.IN-ADDR.ARPA", "22.172.IN-ADDR.ARPA", "23.172.IN-ADDR.ARPA",
"24.172.IN-ADDR.ARPA", "25.172.IN-ADDR.ARPA", "26.172.IN-ADDR.ARPA",
"27.172.IN-ADDR.ARPA", "28.172.IN-ADDR.ARPA", "29.172.IN-ADDR.ARPA",
"30.172.IN-ADDR.ARPA", "31.172.IN-ADDR.ARPA", "168.192.IN-ADDR.ARPA",
/* RFC 6598 */
"64.100.IN-ADDR.ARPA", "65.100.IN-ADDR.ARPA", "66.100.IN-ADDR.ARPA",
"67.100.IN-ADDR.ARPA", "68.100.IN-ADDR.ARPA", "69.100.IN-ADDR.ARPA",
"70.100.IN-ADDR.ARPA", "71.100.IN-ADDR.ARPA", "72.100.IN-ADDR.ARPA",
"73.100.IN-ADDR.ARPA", "74.100.IN-ADDR.ARPA", "75.100.IN-ADDR.ARPA",
"76.100.IN-ADDR.ARPA", "77.100.IN-ADDR.ARPA", "78.100.IN-ADDR.ARPA",
"79.100.IN-ADDR.ARPA", "80.100.IN-ADDR.ARPA", "81.100.IN-ADDR.ARPA",
"82.100.IN-ADDR.ARPA", "83.100.IN-ADDR.ARPA", "84.100.IN-ADDR.ARPA",
"85.100.IN-ADDR.ARPA", "86.100.IN-ADDR.ARPA", "87.100.IN-ADDR.ARPA",
"88.100.IN-ADDR.ARPA", "89.100.IN-ADDR.ARPA", "90.100.IN-ADDR.ARPA",
"91.100.IN-ADDR.ARPA", "92.100.IN-ADDR.ARPA", "93.100.IN-ADDR.ARPA",
"94.100.IN-ADDR.ARPA", "95.100.IN-ADDR.ARPA", "96.100.IN-ADDR.ARPA",
"97.100.IN-ADDR.ARPA", "98.100.IN-ADDR.ARPA", "99.100.IN-ADDR.ARPA",
"100.100.IN-ADDR.ARPA", "101.100.IN-ADDR.ARPA", "102.100.IN-ADDR.ARPA",
"103.100.IN-ADDR.ARPA", "104.100.IN-ADDR.ARPA", "105.100.IN-ADDR.ARPA",
"106.100.IN-ADDR.ARPA", "107.100.IN-ADDR.ARPA", "108.100.IN-ADDR.ARPA",
"109.100.IN-ADDR.ARPA", "110.100.IN-ADDR.ARPA", "111.100.IN-ADDR.ARPA",
"112.100.IN-ADDR.ARPA", "113.100.IN-ADDR.ARPA", "114.100.IN-ADDR.ARPA",
"115.100.IN-ADDR.ARPA", "116.100.IN-ADDR.ARPA", "117.100.IN-ADDR.ARPA",
"118.100.IN-ADDR.ARPA", "119.100.IN-ADDR.ARPA", "120.100.IN-ADDR.ARPA",
"121.100.IN-ADDR.ARPA", "122.100.IN-ADDR.ARPA", "123.100.IN-ADDR.ARPA",
"124.100.IN-ADDR.ARPA", "125.100.IN-ADDR.ARPA", "126.100.IN-ADDR.ARPA",
"127.100.IN-ADDR.ARPA",
/* RFC 5735 and RFC 5737 */
"0.IN-ADDR.ARPA", /* THIS NETWORK */
"127.IN-ADDR.ARPA", /* LOOPBACK */
"254.169.IN-ADDR.ARPA", /* LINK LOCAL */
"2.0.192.IN-ADDR.ARPA", /* TEST NET */
"100.51.198.IN-ADDR.ARPA", /* TEST NET 2 */
"113.0.203.IN-ADDR.ARPA", /* TEST NET 3 */
"255.255.255.255.IN-ADDR.ARPA", /* BROADCAST */
/* Local IPv6 Unicast Addresses */
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6."
"ARPA",
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6."
"ARPA",
/* LOCALLY ASSIGNED LOCAL ADDRESS SCOPE */
"D.F.IP6.ARPA", "8.E.F.IP6.ARPA", /* LINK LOCAL */
"9.E.F.IP6.ARPA", /* LINK LOCAL */
"A.E.F.IP6.ARPA", /* LINK LOCAL */
"B.E.F.IP6.ARPA", /* LINK LOCAL */
/* Example Prefix, RFC 3849. */
"8.B.D.0.1.0.0.2.IP6.ARPA",
/* RFC 7534 */
"EMPTY.AS112.ARPA",
/* RFC 8375 */
"HOME.ARPA",
NULL
};
所以,对于这些反向区,如果管理员不显示的在本地创建,那么默认就已经在程序运行的时候加载,自然也就应答NXDOMAIN。如果管理员显示的创建,那么优先级肯定要高于这个底层内置的。至于bind为什么要这么做,也许是因为这些地址本来在互联网域名体系中就解析不到,与其浪费DNS服务器递归资源到互联网迭代查询,还不如就本地直接应答。
这个特性在当bind用在企业数据中心内网做DNS系统时很重要,因为数据中心内部的主机IP基本是私网地址,宿主机上的应用在调用解析器时可能会自动的发起这些私网IP的方向PTR查询,如果管理员没有显示的创建这些私网地址的反向区,那么其实bind也会正常的应答,只是结果为NXDOMAIN(域名不存在)。