跳转至内容

BIND

来自 ArchWiki

BIND (或 named) 是最广泛使用的域名系统 (DNS) 服务器。

注意 开发 BIND 的组织在 Linux 发行版或公众之前最多提前四天向付费客户提供安全公告。[1]

安装

安装 bind 包。

启动/启用 named.service systemd 单元。

要在本地使用 DNS 服务器,请使用 127.0.0.1 名称服务器(意味着像 Firefox 这样的客户端通过 127.0.0.1 进行解析),请参阅 域名解析。但这将需要您 #允许递归,而防火墙可能会阻止对本地 named 的外部查询。

配置

本文章或章节需要扩充。

原因: 添加指示,说明如何将 BIND 配置为 /etc/resolv.conf 中的本地 DNS 服务器(直接配置和通过 openresolv 配置)。(在 Talk:BIND 中讨论)

BIND 配置在 /etc/named.conf 中。可用选项记录在 named.conf(5) 中。

重新加载 named.service 单元以应用配置更改。

启用 rndc 访问

为了使用 rndc(8) 控制 BIND,您需要为其设置 TSIG 密钥,并告知 BIND 允许使用该密钥进行名称服务器控制。

首先,为此目的生成 TSIG 密钥

$ tsig-keygen console
key "console" {
    algorithm hmac-sha256;
    secret "secret";
};

将输出复制到 /etc/named.conf/etc/rndc.conf

/etc/rndc.conf 中,追加默认名称服务器连接

/etc/rndc.conf
...
options {
    default-key "console";
    default-server 127.0.0.1;
    default-port 953;
};

允许在 /etc/named.conf 中从 localhost 进行 rndc 控制

/etc/named.conf
...
controls {
    inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "console"; };
};
...

现在您可以使用 rndc 来控制本地 DNS 服务器。例如,要检查服务器状态

$ rndc status 

重新加载服务器配置也可以通过以下方式完成

# rndc reload 

限制访问 localhost

BIND 默认监听所有接口和 IP 地址的 53 端口。要仅允许从 localhost 连接,请将以下行添加到 /etc/named.confoptions 部分

listen-on { 127.0.0.1; };
listen-on-v6 { ::1; };

设置 DNS 转发

要让 BIND 将 DNS 查询转发到另一个 DNS 服务器,请将 forwarders 子句添加到 options 部分。

例如,要让 BIND 通过 DNS over TLS 转发到 Google Public DNS 服务器

tls google {
    remote-hostname "dns.google";
};

options {
...
    forward only;
    forwarders port 853 tls google {
        8.8.8.8; 2001:4860:4860::8888;
        8.8.4.4; 2001:4860:4860::8844;
    };
};
注意 此示例使用 Google Public DNS。请将其替换为您信任的 DNS 解析器。请参阅 域名解析#第三方 DNS 服务

也可以通过定义一个转发区域来转发特定区域。如果您想解析内部域或在 Internet 上不可公开访问的域,这会很有用

zone domain.tld {
    type forward;
    forwarders {
        10.20.30.40;
        10.20.30.45;
    };
    forward only;
};
注意 如果被转发的区域包含委派(即有子区域的 NS 记录),您需要使用 forward first。这样,BIND 在解析子区域查询时将遵循委派(进行正常递归),而不是返回 SERVFAIL。这对于托管内部 TLD 是必需的。

通过 TLS 或 HTTPS 提供 DNS 服务

要启用 BIND 中的 DNS over TLS 或 HTTPS 服务,请定义一个 tls 块来指定您的证书,然后添加 listen-on 子句来启用 DNS over TLS 和 HTTPS 侦听器(以及标准的 DNS 侦听器)。

/etc/named.conf
tls mycert {
    cert-file "path.crt";
    key-file "path.key";
};

options {
    // Standard port 53 listeners need to be re-added explicitly
    listen-on    { any; };
    listen-on-v6 { any; };
    
    // Add a DNS over TLS listener on standard port 853
    listen-on    tls mycert { any; };
    listen-on-v6 tls mycert { any; };
    
    // Add a DNS over HTTPS listener on standard HTTPS port 443
    listen-on    tls mycert http default { any; };
    listen-on-v6 tls mycert http default { any; };
    
    // If needed, add a cleartext HTTP listener for a reverse proxy
    //listen-on    port 8443 tls none http default { 127.0.0.1; };
    //listen-on-v6 port 8443 tls none http default { ::1; };
};
...

请注意,tls{} 定义在顶层,*不在* options{} 块内。

运行域的配置模板

下面是一个简单的家庭名称服务器设置,使用 domain.tld 作为向全世界提供的域,就像本 wiki 的 archlinux.org 域一样。

一个更详尽的例子是 BIND9 的 DNS 服务器,而 本篇展示了 如何设置内部网络名称解析。

创建区域文件

创建 /var/named/domain.tld.zone

$ORIGIN domain.tld.
$TTL 2h

@               SOA     ns1 hostmaster (
                                2018111111 ; Serial
                                8h         ; Refresh
                                30m        ; Retry
                                1w         ; Expire
                                1h )       ; Negative Cache TTL
                NS      ns1
                NS      ns2
                
@               A       203.0.113.1
                AAAA    2001:db8:113::1
                MX      10 mail
                TXT     "v=spf1 mx"

www             A       203.0.113.1
                AAAA    2001:db8:113::1

ns1             A       203.0.113.4
                AAAA    2001:db8:113::4

ns2             A       198.51.100.5
                AAAA    2001:db8:5100::5

mail            A       198.51.100.6
                AAAA    2001:db8:5100::6
imap            CNAME   mail
smtp            CNAME   mail

$ORIGIN 定义了所有名称的默认后缀,这些名称尚未以 .(点)结尾,例如 mail 将被展开为 mail.$ORIGINmail.domain.tld. 在所有地方。

$TTL 定义了所有没有指定自己 TTL 的记录的默认生存时间(即缓存过期时间)。这里是 2 小时。

每次更改区域的资源记录之前,必须手动递增序列号,然后重新加载 named。否则,辅助服务器(副本或从服务器)将不会重新传输区域:只有当序列号*大于*上次传输区域时的序列号时,它们才会重新传输。此示例使用相对常见的 YYYYMMDDXX 格式,但这不是必需的;序列号也可以从 1 开始。

配置主服务器

/etc/named.conf 中添加您的区域

 zone "domain.tld" IN {
         type primary;
         file "domain.tld.zone";
         allow-update { none; };
 };

重新加载 named.service 单元以应用配置更改。

配置辅助服务器

如果您有两个或多个服务器,您可以将除一个之外的所有服务器设置为辅助服务器,区域通过 AXFR 传输从主服务器检索。

在主服务器上,显式允许从辅助服务器传输区域

zone "domain.tld" IN {
        ...
        allow-transfer { 198.51.100.5; 20001:db8:113::4; };
};

在辅助服务器上,将区域添加到 /etc/named.conf

zone "domain.tld" IN {
        type secondary;
        file "domain.tld.zone";
        primaries { 203.0.113.4; 2001:db8:113::4; };
};

重新加载 named.service 或使用 rndc(8) 来重新加载主服务器和辅助服务器的配置。

允许递归

如果您运行自己的 DNS 服务器,您可能希望它代表客户端执行递归查找(即解析它不权威的域)——无论是为您自己的机器还是为本地网络。这需要在 BIND 中启用递归,并仔细限制允许使用它的客户端。

默认情况下,为了减轻 DNS 放大攻击,在默认的 Arch /etc/named.conf 中,除了环回接口之外,对所有客户端都禁用了递归。这通常配置为

allow-recursion { 127.0.0.1; ::1; };

要允许 LAN(例如 192.168.0.0/24)上的客户端进行递归查询,您必须显式定义一个 ACL,并将其与 allow-recursionallow-query-cache 一起使用。例如

/etc/named.conf
acl "trusted" {
    127.0.0.1;
    ::1;
    192.168.0.0/24;
    fd01:2345:6789::/64;
};
options {
    // Allow authoritative queries from any client
    allow-query       { any; };
    // Allow recursive lookups and cached results only for trusted clients
    allow-recursion   { trusted; };
    allow-query-cache { trusted; };
};

此设置允许

  • 对任何人进行权威响应(对于此服务器负责的区域)。
  • 仅对本地网络和环回接口上的受信任客户端进行递归查找和缓存结果。
注意 如果未显式定义 allow-recursionallow-query-cache,BIND 默认允许对 localhost 和 localnets 进行访问。localnets ACL 包括服务器网络接口在启动时分配的 IP 地址范围,但它不会自动包含所有私有网络范围(例如 192.168.0.0/24),除非您的接口被分配了该子网中的 IP。

请参阅 “allow-recursion”和“allow-query-cache”行为的变化是什么?

配置 BIND 以提供 DNSSEC 签名区域

BIND 可以轻松地使用 *密钥和签名策略* (KASP) 功能来提供 DNSSEC 签名区域,它会使用您定义的策略自动为您处理区域签名和密钥管理。

创建单独的目录来存储密钥,允许服务器写入

# mkdir /var/named/keys
# chown named:named /var/named/keys

指示 BIND 将密钥存储在上述目录中

/etc/named.conf
options {
    ...
    key-directory "/var/named/keys";
    ...
};

现在可以通过应用所需的策略来签名区域。在大多数情况下,您可以使用 default 策略来应用最新的 DNSSEC 最佳实践

/etc/named.conf
zone "domain.tld" IN {
        ...
        dnssec-policy default;
};

这将使用具有无限密钥生命周期的单个 ecdsap256sha256 组合签名密钥 (CSK) 来签名区域,通过 inline-signing 进行签名,服务器会单独生成签名区域,而无需设置动态 DNS。

如果需要,可以使用 dnssec-policy 块定义自定义策略。例如,main 策略使用传统的密钥签名密钥 (KSK,每年轮换) 和区域签名密钥 (ZSK,每月轮换) 分开来签名区域,同时还有计时参数和 NSEC3 否定存在性

/etc/named.conf
dnssec-policy main {
    keys {
        ksk lifetime P1Y algorithm ecdsap256sha256;
        zsk lifetime P1M algorithm ecdsap256sha256;
    };
    publish-safety 1h;
    retire-safety 1h;
    purge-keys 1h;
    signatures-refresh P3D;
    signatures-validity P3W;
    signatures-validity-dnskey P3W;
    inline-signing yes;
    nsec3param iterations 0 optout no salt-length 0;
};
...

自定义策略可以像之前默认策略一样应用

/etc/named.conf
zone "domain.tld" IN {
    ...
    dnssec-policy main;
};

递增区域的序列号并重新加载服务器配置。

最后一步是与父区域建立信任链。首先,检查区域的 DNSSEC 状态

$ rndc dnssec -status domain.tld
dnssec-policy: main
current time:  Tue Mar 25 08:51:53 2025

key: 58785 (ECDSAP256SHA256), KSK
  published:      yes - since Tue Mar 25 08:47:23 2025
  key signing:    yes - since Tue Mar 25 08:47:23 2025

  Next rollover scheduled on Wed Mar 25 06:42:23 2026
  - goal:           omnipresent
  - dnskey:         rumoured
  - ds:             hidden
  - key rrsig:      rumoured

key: 5017 (ECDSAP256SHA256), ZSK
  published:      yes - since Tue Mar 25 08:47:23 2025
  zone signing:   yes - since Tue Mar 25 08:47:23 2025

  Next rollover scheduled on Fri Apr 25 06:42:23 2025
  - goal:           omnipresent
  - dnskey:         rumoured
  - zone rrsig:     rumoured

这里,KSK 密钥 ID 是 58785。您的将不同。

生成 DS 记录(酌情替换密钥 ID)

$ dnssec-dsfromkey -2 /var/named/keys/Kdomain.tld.+013+58785
domain.tld. IN DS 58785 13 2 hash

将 DS 提交给父区域(例如,通过填写注册商的网页表单)。

当您确认 DS 记录已在父区域中发布后,您可以通过以下方式向 BIND 发出信号

$ rndc dnssec -checkds -key 58785 published domain.tld

自定义信任锚

如果您的 DNSSEC 签名区域是内部的,并且您需要利用 DNSSEC 验证,您需要将该信任锚添加到将用于解析它的解析器中。这可以通过添加 trust-anchors 块来完成

/etc/named.conf
trust-anchors {
    . initial-key 257 3 8 "AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc=";
    . initial-key 257 3 8 "AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=";
    domain.tld. initial-ds 58785 13 2 "hash";
};
注意 信任锚可以用完整的 DNSKEY 或 DS 记录指定。initial-keyinitial-ds 关键字通过 RFC 5011 机制在 KSK/算法轮换期间保持信任锚最新,而 static-keystatic-ds 则不会,并且需要手动更新信任锚。
注意 根的信任锚包含在内以示完整性;当在 /etc/named.conf 中指定 dnssec-validation yes 时,它们是必需的,而不是默认的 dnssec-validation auto

自动监听新接口

默认情况下,BIND 每小时扫描新接口并停止监听已不存在的接口。您可以通过添加以下内容来调整此值

/etc/named.conf
options {
    interface-interval rescan-timeout-in-minutes;
};

最大值为 28 天(40320 分钟)。您可以将此值设置为 0 来禁用此功能。

然后重新启动服务。

在 chroot 环境中运行 BIND

chroot 环境中运行不是必需的,但可以提高安全性。

本文章或章节需要扩充。

原因: /srv/ 对于 chroot 来说是个奇怪的地方,/var/lib/ 会是更常见的地方。(在 Talk:BIND 中讨论)

创建 jail

为此,我们首先需要创建一个用于存放 jail 的地方,我们将使用 /srv/named,然后将所需文件放入 jail 中。

# mkdir -p /srv/named/{dev,etc,usr/lib/engines,var/{run,log,named}}

复制必需的系统文件

# cp -av /etc/{localtime,named.conf} /srv/named/etc/
# cp -av /usr/lib/engines-1.1/* /srv/named/usr/lib/engines/
# cp -av /var/named/* /srv/named/var/named/.

/dev/ 中设置必需的节点

# mknod /srv/named/dev/null c 1 3
# mknod /srv/named/dev/random c 1 8

设置文件的所有权

# chown -R named:named /srv/named

这应该为 jail 创建所需的文件系统。

服务单元

接下来我们需要一个 *替换单元文件*,以便服务调用 bind,这将允许强制 bind 进入 chroot

/etc/systemd/system/named-chroot.service
ExecStart=/usr/bin/named -4 -f -u named -t "/srv/named"

现在,使用 daemon-reload 重新加载 systemd,并启动 named-chroot.service

本地提供根区域服务

如果您不想依赖 第三方 DNS 服务,您可以按照 RFC:7706 在本地提供根区域服务。这可以通过使用 BIND 作为 DNS 递归解析器来实现。

要管理递归解析器,您通常需要配置一个*根提示文件*。此文件包含根区域的权威名称服务器的名称和 IP 地址。

IANA 网站获取文件,并将其放入 /var/named

编辑您的服务器配置,添加相应的文件

/etc/named.conf
zone "." IN {
    type hint;
    file "named.root";
};

在配置中也应该允许递归。请参阅 #允许递归

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.