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

  CREATED BY JENKINSBOT

问题背景

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

实际的情况是这样的:在同一个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
TODO 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?