「BIND9」- 如果记录不存在,则进行转发

问题背景

“如果记录不存在,则进行转发”;

实际的情况是这样的:在同一个 ZONE 中,有些域名使用 ISP 的 DNS 服务器进行解析,而有些域名希望仅在本地 DNS 服务器解析的。比如域名 inner.k4nz.com 仅在内网的 DNS 服务器上解析,而 outer.k4nz.com 则由公网的 DNS 服务器解析。我们希望这二者可以共存,即“如果内网 DNS 服务找不到对应的记录,则到公网的 DNS 服务器查找”,亦即“如果记录不存在,则进行转发”;

这就会存在一个问题:内网的 DNS 服务器接管 k4nz.com 这个 ZONE 之后,导致同 ZONE 内的在公网 DNS 服务解析的域名无法解析。就是说,使用内网 DNS 服务接管 k4nz.com 这个 zone 后,在公网解析的 outer.k4nz.com 就无法解析了。(为什么?因为就这样,去了解以下 DNS 吧……)

解决方案

要怎么解决这个问题呢:首先想到的当然就是“如果记录不存在,则进行转发”,但是 BIND 好像没有提供这个功能“在 ZONE 里找不到就去其他 DNS 服务器查询的功能”(或许是我没找到)。所以,就去搜索了以下,给出的办法是“覆盖”,用到了“Response Policy Zones (RPZ)”配置,包含在 BIND 9.8.1 以后的版本中:定义一个 ZONE,这个 ZONE 用作覆盖原由的记录;

注意,本文侧重于从 DNS 服务层面解决这个问题,而不是在客户端中使用类似于“如果这个 DNS 服务器没有找到记录,则去下一个查找”的方法进行解决。相关方法参见「Ubuntu resolv.conf, not going to next nameserver?」「second nameserver in /etc/resolv.conf not picked up by wget
WIP DNS – 如果没有找到对应的记录,则去下一台进行查找

实行配置

修改 /etc/named.conf 配置文件,内容如下:

options {
        listen-on port 53 { any; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        recursing-file  "/var/named/data/named.recursing";
        secroots-file   "/var/named/data/named.secroots";
        allow-query     { any; };
        recursion yes;
        allow-transfer { none; };
        response-policy { zone "rpz"; };
};

zone "." IN {
        type hint;
        file "named.ca";
};

zone "rpz" IN {
        type master;
        file "named.rpz";
        allow-query {
                none;
        };
};

创建 /var/named/named.rpz 配置文件,内容如下:

$TTL 600
@       IN      SOA     dns.example.com. root.example.com. (20190101 3H 15M 1W 1D)
                NS      dns.example.com.

note.example.com		IN		A		172.31.255.249
mgr.example.com			IN		A		172.31.255.80
sys.example.com			IN		A		172.31.255.33

重启 DNS 服务:

#!/bin/bash

systemctl restart named.service

验证是否有效:

#!/bin/bash

# 查询由内部 DNS 服务解析的域名
dig note.example.com
dig mgr.example.com

# 查询由外部 DNS 服务解析的域名
dig www.example.com

注意事项

用作 RPZ 的 ZONE 名不能和实际的 ZONE 名匹配,否则无法“覆盖”。比如,RPZ 的 ZONE 名为 k4nz.com,那么在 k4nz.com 下面的域名的“覆盖”会无效,这也是使用“rpz”作为 ZONE 名的原因;

参考文献

(1)BIND9 – Response Policy Zone Configuration
(1)How to configure your BIND resolvers to lie using Response Policy Zones (RPZ)
Overriding some DNS entries in BIND for internal networks
How do I resolve a DNS name for the same zone not found locally but that exists on another DNS server?