Dnsmasq 服务搭建完全教程 / 第 02 章:安装与初始配置
第 02 章:安装与初始配置
2.1 安装 Dnsmasq
2.1.1 Debian / Ubuntu
# 更新包索引
sudo apt update
# 安装 Dnsmasq
sudo apt install dnsmasq
# 验证安装
dnsmasq --version
注意:Ubuntu 18.04+ 默认使用 systemd-resolved 占用 53 端口,需要先释放:
# 检查 53 端口占用
sudo ss -tlnp | grep :53
# 方法 1:停止 systemd-resolved(推荐)
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
# 方法 2:修改 systemd-resolved 配置,让它不监听 53
# 编辑 /etc/systemd/resolved.conf
sudo tee -a /etc/systemd/resolved.conf <<'EOF'
[Resolve]
DNSStubListener=no
EOF
# 创建 resolv.conf 指向 Dnsmasq
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
sudo systemctl restart systemd-resolved
2.1.2 CentOS / RHEL / Fedora
# CentOS 7 / RHEL 7
sudo yum install dnsmasq
# CentOS 8+ / RHEL 8+ / Fedora
sudo dnf install dnsmasq
# 验证安装
dnsmasq --version
注意:CentOS 7+ 默认使用
firewalld,需放行 DNS/DHCP 端口:sudo firewall-cmd --permanent --add-service=dns sudo firewall-cmd --permanent --add-service=dhcp sudo firewall-cmd --reload
2.1.3 Alpine Linux
# 安装
apk add dnsmasq
# 设置开机启动
rc-update add dnsmasq default
# 启动服务
rc-service dnsmasq start
2.1.4 Arch Linux
sudo pacman -S dnsmasq
sudo systemctl enable --now dnsmasq
2.1.5 macOS (Homebrew)
brew install dnsmasq
# 编辑配置
brew edit dnsmasq
# 或直接编辑
nano /usr/local/etc/dnsmasq.conf
# 启动服务
sudo brew services start dnsmasq
2.1.6 从源码编译
适用于需要最新版本或自定义编译选项的场景:
# 安装编译依赖
sudo apt install build-essential pkg-config
# 下载源码
cd /tmp
wget http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.90.tar.gz
tar xzf dnsmasq-2.90.tar.gz
cd dnsmasq-2.90
# 查看编译选项
head -30 Makefile
# 编译(默认支持 IPv6)
make
# 安装
sudo make install
# 验证
which dnsmasq
dnsmasq --version
自定义编译选项:
# 编辑 Makefile 头部,修改 COPTS 变量
# 例如禁用 IPv6、启用 Lua 脚本支持:
# COPTS = -DHAVE_IPV6 -DNO_LUA
# 或通过命令行传入
make COPTS="-DNO_IPV6 -DHAVE_LUASCRIPT"
sudo make install
2.2 包管理器安装 vs 源码编译
| 维度 | 包管理器 | 源码编译 |
|---|---|---|
| 安装速度 | 秒级 | 分钟级 |
| 版本 | 发行版维护(可能较旧) | 最新版本 |
| 依赖 | 自动解决 | 手动安装 |
| 升级 | apt upgrade / dnf update | 手动重新编译 |
| 编译选项 | 固定 | 可自定义 |
| 推荐场景 | 大多数情况 | 需要特定版本或功能 |
2.3 配置文件结构
Dnsmasq 使用单一配置文件,支持目录式片段加载:
/etc/dnsmasq.conf ← 主配置文件
/etc/dnsmasq.d/ ← 配置片段目录
/etc/dnsmasq.d/*.conf ← 自动加载的 .conf 文件
/etc/dnsmasq.d/bak/ ← 备份/禁用的配置
/etc/hosts ← 系统 hosts 文件(自动读取)
/etc/resolv.conf ← 上游 DNS 指向(自动读取)
/var/lib/misc/dnsmasq.leases ← DHCP 租约文件
2.3.1 配置文件语法
# 注释行以 # 开头
# 这是注释
# 每行一个选项,格式为:
# 选项=值
# 选项=值1,值2,值3 ← 列表用逗号分隔
# 选项 ← 布尔选项无需值
# --选项=值 ← 两种写法等价
# 示例
listen-address=127.0.0.1,192.168.1.1
port=53
cache-size=1000
domain=home.lan
log-queries
2.3.2 推荐的配置组织方式
不要直接修改 /etc/dnsmasq.conf 主文件,而是使用 /etc/dnsmasq.d/ 目录:
# 保留主配置文件为模板,仅启用配置目录加载
sudo grep -v "^#" /etc/dnsmasq.conf | grep -v "^$" | head -20
# 在 dnsmasq.conf 末尾确认包含这行(多数发行版默认有):
# conf-dir=/etc/dnsmasq.d/,*.conf
创建功能模块化配置:
sudo tee /etc/dnsmasq.d/00-base.conf <<'EOF'
# === 基础 DNS 配置 ===
listen-address=127.0.0.1,192.168.1.1
bind-interfaces
port=53
cache-size=500
neg-ttl=60
domain=home.lan
expand-hosts
EOF
sudo tee /etc/dnsmasq.d/01-upstream.conf <<'EOF'
# === 上游 DNS ===
server=8.8.8.8
server=8.8.4.4
server=114.114.114.114
no-resolv
EOF
sudo tee /etc/dnsmasq.d/02-dhcp.conf <<'EOF'
# === DHCP 配置 ===
interface=eth1
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,24h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,192.168.1.1
EOF
2.4 核心命令行选项
2.4.1 常用选项速查表
| 选项 | 说明 | 示例 |
|---|---|---|
--conf-file=FILE | 指定配置文件 | --conf-file=/etc/dnsmasq.conf |
--conf-dir=DIR | 加载目录中的配置片段 | --conf-dir=/etc/dnsmasq.d/,*.conf |
--no-daemon | 前台运行(调试用) | -d 或 --no-daemon |
--log-queries | 记录 DNS 查询日志 | --log-queries |
--log-facility=FILE | 日志输出文件 | --log-facility=/var/log/dnsmasq.log |
--port=PORT | DNS 监听端口 | --port=5353 |
--listen-address=IP | 监听地址 | --listen-address=127.0.0.1 |
--interface=IFACE | 监听指定接口 | --interface=eth1 |
--except-interface=IFACE | 排除接口 | --except-interface=lo |
--cache-size=N | DNS 缓存条目数 | --cache-size=1000 |
--pid-file=FILE | PID 文件路径 | --pid-file=/run/dnsmasq.pid |
--user=USER | 运行用户 | --user=dnsmasq |
--test | 检查配置语法 | --test |
2.4.2 命令行与配置文件对照
# 命令行
dnsmasq --port=5353 --cache-size=500 --log-queries
# 等价的配置文件
port=5353
cache-size=500
log-queries
优先级规则:命令行选项 > 配置文件选项。命令行中重复的选项,后面的覆盖前面的。
2.5 首次启动
2.5.1 检查配置语法
# 测试配置文件是否正确
dnsmasq --test
# 输出 "dnsmasq: syntax check OK." 表示配置无误
# 输出错误信息则需修复对应行
2.5.2 启动服务
# 使用 systemd(推荐)
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq # 开机自启
sudo systemctl status dnsmasq # 查看状态
# 查看服务日志
sudo journalctl -u dnsmasq -f # 实时跟踪
sudo journalctl -u dnsmasq --since "1 hour ago" # 最近1小时
2.5.3 手动前台启动(调试)
# 前台运行,输出日志到终端
sudo dnsmasq --no-daemon --log-queries --log-facility=-
# 指定配置文件
sudo dnsmasq --no-daemon --conf-file=/etc/dnsmasq.conf
2.5.4 验证 DNS 服务
# 使用 dig 查询
dig @127.0.0.1 www.baidu.com
# 使用 nslookup
nslookup www.baidu.com 127.0.0.1
# 使用 host
host www.baidu.com 127.0.0.1
预期输出(dig):
;; ANSWER SECTION:
www.baidu.com. 300 IN A 110.242.68.66
;; Query time: 28 msec ← 首次查询(从上游获取)
;; SERVER: 127.0.0.1#53
# 再次查询
;; Query time: 0 msec ← 缓存命中,耗时接近 0
;; SERVER: 127.0.0.1#53
2.6 systemd 服务文件详解
Dnsmasq 的 systemd 服务单元文件通常位于 /lib/systemd/system/dnsmasq.service:
[Unit]
Description=DHCP and DNS caching server
After=network.target
Documentation=man:dnsmasq(8)
[Service]
Type=dbus
BusName=org.freedesktop.NetworkManager.dnsmasq
ExecStart=/usr/sbin/dnsmasq -k --log-facility=/var/log/dnsmasq.log
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
关键参数说明:
| 参数 | 说明 |
|---|---|
Type=dbus | 通过 D-Bus 注册服务(NetworkManager 集成) |
-k | 前台运行(systemd 要求,替代 daemon 模式) |
ExecReload | 支持 systemctl reload dnsmasq 热重载配置 |
Restart=on-failure | 异常退出后自动重启 |
2.6.1 自定义 systemd 服务
如果需要自定义启动参数:
# 创建 override 文件(不修改原文件)
sudo systemctl edit dnsmasq
# 在编辑器中写入:
[Service]
ExecStart=
ExecStart=/usr/sbin/dnsmasq -k --conf-file=/etc/dnsmasq-custom.conf
# 重新加载并重启
sudo systemctl daemon-reload
sudo systemctl restart dnsmasq
2.7 完整的最小配置示例
以下是一个功能完备的最小配置,适合家庭网络快速部署:
sudo tee /etc/dnsmasq.d/home-network.conf <<'EOF'
# ============================================
# Dnsmasq 家庭网络最小配置
# ============================================
# --- DNS 基础配置 ---
listen-address=127.0.0.1,192.168.1.1
bind-interfaces
port=53
cache-size=500
min-cache-ttl=300
neg-ttl=60
# --- 上游 DNS ---
server=223.5.5.5
server=119.29.29.29
server=8.8.8.8
no-resolv
no-poll
# --- 本地域名 ---
domain=home.lan
expand-hosts
local=/home.lan/
# --- DHCP 配置 ---
interface=eth1
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,24h
dhcp-option=option:router,192.168.1.1
dhcp-option=option:dns-server,192.168.1.1
dhcp-authoritative
# --- 日志 ---
log-queries
log-facility=/var/log/dnsmasq.log
EOF
验证并启动:
# 检查语法
sudo dnsmasq --test
# 重启服务
sudo systemctl restart dnsmasq
# 验证 DNS
dig @192.168.1.1 www.baidu.com
# 验证 DHCP(在另一台设备上)
# 断开重连网络,检查是否获得 192.168.1.100-200 范围的 IP
2.8 配置热重载
修改配置后无需重启服务,可以发送 SIGHUP 信号让 Dnsmasq 重新加载:
# 方法 1:systemctl reload
sudo systemctl reload dnsmasq
# 方法 2:手动发送信号
sudo kill -HUP $(pidof dnsmasq)
# 方法 3:使用 dnsmasq 的 D-Bus 接口
sudo dbus-send --system --dest=uk.org.thekelleys.dnsmasq \
/uk/org/thekelleys/dnsmasq \
uk.org.thekelleys.dnsmasq.Reload
注意:SIGHUP 会重新读取配置文件、hosts 文件和域名列表,但不会中断现有连接。DHCP 租约文件不会重新加载。
2.9 端口冲突处理
常见端口冲突及解决方案:
| 冲突服务 | 端口 | 解决方案 |
|---|---|---|
| systemd-resolved | 53 | 停用或配置 DNSStubListener=no |
| dnsmasq (另一个实例) | 53 | kill 旧进程或修改端口 |
| named (BIND) | 53 | systemctl stop named |
| NetworkManager 内置 dnsmasq | 53 | 禁用 NM 的 dns=dnsmasq |
| 其他 DHCP 服务 | 67 | 停止 isc-dhcp-server |
# 查看所有 53 端口占用
sudo ss -ulnp | grep :53
sudo ss -tlnp | grep :53
# 查看 67 端口(DHCP)
sudo ss -ulnp | grep :67
2.10 小结
| 要点 | 说明 |
|---|---|
| 安装方式 | 包管理器(推荐)或源码编译 |
| 配置文件 | /etc/dnsmasq.conf + /etc/dnsmasq.d/*.conf |
| 配置检查 | dnsmasq --test |
| 启动管理 | systemctl start/stop/restart/reload dnsmasq |
| 端口冲突 | 优先检查 systemd-resolved |
| 热重载 | systemctl reload dnsmasq(发送 SIGHUP) |