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

Dnsmasq 服务搭建完全教程 / 第 12 章:最佳实践

第 12 章:最佳实践

12.1 安全加固

12.1.1 最小权限原则

# /etc/dnsmasq.d/90-security.conf

# 以非 root 用户运行
user=dnsmasq
group=dnsmasq

# 创建专用用户
sudo useradd -r -s /usr/sbin/nologin -d /var/lib/dnsmasq dnsmasq

# 设置文件权限
sudo chown -R dnsmasq:dnsmasq /var/lib/dnsmasq
sudo chown -R dnsmasq:dnsmasq /var/log/dnsmasq
sudo chmod 750 /var/lib/dnsmasq
sudo chmod 750 /var/log/dnsmasq

12.1.2 网络访问限制

# 只监听特定接口
bind-interfaces
listen-address=127.0.0.1,192.168.1.1
except-interface=eth0

# 禁止 DNS 放大攻击
# 不响应来自外网的 DNS 查询
# 通过 iptables 限制
sudo iptables -A INPUT -p udp --dport 53 -i eth0 -j DROP
sudo iptables -A INPUT -p tcp --dport 53 -i eth0 -j DROP

12.1.3 DNS 安全配置

# 防 DNS 重绑定攻击
stop-dns-rebind
rebind-localhost-ok
rebind-domain-ok=/home.lan/

# 过滤私有 IP 的反向查询
bogus-priv

# 禁止转发私有域名到公网
local=/home.lan/
local=/168.192.in-addr.arpa/

# DNSSEC(可选,可能影响性能)
# dnssec
# dnssec-check-unsigned

12.1.4 防火墙规则

#!/bin/bash
# /usr/local/bin/setup-firewall.sh

# 清空规则
iptables -F INPUT

# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT

# 允许 LAN 访问 DNS
iptables -A INPUT -p udp --dport 53 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -s 192.168.1.0/24 -j ACCEPT

# 允许 LAN 访问 DHCP
iptables -A INPUT -p udp --dport 67 -s 192.168.1.0/24 -j ACCEPT

# 允许 SSH
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT

# 拒绝其他所有
iptables -A INPUT -j DROP

# 保存规则
sudo iptables-save > /etc/iptables/rules.v4

12.2 性能调优

12.2.1 缓存优化

# /etc/dnsmasq.d/91-performance.conf

# 缓存大小(根据设备数量调整)
cache-size=1000        # 家庭/小型办公
# cache-size=5000      # 中型网络
# cache-size=10000     # 大型网络

# 最小缓存 TTL(秒),防止过快过期
min-cache-ttl=300

# 负向缓存 TTL(解析失败也缓存)
neg-ttl=60

# 本地域名 TTL
local-ttl=300

12.2.2 缓存大小估算表

网络规模设备数每日查询量推荐 cache-size内存占用
家庭< 20< 10K150-500~50 KB
小型办公20-10010K-50K500-2000~200 KB
中型网络100-50050K-200K2000-5000~500 KB
大型网络500+200K+5000-10000~1 MB

12.2.3 上游 DNS 选择

# 选择响应快、可靠的上游 DNS

# 国内推荐
server=223.5.5.5          # 阿里 DNS(延迟低)
server=119.29.29.29       # 腾讯 DNS(延迟低)
server=114.114.114.114    # 114 DNS(稳定)

# 国际推荐
server=8.8.8.8            # Google DNS
server=1.1.1.1            # Cloudflare DNS

# 严格顺序(使用延迟最低的)
strict-order

# 并行查询(默认,最快响应优先)
# all-servers

12.2.4 系统级优化

# 增大文件描述符限制
# /etc/security/limits.conf
dnsmasq soft nofile 4096
dnsmasq hard nofile 8192

# 增大 UDP 缓冲区
# /etc/sysctl.conf
net.core.rmem_max=8388608
net.core.wmem_max=8388608
net.core.rmem_default=1048576
net.core.wmem_default=1048576

# 应用 sysctl
sudo sysctl -p

12.3 运维规范

12.3.1 配置管理

推荐的配置目录结构:

/etc/dnsmasq.conf                  # 主配置(仅包含 conf-dir)
/etc/dnsmasq.d/
├── 00-base.conf                   # 基础设置(监听、缓存)
├── 01-upstream.conf               # 上游 DNS
├── 02-local-domain.conf           # 本地域名
├── 10-dhcp-main.conf              # 主网络 DHCP
├── 11-dhcp-vlan10.conf            # VLAN 10 DHCP
├── 12-dhcp-vlan20.conf            # VLAN 20 DHCP
├── 20-pxe.conf                    # PXE 引导(可选)
├── 30-custom-records.conf         # 自定义 DNS 记录
├── 50-filter.conf                 # 域名过滤
├── 90-security.conf               # 安全配置
├── 91-performance.conf            # 性能配置
└── 99-debug.conf                  # 调试配置(默认禁用)
/etc/dnsmasq.hosts                 # 自定义 hosts 文件
/var/lib/misc/dnsmasq.leases       # DHCP 租约文件
/var/log/dnsmasq/dnsmasq.log       # 日志文件

12.3.2 版本控制

# 将配置纳入 Git 版本控制
cd /etc
sudo git init
sudo git add dnsmasq.conf dnsmasq.d/ dnsmasq.hosts
sudo git commit -m "Initial Dnsmasq configuration"

# 配置变更后提交
sudo git add -A
sudo git commit -m "feat: add IoT VLAN DHCP config"

# 查看变更历史
sudo git log --oneline
sudo git diff HEAD~1

12.3.3 备份策略

#!/bin/bash
# /usr/local/bin/backup-dnsmasq.sh

BACKUP_DIR="/backup/dnsmasq"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/dnsmasq_backup_$TIMESTAMP.tar.gz"

mkdir -p "$BACKUP_DIR"

tar czf "$BACKUP_FILE" \
    /etc/dnsmasq.conf \
    /etc/dnsmasq.d/ \
    /etc/dnsmasq.hosts \
    /var/lib/misc/dnsmasq.leases

# 保留最近 30 天的备份
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete

echo "Backup completed: $BACKUP_FILE"
# Cron 定时备份
# 每天凌晨 2 点备份
0 2 * * * root /usr/local/bin/backup-dnsmasq.sh >> /var/log/dnsmasq-backup.log 2>&1

12.3.4 监控与告警

#!/bin/bash
# /usr/local/bin/healthcheck-dnsmasq.sh

# 健康检查脚本,配合 cron 使用
# 每 5 分钟检查一次
# */5 * * * * root /usr/local/bin/healthcheck-dnsmasq.sh

LOGFILE="/var/log/dnsmasq-health.log"
ALERT_FILE="/tmp/dnsmasq-alert-sent"

check_service() {
    if ! systemctl is-active --quiet dnsmasq; then
        echo "[$(date)] CRITICAL: Dnsmasq is not running" >> "$LOGFILE"
        systemctl restart dnsmasq
        if [ $? -eq 0 ]; then
            echo "[$(date)] INFO: Dnsmasq restarted successfully" >> "$LOGFILE"
        fi
        return 1
    fi
    return 0
}

check_dns() {
    local result=$(dig @127.0.0.1 baidu.com +short +timeout=3 2>/dev/null)
    if [ -z "$result" ]; then
        echo "[$(date)] CRITICAL: DNS resolution failed" >> "$LOGFILE"
        return 1
    fi
    return 0
}

check_memory() {
    local rss=$(ps -o rss= -p $(pidof dnsmasq) 2>/dev/null)
    if [ -n "$rss" ] && [ "$rss" -gt 102400 ]; then
        echo "[$(date)] WARNING: Memory usage high: ${rss}KB" >> "$LOGFILE"
    fi
}

check_service && check_dns && check_memory

12.4 家庭网络部署方案

12.4.1 推荐架构

Internet
   │
   │ (WAN - eth0)
┌──┴──────────────────┐
│   路由器/服务器       │
│   Dnsmasq            │
│   192.168.1.1        │
│                      │
│   eth1 (LAN) ───────┼──→ 交换机 ──→ 所有设备
└─────────────────────┘

网络分配:
- 网关/DNS: 192.168.1.1
- 静态设备: 192.168.1.10-49 (打印机、NAS、摄像头)
- DHCP 池: 192.168.1.100-200 (手机、电脑、平板)
- IoT 设备: 192.168.1.200-250

12.4.2 完整配置

# /etc/dnsmasq.d/00-base.conf
bind-interfaces
listen-address=127.0.0.1,192.168.1.1
port=53
cache-size=500
min-cache-ttl=300
neg-ttl=60
domain=home.lan
expand-hosts
local=/home.lan/

# /etc/dnsmasq.d/01-upstream.conf
server=223.5.5.5
server=119.29.29.29
server=8.8.8.8
no-resolv

# /etc/dnsmasq.d/10-dhcp.conf
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

# 静态绑定
dhcp-host=aa:bb:cc:dd:ee:01,192.168.1.10,nas,24h
dhcp-host=aa:bb:cc:dd:ee:02,192.168.1.20,printer,infinite

# /etc/dnsmasq.d/50-filter.conf
# 广告屏蔽
conf-file=/etc/dnsmasq.adblock

# /etc/dnsmasq.d/90-security.conf
stop-dns-rebind
rebind-localhost-ok
bogus-priv
except-interface=eth0
# /etc/dnsmasq.hosts
192.168.1.1     gateway gateway.home.lan
192.168.1.10    nas nas.home.lan
192.168.1.20    printer printer.home.lan
192.168.1.30    camera-front camera-front.home.lan
192.168.1.31    camera-back camera-back.home.lan

12.4.3 OpenWrt 集成

# OpenWrt 使用 UCI 管理 Dnsmasq
# 配置文件:/etc/config/dhcp

# 查看当前配置
uci show dhcp

# 设置上游 DNS
uci set dhcp.@dnsmasq[0].server='223.5.5.5'
uci set dhcp.@dnsmasq[0].server='8.8.8.8'

# 设置缓存大小
uci set dhcp.@dnsmasq[0].cachesize='500'

# 添加静态租约
uci add dhcp host
uci set dhcp.@host[-1].mac='AA:BB:CC:DD:EE:01'
uci set dhcp.@host[-1].ip='192.168.1.10'
uci set dhcp.@host[-1].name='nas'

# 提交配置
uci commit dhcp

# 重启服务
/etc/init.d/dnsmasq restart

12.5 企业网络部署方案

12.5.1 推荐架构

                    Internet
                       │
                   ┌───┴───┐
                   │ 防火墙 │
                   └───┬───┘
                       │
              ┌────────┼────────┐
              │        │        │
         ┌────┴───┐    │   ┌────┴───┐
         │ Dnsmasq│    │   │ Dnsmasq│
         │ 主节点  │    │   │ 备节点  │
         │ .1.1   │    │   │ .1.2   │
         └────┬───┘    │   └────┬───┘
              │        │        │
              └────────┼────────┘
                       │
                   VIP: .1.254
                       │
        ┌──────────────┼──────────────┐
        │              │              │
   ┌────┴────┐   ┌────┴────┐   ┌────┴────┐
   │ VLAN 10 │   │ VLAN 20 │   │ VLAN 30 │
   │ 办公网络 │   │ 访客网络 │   │ IoT 网络 │
   │ .10.0/24│   │ .20.0/24│   │ .30.0/24│
   └─────────┘   └─────────┘   └─────────┘

12.5.2 多 VLAN 企业配置

# /etc/dnsmasq.d/00-base.conf
bind-interfaces
domain=corp.lan
expand-hosts
no-hosts
addn-hosts=/etc/dnsmasq.hosts

# /etc/dnsmasq.d/01-upstream.conf
server=/corp.lan/10.0.0.53     # 企业内网 DNS
server=223.5.5.5               # 公网 DNS
no-resolv

# /etc/dnsmasq.d/10-vlan10-office.conf
listen-address=192.168.10.1
interface=eth1.10
dhcp-range=set:office,192.168.10.100,192.168.10.200,255.255.255.0,12h
dhcp-option=tag:office,option:router,192.168.10.1
dhcp-option=tag:office,option:dns-server,192.168.10.1,10.0.0.53
dhcp-option=tag:office,option:ntp-server,10.0.0.1
dhcp-option=tag:office,option:domain-name,"office.corp.lan"

# /etc/dnsmasq.d/11-vlan20-guest.conf
listen-address=192.168.20.1
interface=eth1.20
dhcp-range=set:guest,192.168.20.100,192.168.20.200,255.255.255.0,2h
dhcp-option=tag:guest,option:router,192.168.20.1
dhcp-option=tag:guest,option:dns-server,223.5.5.5

# /etc/dnsmasq.d/12-vlan30-iot.conf
listen-address=192.168.30.1
interface=eth1.30
dhcp-range=set:iot,192.168.30.100,192.168.30.250,255.255.255.0,168h
dhcp-option=tag:iot,option:router,192.168.30.1
dhcp-option=tag:iot,option:dns-server,192.168.30.1

# 安全:访客网络禁止访问内网
# 通过 iptables 实现,不在 Dnsmasq 中配置

12.5.3 企业级监控集成

# Prometheus + Grafana 监控 Dnsmasq
# docker-compose.monitoring.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

  dnsmasq-exporter:
    image: google/dnsmasq_exporter:latest
    command:
      - "--dnsmasq.address=http://127.0.0.1:53"
    ports:
      - "9153:9153"
    network_mode: host

12.6 容器化部署最佳实践

12.6.1 生产级 Docker Compose

# docker-compose.prod.yml
version: '3.8'

services:
  dnsmasq:
    image: jpillora/dnsmasq:latest
    container_name: dnsmasq
    restart: always
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
    volumes:
      - ./config/dnsmasq.conf:/etc/dnsmasq.conf:ro
      - ./config/dnsmasq.d:/etc/dnsmasq.d:ro
      - ./config/hosts:/etc/dnsmasq.hosts:ro
      - dnsmasq-leases:/var/lib/misc
      - dnsmasq-logs:/var/log/dnsmasq
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=Asia/Shanghai
      - HTTP_USER=admin
      - HTTP_PASS_FILE=/run/secrets/admin_password
    secrets:
      - admin_password
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 128M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "5"
    healthcheck:
      test: ["CMD", "nslookup", "baidu.com", "127.0.0.1"]
      interval: 30s
      timeout: 5s
      retries: 3

volumes:
  dnsmasq-leases:
  dnsmasq-logs:

secrets:
  admin_password:
    file: ./secrets/admin_password.txt

12.7 配置模板与速查

12.7.1 最小可用配置

# 只需 3 行即可运行
listen-address=192.168.1.1
interface=eth1
dhcp-range=192.168.1.100,192.168.1.200,24h

12.7.2 功能完整配置

# 15 行覆盖基本需求
bind-interfaces
listen-address=127.0.0.1,192.168.1.1
domain=home.lan
expand-hosts
server=223.5.5.5
server=8.8.8.8
no-resolv
cache-size=500
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
stop-dns-rebind
except-interface=eth0

12.7.3 常用命令速查

# 服务管理
systemctl start dnsmasq           # 启动
systemctl stop dnsmasq            # 停止
systemctl restart dnsmasq         # 重启
systemctl reload dnsmasq          # 热重载配置
systemctl status dnsmasq          # 查看状态

# 配置检查
dnsmasq --test                    # 语法检查
dnsmasq --version                 # 查看版本
dig @127.0.0.1 example.com        # 测试 DNS
cat /var/lib/misc/dnsmasq.leases  # 查看租约

# 调试
dnsmasq --no-daemon --log-facility=-  # 前台运行
journalctl -u dnsmasq -f          # 实时日志
tcpdump -i eth1 -n port 53        # 抓包分析

# 监控
kill -USR1 $(pidof dnsmasq)       # 输出统计
kill -USR2 $(pidof dnsmasq)       # 输出租约信息
ps aux | grep dnsmasq             # 进程状态

12.8 版本升级指南

12.8.1 升级前检查

# 1. 备份当前配置
sudo tar czf /backup/dnsmasq-pre-upgrade.tar.gz /etc/dnsmasq.*

# 2. 记录当前版本
dnsmasq --version > /backup/dnsmasq-version-before.txt

# 3. 检查新版本 changelog
# http://www.thekelleys.org.uk/dnsmasq/CHANGELOG

# 4. 在测试环境验证

12.8.2 升级步骤

# 使用包管理器升级
sudo apt update && sudo apt upgrade dnsmasq

# 检查配置兼容性
sudo dnsmasq --test

# 重启服务
sudo systemctl restart dnsmasq

# 验证功能
dig @127.0.0.1 www.baidu.com
cat /var/lib/misc/dnsmasq.leases

12.9 小结

类别关键实践重要程度
安全bind-interfaces + 防火墙⭐⭐⭐
安全stop-dns-rebind + bogus-priv⭐⭐⭐
性能合理 cache-size + min-cache-ttl⭐⭐
运维Git 管理配置 + 定期备份⭐⭐⭐
运维健康检查 + 告警⭐⭐
部署no-hosts + addn-hosts⭐⭐
部署分环境配置文件⭐⭐

12.10 扩展阅读