强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Dnsmasq 服务搭建完全教程 / 第 11 章:故障排查

第 11 章:故障排查

11.1 常见问题速查表

现象可能原因快速检查
DNS 不响应端口占用/服务未启动ss -tlnp|grep :53
DNS 解析失败上游 DNS 配置错误dig @127.0.0.1 example.com
DHCP 不分配 IP接口配置错误journalctl -u dnsmasq
客户端获得错误网关dhcp-option 配置错误检查 dhcp-option=option:router
启动失败配置语法错误dnsmasq --test
内存占用高缓存过大检查 cache-size 配置
日志文件过大日志级别过高调整 log-queries

11.2 日志分析

11.2.1 启用详细日志

# /etc/dnsmasq.d/99-debug.conf

# DNS 查询日志
log-queries

# DHCP 事件日志
log-dhcp

# 日志输出到文件
log-facility=/var/log/dnsmasq/dnsmasq.log

11.2.2 查看日志

# 实时查看日志
sudo tail -f /var/log/dnsmasq/dnsmasq.log

# 使用 journalctl
sudo journalctl -u dnsmasq -f

# 查看最近 1 小时
sudo journalctl -u dnsmasq --since "1 hour ago"

# 按时间范围查看
sudo journalctl -u dnsmasq --since "2026-05-10 10:00" --until "2026-05-10 11:00"

# 过滤 DHCP 事件
sudo journalctl -u dnsmasq | grep DHCP

# 过滤特定域名
sudo grep "example.com" /var/log/dnsmasq/dnsmasq.log

11.2.3 日志格式解析

# DNS 查询日志格式:
# dnsmasq[PID]: query[类型] 域名 from 来源IP
dnsmasq[1234]: query[A] www.baidu.com from 192.168.1.100
dnsmasq[1234]: forwarded www.baidu.com to 223.5.5.5
dnsmasq[1234]: reply www.baidu.com is 110.242.68.66

# DNS 缓存命中日志:
dnsmasq[1234]: cached www.baidu.com is 110.242.68.66

# DHCP 日志格式:
dnsmasq[1234]: DHCPDISCOVER(eth1) aa:bb:cc:dd:ee:ff
dnsmasq[1234]: DHCPOFFER(eth1) 192.168.1.100 aa:bb:cc:dd:ee:ff
dnsmasq[1234]: DHCPREQUEST(eth1) 192.168.1.100 aa:bb:cc:dd:ee:ff
dnsmasq[1234]: DHCPACK(eth1) 192.168.1.100 aa:bb:cc:dd:ee:ff mylaptop

11.2.4 日志分析脚本

#!/bin/bash
# /usr/local/bin/dnsmasq-log-analyze.sh

LOG="/var/log/dnsmasq/dnsmasq.log"

echo "=== Dnsmasq Log Analysis ==="
echo "Date: $(date)"
echo ""

echo "--- Top 20 Queried Domains ---"
grep "query\[" "$LOG" | awk '{print $6}' | sort | uniq -c | sort -rn | head -20

echo ""
echo "--- Top 20 Client IPs ---"
grep "query\[" "$LOG" | awk '{print $NF}' | sort | uniq -c | sort -rn | head -20

echo ""
echo "--- Cached Responses ---"
grep "cached" "$LOG" | wc -l

echo ""
echo "--- Forwarded Queries ---"
grep "forwarded" "$LOG" | wc -l

echo ""
echo "--- DHCP Leases ---"
grep "DHCPACK" "$LOG" | wc -l

echo ""
echo "--- Recent Errors ---"
grep -i "error\|fail\|refused" "$LOG" | tail -20

11.3 DNS 故障排查

11.3.1 DNS 不响应

# 步骤 1:检查服务状态
sudo systemctl status dnsmasq

# 步骤 2:检查端口监听
sudo ss -tlnp | grep :53
sudo ss -ulnp | grep :53

# 步骤 3:检查是否有端口冲突
sudo lsof -i :53

# 步骤 4:检查防火墙
sudo iptables -L INPUT -n | grep 53
sudo ufw status

# 步骤 5:检查配置语法
sudo dnsmasq --test

# 步骤 6:查看错误日志
sudo journalctl -u dnsmasq --since "5 min ago" -p err

11.3.2 DNS 解析失败

# 测试本地 DNS
dig @127.0.0.1 www.baidu.com

# 如果本地失败,测试上游 DNS
dig @223.5.5.5 www.baidu.com
dig @8.8.8.8 www.baidu.com

# 检查上游 DNS 配置
grep "^server=" /etc/dnsmasq.d/*.conf

# 检查 no-resolv 设置
grep "no-resolv" /etc/dnsmasq.d/*.conf
# 如果有 no-resolv,必须手动指定 server=

# 检查 resolv.conf
cat /etc/resolv.conf
# 如果 no-resolv 未设置,resolv.conf 中的 nameserver 也会被使用

11.3.3 DNS 缓存问题

# 查看缓存统计
sudo kill -USR1 $(pidof dnsmasq)
sudo journalctl -u dnsmasq --since "5 sec ago"

# 清除缓存
sudo systemctl reload dnsmasq

# 测试缓存是否生效
dig @127.0.0.1 www.baidu.com        # 首次查询(转发)
dig @127.0.0.1 www.baidu.com        # 第二次查询(缓存,Query time: 0 msec)

# 检查缓存 TTL
dig @127.0.0.1 www.baidu.com +ttlid

11.3.4 自定义记录不生效

# 检查 hosts 文件格式
cat /etc/dnsmasq.hosts
# 确保格式正确:IP<空格>主机名

# 检查 addn-hosts 配置
grep "addn-hosts" /etc/dnsmasq.d/*.conf

# 重载 hosts 文件
sudo kill -HUP $(pidof dnsmasq)

# 检查 address 指令
grep "address=" /etc/dnsmasq.d/*.conf

# 检查是否被其他记录覆盖
# address 指令优先级高于 hosts 文件
dig @127.0.0.1 myhost.home.lan +trace

11.3.5 DNS 重绑定保护导致的问题

# 现象:内网域名解析到内网 IP 时返回 NXDOMAIN
# 原因:Dnsmasq 默认开启 DNS 重绑定保护

# 检查配置
grep "stop-dns-rebind" /etc/dnsmasq.d/*.conf

# 解决方案:
# 方案 1:禁用重绑定保护(不推荐)
# 去掉 stop-dns-rebind

# 方案 2:允许特定域名(推荐)
rebind-domain-ok=/home.lan/
rebind-domain-ok=/internal.corp/

# 方案 3:允许 localhost
rebind-localhost-ok

11.4 DHCP 故障排查

11.4.1 客户端无法获取 IP

# 步骤 1:检查 DHCP 服务
sudo systemctl status dnsmasq | grep -i "active"

# 步骤 2:检查 DHCP 端口
sudo ss -ulnp | grep :67

# 步骤 3:检查接口配置
grep "interface=" /etc/dnsmasq.d/*.conf

# 步骤 4:检查地址池配置
grep "dhcp-range" /etc/dnsmasq.d/*.conf

# 步骤 5:查看 DHCP 日志
sudo journalctl -u dnsmasq | grep -i "dhcp"

# 步骤 6:抓包分析
sudo tcpdump -i eth1 -n port 67 or port 68

11.4.2 DHCP 分配错误地址

# 检查是否有多个 DHCP 服务器
sudo tcpdump -i eth1 -n port 67 or port 68

# 查看租约文件
cat /var/lib/misc/dnsmasq.leases

# 检查静态绑定
grep "dhcp-host" /etc/dnsmasq.d/*.conf

# 清除旧租约
sudo truncate -s 0 /var/lib/misc/dnsmasq.leases
sudo systemctl reload dnsmasq

11.4.3 DHCP 选项问题

# 检查 DHCP 选项配置
grep "dhcp-option" /etc/dnsmasq.d/*.conf

# 客户端侧检查(Linux)
ip addr show
ip route show
cat /etc/resolv.conf

# 客户端侧检查(Windows)
ipconfig /all

# 强制刷新租约(Linux)
sudo dhclient -r eth1
sudo dhclient eth1

# 强制刷新租约(Windows)
ipconfig /release
ipconfig /renew

11.4.4 租约冲突

# 现象:两个设备获得同一 IP
# 原因:租约文件损坏或手动配置错误

# 查看当前租约
cat /var/lib/misc/dnsmasq.leases

# 查找冲突的 IP
awk '{print $3}' /var/lib/misc/dnsmasq.leases | sort | uniq -d

# 解决方案
# 1. 清除所有租约
sudo cp /var/lib/misc/dnsmasq.leases /var/lib/misc/dnsmasq.leases.bak
sudo truncate -s 0 /var/lib/misc/dnsmasq.leases
sudo systemctl reload dnsmasq

# 2. 检查静态绑定是否有重复
grep "dhcp-host" /etc/dnsmasq.d/*.conf | awk -F',' '{print $2}' | sort | uniq -d

11.5 调试模式

11.5.1 前台调试模式

# 停止后台服务
sudo systemctl stop dnsmasq

# 前台运行,输出到终端
sudo dnsmasq --no-daemon --log-queries --log-facility=- --conf-file=/etc/dnsmasq.conf

# 输出示例:
# dnsmasq: started, version 2.90 cachesize 500
# dnsmasq: compile time options: IPv6 GNU-getopt DBus ...
# dnsmasq: reading /etc/resolv.conf
# dnsmasq: using nameserver 223.5.5.5#53
# dnsmasq: query[A] www.baidu.com from 127.0.0.1
# dnsmasq: forwarded www.baidu.com to 223.5.5.5
# dnsmasq: reply www.baidu.com is 110.242.68.66

11.5.2 使用 strace 追踪

# 追踪系统调用
sudo strace -p $(pidof dnsmasq) -e trace=network -f

# 追踪文件访问
sudo strace -p $(pidof dnsmasq) -e trace=file -f

# 追踪 DNS 相关系统调用
sudo strace -p $(pidof dnsmasq) -e trace=network,read,write -f 2>&1 | grep -i "dns\|53"

11.5.3 网络抓包分析

# 抓取 DNS 流量
sudo tcpdump -i eth1 -n port 53 -v

# 抓取 DHCP 流量
sudo tcpdump -i eth1 -n port 67 or port 68 -v

# 抓取 TFTP 流量
sudo tcpdump -i eth1 -n port 69 -v

# 保存到文件,用 Wireshark 分析
sudo tcpdump -i eth1 -n port 53 -w /tmp/dns-capture.pcap

# 过滤特定域名
sudo tcpdump -i eth1 -n port 53 | grep "example.com"

11.5.4 DNS 查询测试工具

# 使用 dig 测试
dig @127.0.0.1 www.baidu.com          # A 记录
dig @127.0.0.1 www.baidu.com AAAA     # AAAA 记录
dig @127.0.0.1 -x 192.168.1.1         # PTR 记录
dig @127.0.0.1 www.baidu.com +trace   # 追踪解析过程
dig @127.0.0.1 www.baidu.com +short   # 只显示结果

# 使用 nslookup
nslookup www.baidu.com 127.0.0.1

# 使用 host
host www.baidu.com 127.0.0.1

# 测试 DNSSEC
dig @127.0.0.1 www.dnssec-tools.org +dnssec

11.6 性能问题排查

11.6.1 DNS 响应慢

# 测试响应时间
dig @127.0.0.1 www.baidu.com | grep "Query time"

# 如果缓存命中仍然慢,检查:
# 1. 缓存大小
grep "cache-size" /etc/dnsmasq.d/*.conf

# 2. 上游 DNS 响应时间
dig @223.5.5.5 www.baidu.com | grep "Query time"
dig @8.8.8.8 www.baidu.com | grep "Query time"

# 3. 内存使用
ps -o rss,vsz -p $(pidof dnsmasq)

# 4. 系统负载
top -bn1 | head -5

11.6.2 内存占用分析

# 查看 Dnsmasq 内存使用
ps aux | grep dnsmasq

# 查看详细内存映射
sudo pmap -x $(pidof dnsmasq)

# 查看缓存统计
sudo kill -USR1 $(pidof dnsmasq)
sudo journalctl -u dnsmasq --since "5 sec ago"
# 输出中的 "cache size" 显示缓存占用

11.7 配置问题排查

11.7.1 配置语法检查

# 完整语法检查
sudo dnsmasq --test

# 常见语法错误:
# 1. 缺少等号
#    错误:listen-address 192.168.1.1
#    正确:listen-address=192.168.1.1

# 2. IP 地址格式错误
#    错误:server=8.8.8.8#53#53
#    正确:server=8.8.8.8#53

# 3. 路径不存在
#    错误:addn-hosts=/etc/nonexistent
#    正确:确保文件存在

11.7.2 配置文件调试

# 逐个加载配置文件,定位问题
sudo dnsmasq --no-daemon --conf-file=/etc/dnsmasq.conf --test

# 使用空配置测试
sudo dnsmasq --no-daemon --port=5353 --no-resolv --server=8.8.8.8

# 逐个添加配置文件
sudo dnsmasq --no-daemon --conf-file=/etc/dnsmasq.d/01-base.conf --test
sudo dnsmasq --no-daemon --conf-file=/etc/dnsmasq.d/02-dhcp.conf --test

11.8 常见错误消息

错误消息原因解决方案
dnsmasq: failed to create listening socket端口被占用检查其他 DNS 服务
dnsmasq: cannot read /etc/resolv.conf文件权限chmod 644 /etc/resolv.conf
dnsmasq: bad address配置中 IP 格式错误检查 address 指令
dnsmasq: unknown interface接口不存在检查 interface 配置
dnsmasq: no servers found上游 DNS 未配置添加 server= 指令
dnsmasq: TFTP requestTFTP 文件不存在检查 tftp-root 目录

11.9 完整故障排查流程

问题出现
    │
    ├── 服务是否运行?
    │   ├── 否 → 启动服务,检查错误日志
    │   └── 是 ↓
    │
    ├── 配置是否正确?
    │   ├── 否 → dnsmasq --test
    │   └── 是 ↓
    │
    ├── 端口是否监听?
    │   ├── 否 → 检查端口冲突
    │   └── 是 ↓
    │
    ├── 本地查询是否正常?
    │   ├── 否 → 检查 DNS/接口配置
    │   └── 是 ↓
    │
    ├── 上游查询是否正常?
    │   ├── 否 → 检查上游 DNS 配置/网络
    │   └── 是 ↓
    │
    └── 客户端是否正常?
        ├── 否 → 检查客户端 DNS 配置/防火墙
        └── 是 → 检查网络路由/中间设备

11.10 小结

排查阶段工具/命令目的
服务状态systemctl status确认服务运行
配置检查dnsmasq --test验证语法
端口监听ss -tlnp|grep :53确认端口占用
DNS 测试dig @127.0.0.1验证解析
日志分析journalctl -u dnsmasq定位错误
网络抓包tcpdump -i eth1 port 53分析流量
前台调试dnsmasq --no-daemon实时调试

11.11 扩展阅读