下面我将为你提供一个详细的、手把手的教程,使用 BIND 在主流的 Linux 发行版(如 Ubuntu/Debian 和 CentOS/RHEL)上搭建一个功能完整的 DNS 服务器。

第一步:选择 DNS 服务器软件
虽然 BIND 是最经典的选择,但还有其他优秀的选项,各有千秋:
- BIND: 功能最强大、最稳定、最灵活,是互联网上使用最广泛的 DNS 服务器,适合各种规模的服务器,从个人到顶级域名根服务器,但配置相对复杂。
- Unbound: 一个专注于递归解析的、高性能、高安全性的 DNS 解析器,它验证 DNSSEC,非常适合作为网络内部的缓存 DNS 服务器或家庭/办公室的 DNS 网关。
- dnsmasq: 轻量级、易于配置,它同时提供了 DNS、DHCP 和 TFTP 服务,非常适合小型网络、家庭路由器或需要快速部署简单 DNS/DHCP 服务的场景。
本教程将使用 BIND,因为它功能最全面,能涵盖 DNS 服务的所有核心概念。
第二步:安装 BIND
根据你的 Linux 发行版,选择对应的命令。
对于 Ubuntu/Debian 系统
# 更新软件包列表 sudo apt update # 安装 bind9 和 dnsutils (dnsutils 包含了 dig, nslookup 等有用的工具) sudo apt install bind9 dnsutils -y
对于 CentOS/RHEL/Fedora 系统
# 首先确保你的系统已安装 EPEL 仓库 sudo yum install epel-release -y # 安装 bind 和 bind-utils (bind-utils 包含了 dig, nslookup 等工具) sudo yum install bind bind-utils -y
安装完成后,BIND 服务会自动启动,你可以使用以下命令检查其状态:

# Ubuntu/Debian sudo systemctl status bind9 # CentOS/RHEL sudo systemctl status named
如果看到 active (running),说明安装成功。
第三步:配置 BIND
BIND 的核心配置文件是 named.conf,它通常位于 /etc/bind/ (Ubuntu/Debian) 或 /etc/ (CentOS/RHEL) 目录下。
备份原始配置
在修改任何配置文件之前,养成备份的好习惯。
# Ubuntu/Debian sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bak # CentOS/RHEL sudo cp /etc/named.conf /etc/named.conf.bak
编辑主配置文件
我们将配置一个 权威 DNS 服务器,这意味着它负责回答特定域名的查询。

主要配置文件路径:
- Ubuntu/Debian:
/etc/bind/named.conf.options - CentOS/RHEL:
/etc/named.conf
打开文件进行编辑:
# Ubuntu/Debian sudo nano /etc/bind/named.conf.options # CentOS/RHEL sudo nano /etc/named.conf
核心配置内容:
你需要修改或添加以下几部分:
a) 监听地址
默认情况下,BIND 只监听在本地回环地址 0.0.1,如果你想让它响应来自网络内其他计算机的请求,需要修改 listen-on 选项。
// 在 options 块内
options {
// ... 其他配置 ...
// 允许任何 IP 地址访问 (生产环境应限制为你的网络)
listen-on port 53 { any; };
// 允许任何 IP 地址进行 DNS 查询 (生产环境应限制为你的网络)
allow-query { any; };
// ... 其他配置 ...
};
b) 转发查询
你的 DNS 服务器不可能知道所有域名的 IP 地址,对于它不认识的域名,需要将其转发给一个公共 DNS 服务器(如 Google 8.8.8 或 Cloudflare 1.1.1)。
// 在 options 块内
options {
// ... 其他配置 ...
// 将所有非本域的查询转发到 Google DNS
forwarders {
8.8.8.8;
8.8.4.4;
};
// forward first 表示先查本地缓存,没有则转发
// forward only 表示只转发,不自己递归查询
forward only;
// ... 其他配置 ...
};
c) 定义区域文件 这是最关键的一步,你需要告诉 BIND 它负责管理哪些域名(区域)以及这些域名的信息存放在哪个文件里。
假设我们要管理域名 example.com,其主 DNS 服务器 IP 为 168.1.100。
在主配置文件的末尾(在 include 语句之前),添加以下内容:
// 定义 example.com 的正向解析区域
zone "example.com" {
type master; // 表明这是一个主 DNS 服务器
file "/etc/bind/db.example.com"; // 存储域名记录的文件路径
};
// 定义 example.com 的反向解析区域 (IP -> 域名)
// 192.168.1.0/24 网段的反向区域文件是 db.192.168.1
zone "1.168.192.in-addr.arpa" {
type master;
file "/etc/bind/db.192.168.1";
};
注意: 在 CentOS/RHEL 中,区域文件通常存放在
/var/named/目录下,并且文件名需要以.zone例如/var/named/example.com.zone和/var/named/192.168.1.zone。
创建区域数据文件
我们需要创建上面定义的两个区域文件。
a) 创建正向解析文件
# Ubuntu/Debian sudo cp /etc/bind/db.local /etc/bind/db.example.com sudo nano /etc/bind/db.example.com # CentOS/RHEL sudo cp /var/named/named.localhost /var/named/example.com.zone sudo nano /var/named/example.com.zone
如下:
;
; BIND data file for example.com
;
$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.example.com.
@ IN A 192.168.1.100
@ IN MX 10 mail.example.com.
; 主机记录
ns1 IN A 192.168.1.100
www IN A 192.168.1.101
mail IN A 192.168.1.102
; CNAME 记录 (别名)
www2 IN CNAME www.example.com.
字段解释:
$TTL: 默认的生存时间,604800 秒 = 7 天。SOA: Start of Authority (授权开始),区域的权威记录。ns1.example.com.是主域名服务器,admin.example.com.是管理员邮箱。Serial: 序列号,每次修改区域文件后,必须增加这个数字,以便从服务器知道数据已更新。NS: Name Server (域名服务器),指定负责该域的 DNS 服务器。A: Address (地址),将主机名映射到 IPv4 地址。MX: Mail Exchanger (邮件交换器),指定处理该域邮件的服务器。CNAME: Canonical Name (规范名称),为域名创建别名。
b) 创建反向解析文件
# Ubuntu/Debian sudo cp /etc/bind/db.127 /etc/bind/db.192.168.1 sudo nano /etc/bind/db.192.168.1 # CentOS/RHEL sudo cp /var/named/named.empty /var/named/192.168.1.zone sudo nano /var/named/192.168.1.zone
如下:
;
; BIND reverse data file for 192.168.1.0/24
;
$TTL 604800
@ IN SOA ns1.example.com. admin.example.com. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS ns1.example.com.
; PTR 记录 (指针记录)
100 IN PTR ns1.example.com.
101 IN PTR www.example.com.
102 IN PTR mail.example.com.
字段解释:
zone的名称是网络地址的反向写法,加上.in-addr.arpa。PTR: Pointer (指针),将 IP 地址映射到域名。
第四步:启动并测试服务
检查配置文件语法
在重启服务前,务必检查配置文件是否有语法错误。
# Ubuntu/Debian sudo named-checkconf # CentOS/RHEL sudo named-checkconf
如果没有任何输出,说明主配置文件语法正确。
然后检查区域文件:
# Ubuntu/Debian sudo named-checkzone example.com /etc/bind/db.example.com sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1 # CentOS/RHEL sudo named-checkzone example.com /var/named/example.com.zone sudo named-checkzone 1.168.192.in-addr.arpa /var/named/192.168.1.zone
如果看到 OK,说明区域文件也正确。
重启 BIND 服务
# Ubuntu/Debian sudo systemctl restart bind9 # CentOS/RHEL sudo systemctl restart named
测试 DNS 解析
使用 dig 或 nslookup 工具进行测试。
a) 测试正向解析
# 查询 example.com 的 A 记录 dig @127.0.0.1 example.com # 查询 www.example.com 的 A 记录 dig @127.0.0.1 www.example.com # 查询 MX 记录 dig @127.0.0.1 example.com MX
你应该能看到在 ANSWER SECTION 中返回了你配置的 IP 地址。
b) 测试反向解析
# 查询 IP 192.168.1.101 对应的域名 dig @127.0.0.1 -x 192.168.1.101
你应该能看到在 ANSWER SECTION 中返回了 www.example.com.。
c) 测试 CNAME 记录
dig @127.0.0.1 www2.example.com
你应该看到 www2.example.com 的 CNAME 指向 www.example.com,并且最终解析到 168.1.101。
第五步:设置防火墙
如果你的服务器启用了防火墙,需要开放 TCP 和 UDP 的 53 端口。
对于 UFW (Ubuntu/Debian 默认)
sudo ufw allow 53/tcp sudo ufw allow 53/udp sudo ufw reload
对于 firewalld (CentOS/RHEL 默认)
sudo firewall-cmd --permanent --add-service=dns sudo firewall-cmd --reload
第六步:安全加固 (重要)
一个生产环境的 DNS 服务器必须进行安全加固。
-
限制查询来源 (
allow-query): 不要使用{ any; },将其限制为你的内部网络。options { // ... allow-query { 192.168.1.0/24; localhost; }; // ... }; -
限制递归查询 (
allow-recursion): 递归查询会消耗大量资源,容易被利用进行 DDoS 攻击(DNS 放大攻击),只允许受信任的客户端进行递归查询。options { // ... allow-recursion { 192.168.1.0/24; localhost; }; // ... }; -
启用 DNSSEC (可选但推荐): DNSSEC (DNS Security Extensions) 可以防止 DNS 欺骗和缓存投毒攻击,配置相对复杂,但能极大地提升安全性。
-
运行在非特权端口 (可选): 你可以配置 BIND 使用一个高于 1024 的端口,以减少 root 权限的风险。
通过以上步骤,你已经成功在 Linux 服务器上搭建了一个功能完整的 DNS 服务器,这个服务器可以:
- 为你的域名提供权威的 DNS 解答。
- 为你的内部网络提供域名解析服务。
- 缓存外部查询结果,提高访问速度。
你可以根据这个基础,进一步添加更多域名记录、配置从服务器、实现负载均衡等高级功能。
