使用 dnsmasq 搭建本地 DNS 服务器完整指南

概述

在企业内部网络或开发测试环境中,经常需要搭建本地 DNS 服务器来解析自定义域名。dnsmasq 是一个轻量级的 DNS 转发器和 DHCP 服务器,非常适合这种场景。本文将详细记录我从零开始搭建 dnsmasq DNS 服务器,并解决遇到的各种错误的完整过程。

DNS 服务器工具选型指南

主要 DNS 服务器工具对比

使用 dnsmasq 搭建本地 DNS 服务器完整指南

选型建议

  1. 开发测试环境:推荐 dnsmasq,配置简单,启动快速
  2. 生产环境小规模:dnsmasq 或 Unbound
  3. 企业级部署:BIND 或 PowerDNS
  4. 云原生/容器环境:CoreDNS
  5. 需要集成DHCP:dnsmasq

环境准备

  • 操作系统: CentOS/RHEL 或 Ubuntu/Debian
  • 服务器 IP: 192.168.1.201
  • 目标域名:
    • aaa-test.comm → 192.168.1.188
    • bbb.test.comm → 192.168.1.201

第一阶段:基础安装与初始配置

安装 dnsmasq

在 Ubuntu/Debian 上:

sudo apt update
sudo apt install dnsmasq

在 CentOS/RHEL 上:

sudo yum install dnsmasq

初始配置文件

创建初始配置文件 (/etc/dnsmasq.conf):

# 基本网络配置
port=53
listen-address=192.168.1.201,127.0.0.1

# 上游DNS服务器(用于解析非本地域名)
server=192.168.100.99

# 安全配置
user=dnsmasq
group=dnsmasq
local-service=host

# 域名处理
local=/comm/
domain=comm

# 域名解析 - 使用双重保障
address=/bbb.test.comm/192.168.1.201
host-record=bbb.test.comm,192.168.1.201

address=/aaa-test.comm/192.168.1.188
host-record=aaa-test.comm,192.168.1.188

启动服务

sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq

为什么选择 dnsmasq

在本次实践中选择 dnsmasq 的主要原因:

轻量级: 资源占用极少,适合运行在资源受限的环境中
零配置启动: 默认配置即可工作,适合快速部署
集成 DHCP: 可同时提供 IP 地址分配服务
易于调试: 详细的日志输出,便于问题排查
广泛支持: 大多数 Linux 发行版官方仓库都包含

第二阶段:遇到的问题与解决方案

问题 1: REFUSED 错误

错误信息:

nslookup aaa-test.comm 192.168.1.201
Server: 192.168.1.201
Address: 192.168.1.201#53

Name: aaa-test.comm
Address: 192.168.1.188
** server can't find aaa-test.comm: REFUSED

调试命令:

# 检查服务状态
sudo systemctl status dnsmasq

# 检查配置文件
sudo grep -v "^#" /etc/dnsmasq.conf | grep -v "^$"

# 测试配置语法
sudo dnsmasq --test

解决方案:
添加本地域名声明:

local=/comm/
domain=comm

问题 2: SERVFAIL 错误

错误信息:

nslookup aaa-test.comm 192.168.1.201
Server: 192.168.1.201
Address: 192.168.1.201#53

Name: aaa-test.comm
Address: 192.168.1.188
** server can't find aaa-test.comm: SERVFAIL

调试命令:

# 启用调试模式查看详细日志
sudo systemctl stop dnsmasq
sudo dnsmasq --no-daemon --log-queries --conf-file=/etc/dnsmasq.conf

解决方案:
完全禁用上游 DNS 转发:

no-resolv
no-poll

问题 3: NXDOMAIN 错误

错误信息:

nslookup aaa-test.comm 192.168.1.201
** server can't find aaa-test.comm: NXDOMAIN

调试命令:

# 检查当前配置
sudo grep -v "^#" /etc/dnsmasq.conf | grep -v "^$"

解决方案:
增加配置语法:

host-record=aaa-test.comm,192.168.1.188

详细的调试命令集

基本服务状态检查

# 检查服务状态
sudo systemctl status dnsmasq

# 查看服务日志
sudo journalctl -u dnsmasq -f

# 查看最近10条日志
sudo journalctl -u dnsmasq -n 10 --no-pager

网络和端口检查

# 检查53端口监听情况
sudo netstat -tulpn | grep :53

# 检查防火墙状态
sudo iptables -L -n

# 测试网络连通性
ping -c 3 192.168.1.201

DNS 查询测试命令

# 使用nslookup测试
nslookup aaa-test.comm 192.168.1.201

# 使用dig测试(更详细)
dig @192.168.1.201 aaa-test.comm

# 测试反向解析
dig @192.168.1.201 -x 192.168.1.188

# 使用host命令测试
host aaa-test.comm 192.168.1.201

配置文件检查和验证

# 检查主配置文件
sudo cat /etc/dnsmasq.conf

# 检查非注释行
sudo grep -v "^#" /etc/dnsmasq.conf | grep -v "^$"

# 测试配置文件语法
sudo dnsmasq --test

高级调试技巧

# 调试模式运行(前台运行,显示详细日志)
sudo systemctl stop dnsmasq
sudo pkill dnsmasq
sudo dnsmasq --no-daemon --log-queries --conf-file=/etc/dnsmasq.conf

# 检查进程运行参数
ps aux | grep dnsmasq | grep -v grep

第三阶段:最终成功配置

完整配置文件 (/etc/dnsmasq.conf)

# 基本网络配置
port=53
listen-address=192.168.1.201,127.0.0.1

# 上游DNS服务器(用于解析非本地域名)
server=192.168.100.99

# 安全配置
user=dnsmasq
group=dnsmasq
local-service=host

# 域名处理
local=/comm/
domain=comm

# 域名解析 - 使用双重保障
address=/bbb.test.comm/192.168.1.201
host-record=bbb.test.comm,192.168.1.201

address=/aaa-test.comm/192.168.1.188
host-record=aaa-test.comm,192.168.1.188

配置验证命令

# 重启服务应用新配置
sudo systemctl restart dnsmasq

# 验证配置语法
sudo dnsmasq --test

# 测试域名解析
nslookup aaa-test.comm 192.168.1.201
nslookup bbb.test.comm 192.168.1.201

# 使用dig进行详细验证
dig @192.168.1.201 aaa-test.comm +short
dig @192.168.1.201 bbb.test.comm +short

最终验证结果

成功解析的返回信息:

nslookup aaa-test.comm 192.168.1.201
Server: 192.168.1.201
Address: 192.168.1.201#53

Name: aaa-test.comm
Address: 192.168.1.188

其他 DNS 工具的使用场景

如果选择 BIND

BIND 的配置会更加复杂,但功能更强大:

# 安装 BIND
sudo yum install bind bind-utils

# 配置示例
zone "comm" IN {
type master;
file "comm.zone";
};

如果选择 CoreDNS

CoreDNS 使用更现代的配置方式:

# Corefile 配置
.:53 {
hosts {
192.168.1.188 aaa-test.comm
192.168.1.201 bbb.test.comm
fallthrough
}
forward . 192.168.100.99
cache
}

第四阶段:同 IP 不同端口服务的域名配置

DNS 配置部分

在 dnsmasq 中配置多个域名指向同一 IP:

address=/web.comm/192.168.1.188
address=/api.comm/192.168.1.188
address=/db.comm/192.168.1.188

使用 Nginx 反向代理处理端口差异

server {
listen 80;
server_name web.comm;
location / {
proxy_pass http://192.168.1.188:3000;
}
}

server {
listen 80;
server_name api.comm;
location / {
proxy_pass http://192.168.1.188:3001;
}
}

第五阶段:高级功能与优化

通配符域名解析

# 所有 .comm 子域名都解析到指定 IP
address=/.comm/192.168.1.188

性能优化

cache-size=1000
local-ttl=300

客户端配置

Linux/Mac:

echo "nameserver 192.168.1.201" | sudo tee /etc/resolv.conf

Windows: 在网络适配器设置中将 DNS 服务器设置为 192.168.1.201

工具选型总结表

使用 dnsmasq 搭建本地 DNS 服务器完整指南

经验总结
调试命令总结
服务状态检查: systemctl status dnsmasq
配置文件验证: dnsmasq --test
DNS查询测试: nslookup、dig、host
实时日志监控: journalctl -u dnsmasq -f
网络端口检查: netstat -tulpn | grep :53
调试模式运行: dnsmasq --no-daemon --log-queries
成功关键点
逐步排查: 从简单配置开始,逐步添加复杂功能
理解错误信息: 不同的错误代码指向不同的问题根源
双重保障: 使用多种方式配置同一功能提高可靠性
平衡安全与便利: 在安全性和功能性之间找到平衡点

阅读剩余
THE END