BIND (Berkeley Internet Name Domain) 是目前世界上使用最广泛的 DNS (Domain Name System) 服务器软件。BIND9 是其第9个主要版本,也是当前最稳定和功能最完善的版本。它是一个开源软件,由互联网系统协会 (ISC - Internet Systems Consortium) 开发和维护。
BIND9 可以扮演 DNS 体系中的多种角色:
- 权威DNS服务器 (Authoritative DNS Server): 存储特定域名(例如
example.com
)的官方DNS记录。当其他DNS服务器或客户端查询这个域名的信息时,权威服务器会给出最终的、官方的答案。 - 递归DNS服务器 (Recursive DNS Server / Resolver): 代表客户端(如你的电脑)向其他DNS服务器发起查询,直到找到最终答案,然后将结果返回给客户端并缓存起来以备后续使用。ISP 通常会提供递归DNS服务器。
- 缓存DNS服务器 (Caching DNS Server): 递归服务器通常也扮演缓存服务器的角色,它会缓存查询过的记录,以加快后续相同查询的响应速度并减少网络流量。
- 转发DNS服务器 (Forwarding DNS Server): 将所有收到的查询请求转发给指定的其他DNS服务器处理,自身不进行递归查询。
一、核心组件和概念
-
named
(Name Daemon):- 这是 BIND9 的核心守护进程,负责处理所有 DNS 查询、区域数据管理、区域传送等。
- 通常以
named
用户和named
组(或类似名称,如bind
)的低权限运行,以增强安全性。
-
配置文件 (
named.conf
):- BIND9 的主配置文件,通常位于
/etc/bind/named.conf
(Debian/Ubuntu) 或/etc/named.conf
(RHEL/CentOS)。 - 它定义了服务器的全局选项、日志记录方式、访问控制列表 (ACL)、密钥、视图 (views) 以及管理的区域 (zones)。
- 语法类似于 C 语言,使用花括号
{}
和分号;
。
- BIND9 的主配置文件,通常位于
-
区域文件 (Zone Files):
- 包含特定 DNS 区域(如
example.com
或反向区域1.168.192.in-addr.arpa
)的实际 DNS 记录(如 A, AAAA, CNAME, MX, NS, SOA, TXT, SRV, PTR 等)。 - 通常存储在
/var/cache/bind/
(Debian/Ubuntu) 或/var/named/
(RHEL/CentOS)。 - 每个区域文件以 SOA (Start of Authority) 记录开始,定义了该区域的权威信息。
- 包含特定 DNS 区域(如
-
rndc
(Remote Name Daemon Control):- 一个命令行工具,用于管理和控制
named
守护进程。 - 可以用来重新加载配置、重载区域、刷新缓存、查看状态、停止服务等,而无需重启整个
named
进程。 rndc
通过一个安全的 TCP 连接与named
通信,使用共享密钥进行认证。
- 一个命令行工具,用于管理和控制
-
根提示文件 (Root Hints File):
- 包含全球根 DNS 服务器的名称和 IP 地址列表。
- 递归服务器在启动时或缓存过期时,会使用这个文件来找到根服务器,从而开始 DNS 解析过程。
- 通常命名为
db.root
或named.root
,并定期更新。
二、named.conf
配置文件详解
named.conf
主要由以下几个部分组成:
-
options { ... };
(全局选项)directory "/var/cache/bind";
: 指定区域文件和其他 BIND 文件的默认工作目录。pid-file "/run/named/named.pid";
:named
进程的 PID 文件路径。listen-on { any; };
或listen-on { 192.168.1.10; 127.0.0.1; };
: 指定named
监听 DNS 请求的 IP 地址和端口(默认为53)。any
表示监听所有可用网络接口。listen-on-v6 { any; };
: 类似listen-on
,但针对 IPv6。allow-query { any; };
或allow-query { trusted_clients; };
: 允许哪些客户端查询此服务器。any
表示允许所有。通常递归服务器会限制查询来源。allow-recursion { trusted_clients; };
或allow-recursion { none; };
: 允许哪些客户端使用此服务器进行递归查询。权威服务器通常设置为none
或仅限本地。recursion yes;
或recursion no;
: 是否启用递归查询功能。权威服务器应设为no
。forwarders { 8.8.8.8; 8.8.4.4; };
: 如果此服务器配置为转发器,则指定上游 DNS 服务器的 IP 地址。forward only;
或forward first;
:only
表示只转发,不自行递归;first
表示先尝试转发,失败后再自行递归。dnssec-validation auto;
或dnssec-enable yes; dnssec-validation yes;
: 启用 DNSSEC 支持和验证。querylog yes;
: 启用查询日志(会产生大量日志,通常用于调试)。
-
logging { ... };
(日志配置)- 定义日志通道 (channel) 和类别 (category),并将它们关联起来,以控制日志的输出位置、级别和格式。
- 例如,可以将不同类型的日志信息(如查询、安全事件、区域加载)发送到不同的文件或 syslog。
logging { channel simple_log { file "/var/log/named/named.log" versions 3 size 5m; // 日志文件路径,保留3个版本,每个最大5MB severity info; // 日志级别 print-time yes; // 打印时间戳 print-severity yes; // 打印日志级别 print-category yes; // 打印日志类别 }; category default { simple_log; }; category queries { simple_log; }; // 将查询日志也输出到 simple_log };
-
acl { ... };
(访问控制列表)- 定义 IP 地址或网络的命名集合,方便在
allow-query
,allow-recursion
,allow-transfer
等指令中引用。
acl "trusted_clients" { 127.0.0.1; 192.168.1.0/24; localhost; localnets; // BIND 内建 ACL,代表服务器所有直接连接的网络 };
- 定义 IP 地址或网络的命名集合,方便在
-
key { ... };
(密钥定义)- 用于
rndc
远程控制、TSIG (Transaction Signatures) 事务签名(用于安全的区域传送或动态更新)。
key "rndc-key" { algorithm hmac-sha256; secret "your-secret-key-string"; // 通常由 rndc-confgen 生成 }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
- 用于
-
zone { ... };
(区域定义)-
这是配置的核心,用于定义 BIND9 管理的各个 DNS 区域。
-
权威主服务器 (Master/Primary) 区域:
zone "example.com" IN { type master; // 区域类型:主服务器 file "/var/cache/bind/db.example.com"; // 区域数据文件名 allow-update { none; }; // 是否允许动态更新 (DDNS) allow-transfer { slaves_acl; }; // 允许哪些从服务器进行区域传送 also-notify { ip_of_slave1; ip_of_slave2; }; // 主动通知从服务器更新 };
-
权威从服务器 (Slave/Secondary) 区域:
zone "example.com" IN { type slave; // 区域类型:从服务器 file "slaves/db.example.com"; // 从主服务器获取的区域数据副本的存储位置 masters { ip_of_master; }; // 指定主服务器的 IP 地址 // allow-notify { ip_of_master; }; // 可选,允许主服务器通知 };
-
根提示区域 (Hint Zone):
zone "." IN { type hint; // 区域类型:根提示 file "/etc/bind/db.root"; // 根提示文件名 };
-
转发区域 (Forward Zone):
zone "internal.example.com" IN { type forward; // 区域类型:转发 forwarders { 10.0.0.53; }; // 针对此特定区域的转发服务器 forward only; // 或 first };
-
反向区域 (Reverse Zone):
// IPv4 反向区域 zone "1.168.192.in-addr.arpa" IN { // 对应 192.168.1.0/24 网络 type master; file "/var/cache/bind/db.192.168.1"; allow-update { none; }; };
-
-
view { ... };
(视图)- 允许 BIND9 根据客户端的源 IP 地址提供不同的 DNS 应答。这常用于实现 “Split DNS” 或 “Split Horizon DNS”。
- 例如,内部网络客户端查询
server.example.com
可能得到一个私有 IP 地址,而外部网络客户端查询同一个名称则得到一个公共 IP 地址。
acl "internal_net" { 192.168.0.0/16; 127.0.0.1; }; acl "external_net" { any; }; // 'any' 应该放在最后或更精确地定义 view "internal_view" { match-clients { internal_net; }; // 匹配来自 internal_net 的客户端 recursion yes; // 内部视图通常允许递归 // 内部视图的区域定义 zone "example.com" IN { type master; file "internal/db.example.com"; // 内部区域文件 }; zone "." IN { type hint; file "/etc/bind/db.root"; }; // 其他内部特定区域... }; view "external_view" { match-clients { external_net; }; // 匹配其他所有客户端 recursion no; // 外部视图(如果也是权威服务器)通常禁止递归 // 外部视图的区域定义 zone "example.com" IN { type master; file "external/db.example.com"; // 外部区域文件 }; // 不包含内部区域,可能包含根提示(如果也做递归)或不包含(纯权威) };
注意:
view
的match-clients
顺序很重要,BIND 会使用第一个匹配的视图。
三、区域文件 (Zone File) 格式
区域文件包含 DNS 资源记录 (Resource Records, RR)。
-
$TTL
指令: 定义区域中记录的默认生存时间 (Time To Live),单位为秒。 -
$ORIGIN
指令: 定义区域的域名。通常在文件开头设置,后续不包含完整域名的记录会默认追加此ORIGIN
。 -
记录格式:
[name] [ttl] [class] type data
name
: 主机名或子域名。如果是@
,代表$ORIGIN
本身。如果为空,则继承上一条记录的name
。ttl
: 可选,覆盖$TTL
。class
: 网络类别,通常是IN
(Internet)。type
: 记录类型。data
: 记录的具体数据。
-
常用记录类型:
-
SOA
(Start of Authority):- 格式:
@ IN SOA primary-ns.example.com. admin-email.example.com. ( serial refresh retry expire minimum-ttl )
primary-ns.example.com.
: 主域名服务器的 FQDN (注意末尾的点)。admin-email.example.com.
: 管理员邮箱地址 (用.
代替@
)。serial
: 区域文件的序列号。每次修改区域文件时必须增加此值,从服务器通过比较序列号来判断是否需要更新。通常使用 YYYYMMDDNN 格式。refresh
: 从服务器检查主服务器更新的间隔时间。retry
: 如果从服务器无法连接到主服务器,重试的间隔时间。expire
: 如果从服务器持续无法联系到主服务器,多久后该区域数据被视为无效。minimum-ttl
(Negative Caching TTL): 其他服务器缓存此区域中“名称不存在”(NXDOMAIN) 响应的时长。
- 格式:
-
NS
(Name Server):- 格式:
@ IN NS ns1.example.com.
- 格式:
subdomain IN NS ns2.example.com.
(委派子域名) - 指定该区域的权威域名服务器。
- 格式:
-
A
(Address):- 格式:
hostname IN A 192.168.1.100
- 将主机名映射到 IPv4 地址。
- 格式:
-
AAAA
(IPv6 Address):- 格式:
hostname IN AAAA 2001:db8::1
- 将主机名映射到 IPv6 地址。
- 格式:
-
CNAME
(Canonical Name):- 格式:
aliasname IN CNAME realname.example.com.
- 创建别名。
aliasname
是realname.example.com.
的别名。 - 注意:
CNAME
记录不能与其他记录类型(如MX
,NS
,A
)共存于同一个名称下(除了 DNSSEC 相关的NSEC
,RRSIG
等)。
- 格式:
-
MX
(Mail Exchange):- 格式:
@ IN MX 10 mail.example.com.
- 格式:
@ IN MX 20 backupmail.example.com.
- 指定接收该域名邮件的邮件服务器。数字 (10, 20) 是优先级,数值越小优先级越高。
- 格式:
-
PTR
(Pointer):- 用于反向 DNS 解析 (IP 地址到主机名)。
- 格式 (在
1.168.192.in-addr.arpa
区域文件中):100 IN PTR hostname.example.com.
(对应192.168.1.100
)
-
TXT
(Text):- 格式:
@ IN TXT "Some descriptive text"
- 格式:
_spf IN TXT "v=spf1 mx -all"
(用于 SPF 记录) - 存储任意文本信息,常用于 SPF, DKIM, DMARC 等。
- 格式:
-
SRV
(Service):- 格式:
_service._proto.name. IN SRV priority weight port target.
- 例如:
_sip._tcp.example.com. IN SRV 10 60 5060 sipserver.example.com.
- 用于定位特定服务(如 SIP, XMPP, LDAP)。
- 格式:
-
四、安装与基本配置步骤 (以 Debian/Ubuntu 为例)
-
安装 BIND9:
sudo apt update sudo apt install bind9 bind9utils bind9-doc dnsutils
bind9
: 核心服务器软件包。bind9utils
: 包含dig
,nslookup
(虽然dnsutils
也提供) 和named-checkconf
,named-checkzone
等工具。bind9-doc
: BIND9 文档。dnsutils
: 包含dig
和nslookup
。
-
配置
named.conf.options
(或named.conf
中的options
块):- 编辑
/etc/bind/named.conf.options
。 - 设置
listen-on
,allow-query
,recursion
,forwarders
等。 - 示例:配置一个本地网络的缓存递归服务器:
// /etc/bind/named.conf.options options { directory "/var/cache/bind"; listen-on { 127.0.0.1; 192.168.1.10; }; // 监听本地和内网IP listen-on-v6 { none; }; // 如果不需要IPv6 allow-query { localhost; 192.168.1.0/24; }; // 允许本地和内网查询 recursion yes; allow-recursion { localhost; 192.168.1.0/24; }; // 允许本地和内网递归 forwarders { 8.8.8.8; // Google Public DNS 1.1.1.1; // Cloudflare DNS }; // dnssec-validation auto; // 推荐开启 };
- 编辑
-
配置区域 (如果作为权威服务器):
- 编辑
/etc/bind/named.conf.local
(或直接在named.conf
中,但不推荐)。 - 添加
zone
定义。 - 创建区域文件 (如
/var/cache/bind/db.example.com
)。 - 示例
named.conf.local
:// /etc/bind/named.conf.local zone "example.com" { type master; file "/var/cache/bind/db.example.com"; allow-transfer { none; }; // 根据需要设置 }; zone "1.168.192.in-addr.arpa" { type master; file "/var/cache/bind/db.192.168.1"; };
- 示例区域文件
/var/cache/bind/db.example.com
:$TTL 86400 ; 1 day @ IN SOA ns1.example.com. admin.example.com. ( 2023031501 ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ; Name servers @ IN NS ns1.example.com. @ IN NS ns2.example.com. ; 如果有第二个NS ; Mail servers @ IN MX 10 mail.example.com. ; A records @ IN A 192.168.1.10 ns1 IN A 192.168.1.10 ns2 IN A 192.168.1.11 ; 假设有第二个NS服务器 www IN A 192.168.1.20 mail IN A 192.168.1.30 ftp IN CNAME www.example.com.
- 示例反向区域文件
/var/cache/bind/db.192.168.1
:$TTL 86400 @ IN SOA ns1.example.com. admin.example.com. ( 2023031501 ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum TTL ; Name servers @ IN NS ns1.example.com. ; PTR records 10 IN PTR ns1.example.com. ; 192.168.1.10 11 IN PTR ns2.example.com. ; 192.168.1.11 20 IN PTR www.example.com. ; 192.168.1.20 30 IN PTR mail.example.com. ; 192.168.1.30
- 编辑
-
检查配置文件和区域文件语法:
sudo named-checkconf /etc/bind/named.conf sudo named-checkzone example.com /var/cache/bind/db.example.com sudo named-checkzone 1.168.192.in-addr.arpa /var/cache/bind/db.192.168.1
如果没有任何输出,表示语法正确。
-
设置
rndc
(如果尚未配置):- 通常安装时会自动生成
/etc/bind/rndc.key
并在named.conf
中引用。 - 如果需要手动生成:
sudo rndc-confgen -a -c /etc/bind/rndc.key
- 确保
named.conf
中有类似这样的controls
块:include "/etc/bind/rndc.key"; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; };
- 通常安装时会自动生成
-
重启或重载 BIND9 服务:
sudo systemctl restart bind9 # 或者,如果只是修改了区域文件或部分配置,可以尝试重载 # sudo rndc reload # sudo rndc reload example.com // 重载特定区域
-
测试 DNS 解析:
- 在服务器本机测试:
dig @127.0.0.1 www.example.com dig @127.0.0.1 -x 192.168.1.20 nslookup www.example.com 127.0.0.1
- 在客户端机器上,将 DNS 服务器设置为 BIND9 服务器的 IP 地址,然后测试。
- 在服务器本机测试:
-
查看日志:
- 检查
/var/log/syslog
或 BIND9 配置的特定日志文件 (如/var/log/named/named.log
)。
- 检查
五、安全注意事项
- 最小权限原则: 确保
named
以非 root 用户运行。 - 限制递归: 如果是权威服务器,务必禁用或严格限制递归 (
allow-recursion { trusted_nets; };
或recursion no;
),防止被用作DDoS放大攻击的源头。 - 限制查询:
allow-query
应该根据服务器角色来设置。公共权威服务器通常是any
,但递归服务器应限制为受信任的客户端。 - 限制区域传送:
allow-transfer
应仅限于你的从服务器 IP 地址。 - 隐藏版本号: 在
options
中添加version "not currently available";
。 - 使用
rndc
: 通过rndc
管理服务,避免不必要的重启。确保rndc.key
文件权限安全。 - 及时更新: BIND9 经常发布安全补丁,保持软件最新非常重要。
- DNSSEC: 部署 DNSSEC (Domain Name System Security Extensions) 来防止 DNS 欺骗和缓存投毒。配置 DNSSEC 相对复杂,但对安全性提升很大。
- 响应速率限制 (RRL - Response Rate Limiting): BIND9 支持 RRL 功能,可以缓解某些类型的 DNS 放大攻击。
- 防火墙: 在服务器上配置防火墙,只允许必要的端口(如 TCP/UDP 53,TCP 953 for rndc)从特定源访问。
六、高级特性
- DNSSEC (Domain Name System Security Extensions): 为 DNS 数据提供来源验证和数据完整性保护。
- TSIG (Transaction Signatures): 使用共享密钥对 DNS 消息(如区域传送、动态更新)进行签名,确保通信安全。
- DDNS (Dynamic DNS): 允许客户端动态更新其 DNS 记录,常用于 IP 地址不固定的主机。
- Views: 如前所述,根据客户端 IP 提供不同 DNS 视图。
- DLZ (Dynamically Loadable Zones): 允许 BIND9 从外部数据库(如 LDAP, MySQL, PostgreSQL)动态加载区域数据,而不是从传统的区域文件。
- RPZ (Response Policy Zones): 允许管理员定义策略来修改或阻止对特定恶意域名的解析。
BIND9 是一个功能强大且灵活的 DNS 服务器,但配置也相对复杂。理解其核心概念、配置文件结构和区域文件格式是成功部署和管理 BIND9 的关键。对于初学者,建议从简单的缓存递归服务器或单个权威区域开始,逐步深入。务必参考官方文档以获取最准确和最新的信息。