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 request | TFTP 文件不存在 | 检查 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 扩展阅读