凌峰创科服务平台

Linux内网DNS服务器如何搭建与配置?

我将为你提供一个从基础到进阶的完整指南,涵盖最常用的 DNS 服务器软件 BIND (Berkeley Internet Name Domain)

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

第一部分:基础 DNS 服务器搭建 (仅提供内网域名解析)

假设我们的目标是:

  • 内网网段: 168.1.0/24
  • DNS 服务器 IP: 168.1.10
  • 内网域名: local.lan
  • 需要解析的主机:
    • server.local.lan -> 168.1.10
    • nas.local.lan -> 168.1.20
    • pc1.local.lan -> 168.1.30

步骤 1: 安装 BIND

BIND 是最主流、功能最强大的 DNS 服务器软件。

在基于 Debian/Ubuntu 的系统上:

sudo apt update
sudo apt install bind9 bind9utils

在基于 RHEL/CentOS/Fedora 的系统上:

Linux内网DNS服务器如何搭建与配置?-图2
(图片来源网络,侵删)
sudo yum install bind bind-utils
# 或者对于 dnf
sudo dnf install bind bind-utils

步骤 2: 配置 BIND

BIND 的主要配置文件是 /etc/bind/named.conf/etc/named.conf,我们主要编辑它的两个部分:optionszone

  1. 编辑主配置文件

    打开主配置文件:

    sudo nano /etc/bind/named.conf

    确保文件内容大致如下,特别是 listen-onallow-query 部分,我们只监听内网 IP,并只响应内网查询。

    Linux内网DNS服务器如何搭建与配置?-图3
    (图片来源网络,侵删)
    //
    // Please read /usr/share/doc/bind9/README.Debian.gz for information on
    // the up-to-date versions of the configuration files and zones.
    //
    // Do any local changes in /etc/bind/named.conf.local, instead of here.
    // 
    include "/etc/bind/named.conf.options";
    include "/etc/bind/named.conf.local";
    include "/etc/bind/named.conf.default-zones";
    // --- 以下是关键的修改部分 ---
    // 只监听内网接口 192.168.1.10
    // 将 127.0.0.1::1 替换为你的内网IP
    listen-on port 53 { 127.0.0.1; 192.168.1.10; };
    // 如果允许IPv6,可以取消下面这行的注释并填入内网IPv6地址
    // listen-on port 53 { 127.0.0.1; ::1; 192.168.1.10; };
    // 只允许内网网段 192.168.1.0/24 进行DNS查询
    allow-query { localhost; 192.168.1.0/24; };
    // 允许从本机进行递归查询(非常重要,否则无法解析外网域名)
    recursion yes;
    // 限制递归查询的来源,防止滥用
    allow-recursion { localhost; 192.168.1.0/24; };
    // 其他优化选项
    dnssec-validation auto;
    auth-nxdomain no;    # conform to RFC1035

    注意: listen-on 指定了服务器在哪个 IP 地址上监听 DNS 请求。allow-query 指定了哪些 IP 地址可以向这个服务器发起查询请求。

  2. 定义区域文件

    区域文件定义了哪个 DNS 后缀(如 local.lan)由这个服务器负责解析。

    继续编辑 /etc/bind/named.conf.local 文件:

    sudo nano /etc/bind/named.conf.local

    在文件末尾添加以下内容,定义一个“正向区域”和一个“反向区域”。

    //
    // Do any local configuration here
    //
    // Consider adding the 1918 zones here, if they are not used in your
    // organization
    // include "/etc/bind/zones.rfc1918";
    // --- 添加我们自己的区域定义 ---
    // 正向区域:将 local.lan 域名解析为 IP 地址
    zone "local.lan" {
        type master;
        file "/etc/bind/db.local.lan";
    };
    // 反向区域:将 192.168.1.0/24 网段内的 IP 解析为 local.lan 域名
    // 注意这里的网络地址是 1.168.192.in-addr.arpa 的格式
    zone "1.168.192.in-addr.arpa" {
        type master;
        file "/etc/bind/db.192.168.1";
    };
  3. 创建区域数据文件

    我们需要创建上面定义的两个区域数据文件。

    • 创建正向区域文件

      # 复制一个模板文件
      sudo cp /etc/bind/db.local /etc/bind/db.local.lan
      # 编辑新文件
      sudo nano /etc/bind/db.local.lan

      修改为:

      ;
      ; BIND data file for local.lan
      ;
      $TTL    604800
      @       IN      SOA     ns1.local.lan. admin.local.lan. (
                            2         ; Serial
                       604800         ; Refresh
                        86400         ; Retry
                      2419200         ; Expire
                       604800 )       ; Negative Cache TTL
      ;
      @       IN      NS      ns1.local.lan.
      @       IN      A       192.168.1.10
      @       IN      AAAA    ::1
      ; --- 添加我们的内网主机记录 ---
      ns1     IN      A       192.168.1.10
      server  IN      A       192.168.1.10
      nas     IN      A       192.168.1.20
      pc1     IN      A       192.168.1.30
    • 创建反向区域文件

      # 复制一个模板文件
      sudo cp /etc/bind/db.127 /etc/bind/db.192.168.1
      # 编辑新文件
      sudo nano /etc/bind/db.192.168.1

      修改为:

      ;
      ; BIND reverse data file for 192.168.1.0/24
      ;
      $TTL    604800
      @       IN      SOA     ns1.local.lan. admin.local.lan. (
                            1         ; Serial
                       604800         ; Refresh
                        86400         ; Retry
                      2419200         ; Expire
                       604800 )       ; Negative Cache TTL
      ;
      @       IN      NS      ns1.local.lan.
      ; --- 添加我们的反向解析记录 ---
      10      IN      PTR     server.local.lan.
      20      IN      PTR     nas.local.lan.
      30      IN      PTR     pc1.local.lan.

      注意: PTR 记录的 IP 地址部分是反写的,并且没有 .0 (网络位)。

步骤 3: 启动并测试服务

  1. 检查配置文件语法 在重启服务前,务必检查配置是否正确。

    # 对于 Debian/Ubuntu
    sudo named-checkconf
    # 对于 RHEL/CentOS
    sudo named-checkconf -c /etc/named.conf
    # 检查区域文件语法
    sudo named-checkzone local.lan /etc/bind/db.local.lan
    sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1

    如果没有输出,说明语法正确。

  2. 启动并启用 BIND 服务

    # 对于 Debian/Ubuntu (使用 systemd)
    sudo systemctl start bind9
    sudo systemctl enable bind9
    # 对于 RHEL/CentOS (使用 systemd)
    sudo systemctl start named
    sudo systemctl enable named
  3. 在客户端测试

    将你电脑的 DNS 服务器地址临时修改为 168.1.10

    • 测试正向解析

      nslookup server.local.lan
      # 应该返回: 192.168.1.10
      nslookup nas.local.lan
      # 应该返回: 192.168.1.20
    • 测试反向解析

      nslookup 192.168.1.20
      # 应该返回: nas.local.lan
    • 测试外网解析

      nslookup www.baidu.com
      # 应该返回百度的公网IP地址,证明递归查询正常工作

如果所有测试都通过,恭喜你,你的基础内网 DNS 服务器已经搭建成功了!


第二部分:进阶功能 (广告过滤)

要实现广告过滤,我们需要一个包含大量广告域名黑名单的 zone 文件。Pi-hole 项目提供了现成的黑名单,我们可以利用它。

  1. 下载广告域名列表 你可以从 https://firebog.net/ 网站找到很多优秀的广告列表,这里我们使用一个组合列表。

    # 创建一个目录存放广告列表
    sudo mkdir -p /etc/bind/adlists
    # 下载几个主要的列表 (使用 curl 或 wget)
    curl -o /etc/bind/adlists/adlist.txt https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
    curl -o /etc/bind/adlists/list1.txt https://hosts-file.net/ad_servers.txt
    # ... 可以继续添加更多列表
  2. 合并并处理列表 我们需要将这些列表转换成 BIND 的 zone 文件格式,这个过程有点繁琐,通常需要编写一个脚本来完成:

    • 读取所有列表文件。
    • 提取出域名部分(去掉 IP 地址)。
    • 去重。
    • 为每个域名生成 CNAME 记录,指向一个不存在的地址,如 blackhole.local.lan

    一个简化的合并脚本示例 (/usr/local/bin/create_ad_block_zone.sh):

    #!/bin/bash
    ADLIST_DIR="/etc/bind/adlists"
    ZONE_FILE="/etc/bind/db.adblock"
    BLACKHOLE_DOMAIN="blackhole.local.lan."
    # 清空或创建区域文件
    echo "; Ad Block Zone File - Generated on $(date)" > $ZONE_FILE
    echo "\$TTL    604800" >> $ZONE_FILE
    echo "@       IN      SOA     ns1.local.lan. admin.local.lan. ( $(date +%s) 604800 86400 2419200 604800 )" >> $ZONE_FILE
    echo "@       IN      NS      ns1.local.lan." >> $ZONE_FILE
    echo "" >> $ZONE_FILE
    # 遍历所有列表文件,提取域名并生成 CNAME 记录
    for file in $ADLIST_DIR/*.txt; do
        # 使用 sed 提取域名,跳过注释和空行
        sed -e 's/#.*$//' -e '/^[[:space:]]*$/d' "$file" | awk '{print $2}' | \
        grep -v '^localhost$' | grep -v '^localdomain$' | \
        while read -r domain; do
            # 检查域名是否已存在
            if ! grep -qF " ${domain} IN CNAME" $ZONE_FILE; then
                echo "*.${domain}. IN CNAME ${BLACKHOLE_DOMAIN}." >> $ZONE_FILE
            fi
        done
    done
    echo "Ad block zone file generated: $ZONE_FILE"

    给脚本执行权限并运行:

    sudo chmod +x /usr/local/bin/create_ad_block_zone.sh
    sudo /usr/local/bin/create_ad_block_zone.sh
  3. 在 named.conf 中加载广告过滤区域 编辑 /etc/bind/named.conf.local,在文件末尾添加:

    // 广告过滤区域
    zone "adblock" {
        type master;
        file "/etc/bind/db.adblock";
        // 这个区域只允许查询,不允许动态更新
        allow-query { any; };
        allow-transfer { none; };
    };

    注意,这里我们使用了 通配符,这意味着所有在 db.adblock 文件中定义的域名(及其所有子域名)都会被解析到 blackhole.local.lan

  4. 重新加载 BIND 配置

    sudo rndc reload
    # 或者重启服务
    sudo systemctl restart bind9
  5. 测试广告过滤 将你的 DNS 服务器指向 168.1.10,然后尝试访问一个已知的广告网站,或者使用 dig/nslookup 查询一个广告域名。

    # 假设 doubleclick.net 是一个广告域名
    nslookup doubleclick.net
    # 应该返回 blackhole.local.lan 的地址(如果它也在你的列表里)

第三部分:常用管理命令

  • 检查配置: sudo named-checkconf
  • 检查区域: sudo named-checkzone <zone_name> <zone_file>
  • 重新加载配置 (不中断服务): sudo rndc reload
  • 查看日志: sudo tail -f /var/log/syslog (Debian/Ubuntu) 或 sudo journalctl -u named -f (RHEL/CentOS)
  • 测试查询:
    • dig @192.168.1.10 nas.local.lan (指定 DNS 服务器进行查询)
    • host nas.local.lan 192.168.1.10 (使用 host 命令)

总结与最佳实践

  1. 静态 IP: 确保 DNS 服务器使用一个固定的内网 IP 地址。
  2. 安全: 不要将 allow-query 设置为 any,除非你有特殊需求,限制在你的内网网段。
  3. 日志: 定期查看日志,可以帮助你排查问题或发现异常的查询行为。
  4. 高可用: 对于生产环境,可以考虑配置两台 DNS 服务器,并使用 nsupdate 或其他工具实现动态更新和故障转移。
  5. 替代方案: 如果你觉得 BIND 配置复杂,可以考虑使用更简单的工具,如 dnsmasq,它非常轻量,集成了 DHCP 和 DNS 功能,特别适合小型家庭或办公室网络。

希望这份详细的指南能帮助你成功搭建自己的内网 DNS 服务器!

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