在 Linux 上设置本地权威 DNS 服务器

CompTIABeginner
立即练习

介绍

在本实验中,你将学习如何使用 bind9 在 Linux 系统上设置和配置一个本地权威 DNS 服务器。你将获得使用最广泛的 DNS 软件之一的实践经验,将一台标准的 Linux 机器转变为一台能够为本地网络解析自定义域名的服务器。

整个过程始于安装必要的软件包并配置全局服务器选项,例如设置转发器(forwarders)。然后,你将定义一个正向查找区域(forward lookup zone),用于将域名解析为 IP 地址,以及一个反向查找区域(reverse lookup zone),用于相应的 IP 地址范围。最后,你将验证 bind9 配置文件是否存在语法错误,并使用 dig 工具测试你的新 DNS 服务器,确保它能正确解析本地域名的查询。

安装 bind9 并配置全局选项

在此步骤中,你将开始设置 DNS 服务器的核心组件。这包括安装 bind9,它是 Linux 上最广泛使用的 DNS 服务器软件之一。你还将配置其全局选项,这些选项控制服务器的一般行为,例如它如何处理它不权威的域的请求。

首先,更新系统的软件包列表是标准做法,以确保你获得最新版本的软件。

在你的终端中执行以下命令:

sudo apt-get update

接下来,安装 bind9 包,其中包含 DNS 服务器守护进程,以及 bind9-utils,它提供了有用的命令行工具,如 dignamed-checkconf,你稍后将使用它们进行测试和验证。

sudo apt-get install bind9 bind9-utils

系统会提示你确认安装。输入 Y 并按 Enter。输出将与此类似:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  bind9-libs bind9-doc dns-root-data
...
After this operation, XX.X MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
...
Setting up bind9 (1:9.18.X-XubuntuX.X) ...

安装完 bind9 后,下一步是配置其全局行为。主配置文件被分成几个文件,都位于 /etc/bind/ 目录下。对于全局选项,你将编辑 named.conf.options 文件。

使用 nano 编辑器打开文件:

sudo nano /etc/bind/named.conf.options
options {
        directory "/var/cache/bind";

        // If there is a firewall between you and nameservers you want
        // to talk to, you may need to fix the firewall to allow multiple
        // ports to talk.  See http://www.kb.cert.org/vuls/id/800113

        // If your ISP provided one or more IP addresses for stable
        // nameservers, you probably want to use them as forwarders.
        // Uncomment the following block, and insert the addresses replacing
        // the all-0's placeholder.

        // forwarders {
        //      0.0.0.0;
        // };

        //========================================================================
        // If BIND logs error messages about the root key being expired,
        // you will need to update your keys.  See https://www.isc.org/bind-keys
        //========================================================================
        dnssec-validation auto;

        listen-on-v6 { any; };
};

在此文件中,你将看到一个 options { ... }; 块。你需要确保此块包含转发(forwarding)、查询权限(query permissions)和监听接口(listening interfaces)的指令。转发允许你的 DNS 服务器通过询问其他公共 DNS 服务器来解析外部域名(如 google.com)。

修改 options 块以匹配以下内容。你可以添加缺失的行,或取消注释并更改已存在的行。

提示:你可以通过按 Ctrl+K 清空文件内容,然后粘贴以下内容。

options {
        directory "/var/cache/bind";

        // If there is not a line with forwarders, add the following section.
        // If there is one, ensure it's not commented out and has valid IPs.
        forwarders {
                8.8.8.8;
                8.8.4.4;
        };

        // Add or uncomment this line to allow queries from any host
        allow-query { any; };
        recursion yes;

        listen-on { any; }; // Listen on all interfaces
        listen-on-v6 { any; }; // Listen on all IPv6 interfaces

        dnssec-validation auto;
        auth-nxdomain no;    ## conform to RFC1035
};

编辑完成后,按 Ctrl+O 保存文件,然后按 Enter 确认文件名。按 Ctrl+X 退出 nano 编辑器。你已成功安装 bind9 并设置了其初始配置。

mylocaldomain.net 定义并创建正向查找区域

在此步骤中,你将配置你的 bind9 服务器使其成为自定义域的权威服务器。这是通过创建一个正向查找区域(forward lookup zone)来实现的,它是一个数据库,将人类可读的主机名(如 webserver.mylocaldomain.net)映射到其对应的 IP 地址。你将首先在 bind9 配置中定义该区域,然后创建包含 DNS 记录的实际区域文件。

首先,你需要告知 bind9 关于你的新区域。本地区域配置保存在 /etc/bind/named.conf.local 中,以将其与默认软件包配置分开。此文件将在下一步中完全配置。

现在区域已定义,你必须创建相应的区域文件。此文件包含实际的 DNS 记录。

首先,复制一个模板文件以确保新文件具有正确的权限和所有权:

sudo cp /etc/bind/db.local /etc/bind/db.mylocaldomain.net

接下来,你无需手动编辑文件,而是可以运行一个命令块,该命令块将:

  1. 获取你的 VM 的 IP 地址。
  2. 使用当前日期生成动态序列号。
  3. 将完整且正确的区域文件内容写入 /etc/bind/db.mylocaldomain.net

首先,将你的 VM 的 IP 地址捕获到一个将在区域文件中使用的变量中:

VM_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

此命令使用正则表达式从你的主网络接口(eth0)提取 IPv4 地址。IP 地址将自动插入到你的 DNS 记录中。

现在,使用适当的 DNS 记录创建区域文件。这个单一命令将生成完整的区域文件:

sudo bash -c "cat > /etc/bind/db.mylocaldomain.net" << EOF
\$TTL    604800
@       IN      SOA     ns1.mylocaldomain.net. admin.mylocaldomain.net. (
                     $(date +%Y%m%d)01 ; Serial (YYYYMMDDNN)
                             604800     ; Refresh
                              86400     ; Retry
                            2419200     ; Expire
                             604800 )   ; Negative Cache TTL
;
@       IN      NS      ns1.mylocaldomain.net.
ns1     IN      A       ${VM_IP}
webserver IN    A       ${VM_IP}
fileserver IN   A       ${VM_IP}
www     IN      CNAME   webserver
EOF

此命令使用你的 VM 的特定 IP 地址自动填充区域文件中的正确记录。你可以使用 cat /etc/bind/db.mylocaldomain.net 来验证内容。你现在已成功定义并创建了你的第一个正向查找区域。

定义并创建所有本地区域

在此步骤中,你将创建所有必需的本地区域配置。你将使用一个脚本来执行以下操作,而不是手动编辑文件,以确保设置准确:

  1. 创建 /etc/bind/named.conf.local: 此文件将从头开始生成,以包含你的正向(mylocaldomain.net)和反向查找区域的定义。
  2. 创建反向区域文件: 该脚本还将创建 db.REVERSE_IP 文件,其中包含必需的 PTR 记录。

首先,收集两个区域配置所需的 IP 地址信息:

IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
REV_IP=$(echo $IP | awk -F. '{print $3"."$2"."$1}')
LAST_OCTET=$(echo $IP | awk -F. '{print $4}')

这会提取你的 VM 的 IP 地址并对其进行处理,以创建反向查找区域所需的反向 IP 格式。例如,如果你的 IP 是 172.16.50.100,则 REV_IP 变为 50.16.172LAST_OCTET 变为 100

接下来,创建告诉 bind9 关于这两个区域的主区域配置文件:

sudo bash -c "cat > /etc/bind/named.conf.local" << EOF
//
// Do any local configuration here
//

// Forward lookup zone
zone "mylocaldomain.net" {
    type master;
    file "/etc/bind/db.mylocaldomain.net";
};

// Reverse lookup zone
zone "${REV_IP}.in-addr.arpa" {
    type master;
    file "/etc/bind/db.${REV_IP}";
};
EOF

此文件定义了正向查找区域(用于将名称解析为 IP)和反向查找区域(用于将 IP 解析回名称)。type master 表示此服务器是这些区域的权威服务器。

最后,创建带有 PTR 记录的反向区域文件:

sudo bash -c "cat > /etc/bind/db.${REV_IP}" << EOF
\$TTL    604800
@       IN      SOA     ns1.mylocaldomain.net. admin.mylocaldomain.net. (
                     $(date +%Y%m%d)01 ; Serial
                             604800     ; Refresh
                              86400     ; Retry
                            2419200     ; Expire
                             604800 )   ; Negative Cache TTL
;
@       IN      NS      ns1.mylocaldomain.net.
;
${LAST_OCTET}     IN      PTR     ns1.mylocaldomain.net.
${LAST_OCTET}     IN      PTR     webserver.mylocaldomain.net.
${LAST_OCTET}     IN      PTR     fileserver.mylocaldomain.net.
EOF

这种自动化方法确保了 named.conf.local 中正确定义了两个区域,并且正确创建了反向区域文件,从而避免了常见的配置错误。

验证 bind9 配置并使用 dig 测试 DNS 解析

在此步骤中,你将验证你所做的所有配置更改,然后测试你的实时 DNS 服务器。在应用配置更改之前检查配置文件是否存在语法错误是一项关键实践,因为一个错误可能会导致 bind9 服务无法正确启动。验证完成后,你将使用 dig 工具执行 DNS 查询,并确认你的服务器按预期工作。

首先,使用 named-checkconf 检查主 bind9 配置文件是否存在任何语法错误。如果此命令没有产生任何输出,则表示你的配置文件(named.conf.localnamed.conf.options 等)是有效的。

sudo named-checkconf

接下来,验证你的正向查找区域文件的语法。named-checkzone 命令用于检查区域文件的正确性。

sudo named-checkzone mylocaldomain.net /etc/bind/db.mylocaldomain.net

成功的检查将返回 "OK" 状态并显示你区域文件中的序列号:

zone mylocaldomain.net/IN: loaded serial 2024052001
OK

现在,验证反向查找区域。由于区域名称和文件名取决于你的 VM 的 IP 地址,请先收集必要的信息:

IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
REV_IP=$(echo $IP | awk -F. '{print $3"."$2"."$1}')
ZONE_NAME="${REV_IP}.in-addr.arpa"
ZONE_FILE="/etc/bind/db.${REV_IP}"

这会根据你的 VM 的实际 IP 地址创建正确的区域名称和文件路径。

现在运行区域验证命令:

echo "Checking reverse zone: ${ZONE_NAME}"
sudo named-checkzone ${ZONE_NAME} ${ZONE_FILE}

成功的检查将再次显示 "OK" 状态:

zone 50.16.172.in-addr.arpa/IN: loaded serial 2024052001
OK

在重启之前,请通过设置正确的权限来确保 bind9 服务能够读取区域文件。首先,再次获取 IP 信息以构建正确的文件路径:

IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
REV_IP=$(echo $IP | awk -F. '{print $3"."$2"."$1}')

现在为两个区域文件设置正确的权限:

sudo chown root:bind /etc/bind/db.mylocaldomain.net "/etc/bind/db.${REV_IP}"

在所有配置都经过验证后,是时候重启 bind9 服务以应用更改了:

sudo systemctl restart bind9

为了确保服务正确启动并加载了你的新区域,请检查系统日志。

sudo grep named /var/log/syslog | grep "loaded serial"

你应该会看到确认你的两个区域都已成功加载的输出。输出还将包括 localhost 等默认区域,这是正常的。关键是找到 mylocaldomain.net 和你的反向区域的行。

... named[...]: zone mylocaldomain.net/IN: loaded serial 2025071401
... named[...]: zone 50.16.172.in-addr.arpa/IN: loaded serial 2025071401
...

如果你没有看到这些行,请查看 sudo systemctl status bind9 的输出以获取错误信息。

最后,使用 dig 测试你的 DNS 服务器。你将通过指定 @127.0.0.1 直接查询你的本地服务器。

首先,测试 webserver.mylocaldomain.net 的正向查找:

dig @127.0.0.1 webserver.mylocaldomain.net

在输出中,查找 ANSWER SECTION。它应该显示指向你的 VM IP 地址的 A 记录,并且重要的是,头部的 flags 应包含 aa 以表示权威应答。底部的 SERVER 行应显示 127.0.0.1

...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;webserver.mylocaldomain.net. IN A

;; ANSWER SECTION:
webserver.mylocaldomain.net. 604800 IN A <your_vm_ip>

;; SERVER: 127.0.0.1#53(127.0.0.1)
...

接下来,使用 -x 标志测试反向查找。首先,捕获你的 VM 的 IP 地址:

IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

现在执行反向查找测试:

dig @127.0.0.1 -x $IP

ANSWER SECTION 现在应该显示你创建的 PTR 记录,将你的 IP 解析回主机名,并且 flags 也应包含 aa

...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;<last_octet>.<your_reversed_network_part>.in-addr.arpa. IN PTR

;; ANSWER SECTION:
<last_octet>.<your_reversed_network_part>.in-addr.arpa. 604800 IN PTR fileserver.mylocaldomain.net.
<last_octet>.<your_reversed_network_part>.in-addr.arpa. 604800 IN PTR ns1.mylocaldomain.net.
<last_octet>.<your_reversed_network_part>.in-addr.arpa. 604800 IN PTR webserver.mylocaldomain.net.

;; SERVER: 127.0.0.1#53(127.0.0.1)
...

恭喜!你已成功配置、验证并测试了一个基本的权威 DNS 服务器。

总结

在此实验中,你使用 bind9 软件包在 Linux 上配置了一个本地权威 DNS 服务器。该过程始于安装 bind9 及其基本工具,然后编辑全局 named.conf.options 文件以定义服务器范围的行为,例如设置转发器以解析外部域名查询。

接着,你创建了主要的 DNS 区域:一个用于 mylocaldomain.net 的正向查找区域,使用 A 记录将主机名映射到 IP 地址;以及一个相应的反向查找区域,使用 PTR 记录将 IP 地址映射回主机名。实验最后是关键的验证阶段,你使用 named-checkconfnamed-checkzone 检查配置错误,然后使用 dig 工具执行成功的正向和反向查找来测试实时服务器的功能。