凌峰创科服务平台

Linux如何搭建DNS服务器?

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

Linux如何搭建DNS服务器?-图1
(图片来源网络,侵删)

第一步:选择 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 服务会自动启动,你可以使用以下命令检查其状态:

Linux如何搭建DNS服务器?-图2
(图片来源网络,侵删)
# 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 服务器,这意味着它负责回答特定域名的查询。

Linux如何搭建DNS服务器?-图3
(图片来源网络,侵删)

主要配置文件路径:

  • 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 解析

使用 dignslookup 工具进行测试。

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 服务器必须进行安全加固。

  1. 限制查询来源 (allow-query): 不要使用 { any; },将其限制为你的内部网络。

    options {
        // ...
        allow-query { 192.168.1.0/24; localhost; };
        // ...
    };
  2. 限制递归查询 (allow-recursion): 递归查询会消耗大量资源,容易被利用进行 DDoS 攻击(DNS 放大攻击),只允许受信任的客户端进行递归查询。

    options {
        // ...
        allow-recursion { 192.168.1.0/24; localhost; };
        // ...
    };
  3. 启用 DNSSEC (可选但推荐): DNSSEC (DNS Security Extensions) 可以防止 DNS 欺骗和缓存投毒攻击,配置相对复杂,但能极大地提升安全性。

  4. 运行在非特权端口 (可选): 你可以配置 BIND 使用一个高于 1024 的端口,以减少 root 权限的风险。


通过以上步骤,你已经成功在 Linux 服务器上搭建了一个功能完整的 DNS 服务器,这个服务器可以:

  • 为你的域名提供权威的 DNS 解答。
  • 为你的内部网络提供域名解析服务。
  • 缓存外部查询结果,提高访问速度。

你可以根据这个基础,进一步添加更多域名记录、配置从服务器、实现负载均衡等高级功能。

分享:
扫描分享到社交APP
上一篇
下一篇