Linux DNS 与 DHCP 服务:BIND/dnsmasq、zone 文件与解析排错

深入 Linux DNS 与 DHCP 服务:域名解析原理与关键文件(/etc/resolv.conf)、dnsmasq 轻量 DNS+DHCP 二合一、BIND 权威 DNS 与 zone 文件(正向/反向解析)、DHCP 地址池与固定分配、systemd-resolved 本地解析、缓存与转发性能、dig/nslookup 排错实战,掌握内网域名解析与动态地址分配。

引言

内网能不能用 http://db-server 访问数据库、新设备能不能自动拿 IP——靠DNS(域名解析)与 DHCP(动态地址分配)。本文把两个服务拆开讲透:先讲解析原理与关键文件(/etc/resolv.conf、/etc/hosts),再给轻量方案 dnsmasq(DNS+DHCP 二合一,小内网首选) 与权威方案 BIND(zone 文件,企业级),覆盖正向/反向解析、DHCP 固定分配、缓存转发,最后用 dig/nslookup 排错。

前置:/linux-network-commands/(网络配置)。域名与网络基础见该文;防火墙放行见 /linux-firewall-nftables/(DNS 端口 53/5353)。


目录


1. DNS 与 DHCP 服务全景

DNS 把「名字」解析成「IP」,DHCP 把「IP」分配给「设备」:

内网基础设施双雄:
  DNS:db-server → 192.168.1.50(名字 → IP)
  DHCP:新手机 → 自动拿 192.168.1.60/24(IP 自动分配)
两者常一起部署(dnsmasq 一个进程干两件事)
服务端口作用常用实现
DNS53 (UDP/TCP)域名 → IPdnsmasq / BIND
DHCP67/68 (UDP)IP 自动分配dnsmasq / isc-dhcp-server
本地解析127.0.0.53系统 DNS 缓存systemd-resolved

心智:DNS 是「内网电话簿」、DHCP 是「内网发号机」。小内网(<100 设备)用 dnsmasq 一个搞定;企业内网 DNS 用 BIND 权威解析、DHCP 用独立服务。


2. 域名解析原理与关键文件

解析流程(客户端侧):

输入 db-server 或 www.example.com
  → 查 /etc/hosts(本地静态表)
  → 查 /etc/resolv.conf 配置的 DNS 服务器
  → DNS 服务器逐级解析(根 → .com → example.com → 最终 IP)
  → 返回 IP,缓存到本地

三个关键文件:

# 1. /etc/resolv.conf:配置 DNS 服务器(当前机器用谁解析)
nameserver 127.0.0.53        # systemd-resolved 本地缓存
nameserver 8.8.8.8           # 备用公共 DNS
search internal.example.com  # 自动补全域名后缀

# 2. /etc/hosts:本地静态解析(优先于 DNS)
127.0.0.1 localhost
192.168.1.50 db-server       # 内网手动映射

# 3. /etc/nsswitch.conf:解析顺序(hosts: files dns)
# files = /etc/hosts,dns = DNS 服务器

记忆:解析顺序 = hosts(静态)→ resolv.conf(DNS 服务器)。想让某域名「永远走某 IP」就写 /etc/hosts(优先级最高);想改「用哪个 DNS」就改 resolv.conf。


3. dnsmasq:轻量 DNS 与 DHCP 二合一

dnsmasq 是内网神器——一个进程同时干 DNS 和 DHCP:

sudo apt install dnsmasq

# 配置:/etc/dnsmasq.conf
sudo tee -a /etc/dnsmasq.conf > /dev/null <<'EOF'
# DNS 部分:转发上游 + 本地解析
server=8.8.8.8              # 上游 DNS(公网查询转给它)
address=/db.internal/192.168.1.50   # 本地域名直接给 IP

# DHCP 部分:地址池 + 网关 + DNS
dhcp-range=192.168.1.100,192.168.1.200,12h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,192.168.1.1
EOF

sudo systemctl restart dnsmasq
# 客户端把 DNS 指到 dnsmasq 主机 → 内网域名立即可用
echo "nameserver 192.168.1.1" > /etc/resolv.conf
nslookup db.internal        # 返回 192.168.1.50

记忆:dnsmasq 的「address=/域名/IP」一行就是一张迷你电话簿,DHCP 一行就是发号机。家庭/小办公网络 10 分钟搭完,是 OpenWrt、树莓派网关的默认方案。


4. BIND:权威 DNS 服务器

BIND 是企业级 DNS——跑正式 zone 文件、支持主从、权威应答:

sudo apt install bind9

# 主配置:/etc/bind/named.conf.local
sudo tee /etc/bind/named.conf.local > /dev/null <<'EOF'
zone "internal.example.com" {
    type master;
    file "/etc/bind/zones/db.internal.example.com";
};
EOF

sudo systemctl restart named
# 验证服务起来 + 本地查询
sudo systemctl status named
dig @localhost db1.internal.example.com

BIND vs dnsmasq 怎么选:

维度dnsmasqBIND
定位轻量、二合一权威、企业级
zone 管理无(address= 简单映射)完整 zone 文件
主从无支持(type slave)
适用小内网/家庭企业正式域名

心法:dnsmasq 用「address=」做静态映射,BIND 用「zone 文件」做权威解析。要「正式、可扩展、主从冗余」上 BIND;「够用、快、省资源」dnsmasq。


5. zone 文件:正向与反向解析

zone 文件是 BIND 的「电话簿正文」——域名记录一条条写:

# /etc/bind/zones/db.internal.example.com(正向解析:名字 → IP)
$TTL 86400
@   IN  SOA  ns1.internal.example.com. admin.internal.example.com. (
        2026092801 ; serial(改 zone 必改它)
        7200 3600 1209600 86400 )
@       IN  NS      ns1.internal.example.com.
ns1     IN  A       192.168.1.1
db1     IN  A       192.168.1.50       ; db1.internal.example.com → 192.168.1.50
web     IN  CNAME   db1                ; 别名
# 反向 zone(IP → 名字,可选但常用)
zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/db.192.168.1";
};
# 内容:50 IN PTR db1.internal.example.com.

记忆:zone 文件三件套 = SOA(区域头)+ NS(权威服务器)+ A/PTR 记录(名字⇄IP)。改 zone 后 named-checkzone 校验 + 递增 serial + rndc reload 才会生效。正向写 A/AAAA/CNAME,反向写 PTR。


6. DHCP:地址池与固定分配

DHCP 自动分配 IP,还能按 MAC 固定分配(服务器专用 IP):

# dnsmasq 固定分配:按 MAC 给固定 IP
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.1.50,db-server
dhcp-host=00:11:22:33:44:55,192.168.1.60,print-server
# 独立 DHCP 服务(isc-dhcp-server)
sudo apt install isc-dhcp-server
# /etc/dhcp/dhcpd.conf
subnet 192.168.1.0 netmask 255.255.255.0 {
    range 192.168.1.100 192.168.1.200;
    option routers 192.168.1.1;
    option domain-name-servers 192.168.1.1;
    host db-server {
        hardware ethernet aa:bb:cc:dd:ee:ff;
        fixed-address 192.168.1.50;
    }
}

记忆:DHCP 分配有两种——「池里随便拿」(range)与「MAC 固定」(host)。数据库、打印机这类要稳定 IP 的用固定分配,一般设备用地址池。查当前分配:dnsmasq 看 /var/lib/misc/dnsmasq.leases。


7. systemd-resolved:本地 DNS 解析

systemd-resolved 是系统的本地 DNS 缓存与分流器——监听 127.0.0.53:

# 查看当前解析配置
resolvectl status

# 临时指定某域走某 DNS(分流)
resolvectl dns eth0 8.8.8.8
resolvectl domain eth0 "~internal.example.com"

# 重新生成 /etc/resolv.conf 指向它
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

记忆:resolved 把「系统所有查询」汇总到 127.0.0.53——所以 /etc/resolv.conf 里 nameserver 127.0.0.53 很常见。它做缓存 + 按接口分流;想绕开它(如容器网络)需单独处理。


8. 缓存、转发与性能

DNS 性能三要素:缓存、转发、TTL:

查询路径:
  客户端 → 本地缓存(resolved/dnsmasq)→ 命中则秒回
  → 未命中 → 转发上游(8.8.8.8)→ 逐级解析 → 返回并缓存
# dnsmasq 缓存调优
cache-size=10000            # 缓存条数(默认 150 太小)
no-resolv                   # 不读 resolv.conf,只听 server=
server=8.8.8.8              # 明确上游

# 看缓存命中率
# dnsmasq 日志会打 query/cache 命中情况

心法:「慢查询」八成是缓存没命中 + 上游慢。内网域名用 address= 本地直答(不走上游);公网域名靠缓存。TTL 越长缓存越久(改 IP 后生效越慢,权衡)。


9. 排错:dig 与 nslookup

DNS 排错用 dig(现代)与 nslookup(经典):

# dig 全家桶
dig db1.internal.example.com          # 查询
dig @192.168.1.1 db1.example.com      # 指定服务器查(跳过本地缓存)
dig +short db1.example.com            # 只要结果
dig -x 192.168.1.50                   # 反向解析(IP → 名字)

# nslookup 经典
nslookup db1.example.com
nslookup 192.168.1.50                 # 反向
dig 输出关键行:
  status: NOERROR    # 解析成功
  status: NXDOMAIN   # 域名不存在
  status: SERVFAIL   # 服务器处理失败
  ANSWER SECTION     # 有答案 → 看 A 记录
现象原因解法
NXDOMAIN域名真不存在/拼错查 zone 记录
SERVFAIL上游/zone 出错查 BIND 日志
查到了但不对缓存旧/多级 DNS 不一致dig @指定服务器 绕缓存
内网域名不通没指对 DNS 服务器resolv.conf 指向 dnsmasq/BIND

记忆:排错口诀 = dig +short 看结果 → dig @服务器 绕缓存 → 看 status。status 三连(NOERROR/NXDOMAIN/SERVFAIL)直接告诉你是「有答案/没名字/服务坏」。


10. 速查表

需求方案关键配置
小内网 DNS+DHCPdnsmasqserver= + dhcp-range=
企业权威 DNSBINDzone 文件 + named.conf
本地静态映射/etc/hostsIP 域名 一行
客户端 DNS/etc/resolv.confnameserver IP
固定 IPDHCP hostdhcp-host=MAC,IP
正向解析zone A 记录db1 IN A 192.168.1.50
反向解析zone PTR50 IN PTR db1...
查询测试digdig @server +short name
本地缓存systemd-resolved127.0.0.53

一句话记忆:DNS 管「名字→IP」(dnsmasq 轻量 / BIND 权威 / hosts 静态 / resolved 缓存)、DHCP 管「IP 自动发」(range 池 / host 固定)——排错先用 dig 看 status,再决定查 zone 还是绕缓存。


延伸阅读

  • /linux-network-commands/ — 网络配置与排查基础
  • /linux-firewall-nftables/ — 放行 DNS/DHCP 端口
  • /linux-containers-isolation/ — 容器内 DNS(resolved 绕行)
  • /linux-systemd-services/ — 服务开机自启
  • [[docker]] — 容器网络与内建 DNS

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「linux」更多文章

  1. Linux 日志管理:rsyslog 集中收集、logrotate 轮转与日志分析
  2. Linux SSH 服务与隧道:sshd 配置、密钥认证、端口转发与安全加固
  3. Linux 定时任务:cron/at/anacron 与 systemd timer 全解析