环境 链接到标题
| 项目 | 内容 |
|---|---|
| 硬件 | Raspberry Pi 4 (4GB) |
| 系统 | Ubuntu Server 24.04.2 LTS (arm64) |
| Docker | 29.3.0 + Compose v5.1.0 |
方案选型 链接到标题
旧的 DNS 服务器不打算继续用了,在树莓派 4 上重新搭一个。需求很简单:内网设备 hostname 解析 *.lan。
备选方案:
| 方案 | 语言 | 特点 | 结论 |
|---|---|---|---|
| dnsmasq | C | 极轻量,单二进制,2000年至今 | ✅ 够用 |
| systemd-resolved | C | Ubuntu 自带,零安装 | ❌ 对外监听需额外配置,expand-hosts 不支持 |
| unbound | C | 递归解析器,DNSSEC 强 | ❌ 大炮打蚊子 |
| CoreDNS | Go | 云原生,插件化 | ❌ 太重 |
| blocky | Go | Web UI,策略丰富 | ❌ 功能过剩 |
dnsmasq 入选理由:轻量、稳定、内网场景足够。
注意 CVE 链接到标题
2026年5月 dnsmasq 被通报了 6 个 CVE(CVE-2026-2291 ~ CVE-2026-5172),包括堆溢出导致 DNS 缓存投毒、DNSSEC DoS、DHCPv6 提权等。修复版本 2.93。务必使用 2.93+,不要用系统仓库中的旧版。
安装 链接到标题
拉取镜像 链接到标题
Docker Hub 被墙,走 DaoCloud 镜像:
docker pull docker.m.daocloud.io/dockurr/dnsmasq:2.93
dockurr/dnsmasq 并非官方镜像(dnsmasq 无官方 Docker 镜像),但 GitHub 开源,500K+ pulls,支持 amd64/arm64/armv7。
配置 链接到标题
docker-compose.yml
services:
dnsmasq:
image: docker.m.daocloud.io/dockurr/dnsmasq:2.93
container_name: dnsmasq
network_mode: host
cap_add:
- NET_ADMIN
volumes:
- ./dnsmasq.conf:/etc/dnsmasq.conf
- ./hosts:/etc/hosts
restart: always
dnsmasq.conf
port=53
domain=lan
expand-hosts
local=/lan/
bind-interfaces
no-resolv
server=223.5.5.5
server=114.114.114.114
hosts(示例,按实际情况替换 IP 和主机名)
10.0.0.50 server-a
10.0.0.51 server-b
10.0.0.99 nas-01
链接到标题
踩坑记录 链接到标题
坑一:listen-address 导致 UDP 不响应
链接到标题
现象:dnsmasq 启动正常,日志无报错,端口 53 正常监听,但 DNS 查询全部超时。TCP 连接正常,UDP 无响应。
原因:Alpine 容器中 listen-address=0.0.0.0 与 musl libc 的 socket 行为不兼容,UDP 数据包无法被 dnsmasq 处理。
解决:改为 bind-interfaces,不显式指定 listen-address。
坑二:Docker bridge 网络 UDP 端口转发不通 链接到标题
现象:容器内端口正常,宿主机 ss 显示 53 监听,但宿主机到容器的 UDP 查询超时。tcpdump 显示数据包已到达 Docker bridge,但容器未响应。
原因:Docker bridge 模式下 UDP 端口转发存在兼容性问题(猜测与内核 iptables 或 Docker 版本有关)。
解决:改用 network_mode: host,容器直接使用宿主机网络栈,绕过 Docker bridge。
坑三:address= 指令与 expand-hosts 不兼容
链接到标题
现象:查询 server-a.lan 返回 NXDOMAIN。
原因:expand-hosts 只对 /etc/hosts 文件中的条目生效,address= config 指令不参与域名扩展。
解决:直接把 IP 映射写在 /etc/hosts 文件中,由 expand-hosts + domain=lan 自动追加 .lan 后缀。
验证 链接到标题
$ dig +short server-a.lan @127.0.0.1
10.0.0.50
$ dig +short device-x.lan @127.0.0.1
10.0.0.60
$ dig +short baidu.com @127.0.0.1
1.2.4.8
本地解析和上游解析均正常。
总结 链接到标题
dnsmasq 仍然是内网 DNS 最省心的方案。这次升级到 2.93 解决了已知 CVE,同时补上了最近 Docker + Alpine + musl libc 的几个坑。配置文档在此:github.com/dockur/dnsmasq。