作者:刘大硕
语言:Go 1.21+
许可:MIT License
代码量:~5800 行(50+ 源文件)
GoDNS 是一款用 Go 语言编写的轻量级 DNS 中转服务器,旨在替代手动维护本机 hosts 文件。
- 开发测试环境中需要将非真实域名(如
*.test.com)解析到内网测试服务器 - 域名数量多、变更频繁、需要在团队内共享配置
- 传统修改
hosts文件方式维护成本高且易出错
客户端 DNS 请求(:53)
│
▼
┌──────────────┐ 命中 ┌──────────────┐
│ 规则匹配器 │──────────→│ 返回自定义 IP │
│ (预编译正则) │ └──────────────┘
└──────┬───────┘
│ 未命中
▼
┌──────────────┐
│ 上游 DNS 转发 │──→ 114.114.114.114 / 8.8.8.8 / ...
│ (连接池+熔断) │
└──────────────┘
- 命中规则:返回配置文件 / 数据库中预设的自定义 IP
- 未命中:转发到上游公共 DNS 服务器解析
- 缓存加速:上游解析结果自动缓存(TTL 感知 + LRU 淘汰)
| 模块 | 功能 | 状态 |
|---|---|---|
| DNS 服务 | UDP DNS 服务器,监听 53 端口 | ✅ |
| 域名规则 | 精确匹配 + 泛域名通配符(*.example.com / (.*).example.com) |
✅ |
| 记录类型 | 13 种:A / AAAA / CNAME / TXT / MX / SRV / NS / SOA / PTR / DNAME / SPF / DKIM / DMARC | ✅ |
| 上游转发 | 多上游 DNS + 智能测速选路 + 连接池 + 故障转移 | ✅ |
| 缓存系统 | TTL 感知内存缓存 + LRU 淘汰 + 上游 TTL 提取 | ✅ |
| Web 管理 | 浏览器管理域名规则和上游服务器,密码认证 | ✅ |
| 密码管理 | 首次启动自动生成密码 + Web 修改密码 + 忘记密码一键重置 | ✅ |
| CLI 仪表盘 | 启动显示作者、监听地址、规则数、上游状态、密码 | ✅ |
| 安全防护 | ACL 访问控制 + 令牌桶速率限制 + 上游熔断器 | ✅ |
| 服务器标识 | PTR 反向查询自动返回配置的服务器主机名 | ✅ |
| 可观测性 | Prometheus 指标暴露 + 健康检查端点 + JSON 状态 API | ✅ |
| 日志系统 | 结构化日志(slog)+ 查询 TSV 日志 + 按大小/天数轮转 | ✅ |
| 配置热加载 | fsnotify 监听配置文件变更,自动重载 | ✅ |
| 系统服务 | Windows Service / Linux systemd Daemon | ✅ |
| 优雅关闭 | SIGTERM 信号捕获,等待进行中请求完成 | ✅ |
| 跨平台 | Windows / Linux / macOS(amd64 + arm64) | ✅ |
| 数据库 | SQLite(纯 Go 实现,零 CGO 依赖) | ✅ |
| 指标 | 数值 |
|---|---|
| 最大并发请求 | 10000+ QPS(取决于硬件) |
| 缓存容量 | 可配置(默认 10000 条) |
| 上游测速间隔 | 可配置(默认 60s) |
| 规则匹配延迟 | < 1μs(预编译正则) |
| 二进制体积 | ~15 MB(静态编译,无外部依赖) |
┌──────────────────────────────────────────────────────┐
│ Web 管理后台(:8530) │
│ 浏览器操作域名规则 / 上游管理 / 密码修改 │
├──────────────────────────────────────────────────────┤
│ CLI 仪表盘(启动打印) │
│ 作者信息 / 监听地址 / 规则数 / 运行状态 │
├──────────────────────────────────────────────────────┤
│ DNS 核心引擎(:53) │
│ ┌───────────┐ ┌───────────┐ ┌────────────────┐ │
│ │ 请求解析器 │→│ 规则匹配器 │→│ 响应构造器/转发器 │ │
│ │ (parser) │ │ (matcher) │ │ (responder/ │ │
│ │ │ │ 预编译正则 │ │ forwarder) │ │
│ └───────────┘ └───────────┘ └────────────────┘ │
│ ↓ ↓ ↓ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 缓存层(TTL-aware LRU Cache) │ │
│ └────────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 安全层(ACL / 令牌桶限流 / 熔断器) │ │
│ └────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────┤
│ 数据持久层 │
│ ┌──────────┐ ┌────────────┐ ┌────────────────┐ │
│ │ SQLite │ │ config.yaml │ │ 日志文件(轮转) │ │
│ │ (域名/ │ │ (YAML) │ │ server.log │ │
│ │ 上游/ │ │ │ │ query.log │ │
│ │ 用户) │ │ │ │ │ │
│ └──────────┘ └────────────┘ └────────────────┘ │
├──────────────────────────────────────────────────────┤
│ 可观测性 & 运维(:9090) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │Prometheus│ │ 健康检查 │ │ 优雅关闭(SIGTERM)│ │
│ │ /metrics │ │ /health │ │ │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────────────────────────────────────────┘
godns/
├── main.go # 入口
├── config.yaml # 主配置文件
├── host2ip.txt # 域名映射文件(可选,启动时导入)
├── go.mod / go.sum # Go 模块依赖
├── Makefile # 构建脚本
│
├── cmd/ # CLI 命令
│ ├── serve.go # 启动服务
│ ├── install.go / uninstall.go # 系统服务安装/卸载
│ ├── resetpwd.go # 重置 Web 密码
│ └── version.go # 版本信息
│
├── internal/
│ ├── config/ # 配置管理(YAML 加载 + 热加载)
│ ├── dns/ # DNS 核心引擎
│ │ ├── server.go # UDP DNS 服务器
│ │ ├── parser.go # DNS 包解析
│ │ ├── matcher.go # 规则匹配器(预编译正则)
│ │ ├── responder.go # 响应构造器(13 种记录类型)
│ │ ├── forwarder.go # 上游转发器
│ │ ├── cache.go # TTL 感知缓存
│ │ └── types.go # 类型定义
│ ├── upstream/ # 上游连接池 / 探测 / 选择策略
│ ├── rule/ # 规则管理 / 加载 / 校验
│ ├── web/ # Web 管理后台
│ │ ├── server.go # HTTP 服务器 + 路由
│ │ └── handler/ # 请求处理器 + HTML 模板
│ ├── db/ # SQLite 数据库层
│ ├── security/ # ACL / 限流 / 熔断
│ ├── logger/ # 日志系统(slog + 轮转)
│ ├── metrics/ # Prometheus 指标
│ └── service/ # 系统服务集成
│
├── pkg/ # 公共工具包
│ ├── version/ # 版本信息
│ └── utils/ # 加密 / 网络工具
│
└── scripts/ # 运维脚本
├── init.sql # 数据库初始化 SQL
├── install.sh # Linux 安装脚本
└── install.bat # Windows 安装脚本
- Go 1.21+:https://go.dev/dl/
- Git(可选,用于版本标识)
# 克隆项目(或解压源码到目录)
cd godns
# 编译(当前平台)
go build -ldflags "-s -w" -o godns .
# 编译 Linux 版本
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o godns-linux-amd64 .
# 编译 Windows 版本
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o godns-windows-amd64.exe .
# 使用 Makefile 一键编译所有平台
make build-all编译产物在 bin/ 目录下:
bin/
├── godns-linux-amd64 # Linux x86_64
├── godns-linux-arm64 # Linux ARM64
└── godns-windows-amd64.exe # Windows x64
编译使用
CGO_ENABLED=0产生完全静态链接的二进制文件,不依赖任何外部 DLL 或 SO 库(SQLite 使用纯 Go 实现),可直接拷贝到目标机器运行。
DNS 服务需要监听 53 端口(UDP),该端口经常被系统服务占用。以下提供 Windows 和 Linux 的解决方法。
Windows 的 DNS Client 服务(dnscache)默认占用 53 端口。
通过服务管理器(GUI):
- 按
Win+R,输入services.msc,回车 - 找到 DNS Client 服务
- 右键 → 停止
- 右键 → 属性 → 启动类型改为 禁用
- 点击确定
通过命令行(管理员 PowerShell):
# 停止 DNS Client 服务
Stop-Service -Name Dnscache -Force
# 禁用开机自启
Set-Service -Name Dnscache -StartupType Disabled
# 验证 53 端口已释放
netstat -ano | findstr ":53 "ICS 服务也可能占用 53 端口:
Stop-Service -Name SharedAccess -Force
Set-Service -Name SharedAccess -StartupType Disabled某些 Windows 版本有其他 DNS 相关服务:
# 查看占用 :53 的进程
netstat -ano | findstr ":53 "
# 假设 PID 是 1234,查看进程名
tasklist | findstr "1234"
# 强制结束该进程(将 1234 替换为实际 PID)
taskkill /F /PID 1234如果必须保留系统 DNS 服务,可将 GoDNS 部署在另一台机器上,或使用其他端口:
# config.yaml
server:
dns:
port: 5353 # 使用非标准端口然后配置客户端使用 192.168.31.154:5353。
# 查看 53 端口占用
sudo lsof -i :53
sudo ss -tulnp | grep :53
# 停止 systemd-resolved
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
# 修改 resolv.conf(否则 DNS 可能不工作)
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.confsudo systemctl stop dnsmasq
sudo systemctl disable dnsmasqsudo systemctl stop named
sudo systemctl disable named# 编辑 NetworkManager 配置
sudo nano /etc/NetworkManager/NetworkManager.conf在 [main] 段添加:
dns=nonesudo systemctl restart NetworkManager如果无法释放 53 端口,也可以让其他程序使用高端口:
# 允许 GoDNS 绑定 53 端口(无需 root)
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/godns# 安装服务(管理员 PowerShell/CMD)
godns-windows-amd64.exe install
# 启动服务
sc start GoDNS
# 查看状态
sc query GoDNS
# 停止服务
sc stop GoDNS
# 卸载服务
godns-windows-amd64.exe uninstall# 安装服务(需要 root)
sudo ./godns-linux-amd64 install
# 启动服务
sudo systemctl start godns
# 设置开机自启
sudo systemctl enable godns
# 查看状态
sudo systemctl status godns
# 停止服务
sudo systemctl stop godns
# 卸载服务
sudo ./godns-linux-amd64 uninstallGoDNS 使用 config.yaml 作为主配置文件,首次启动时自动读取。
server:
# 服务器身份标识(nslookup 显示的服务器名称)
identity:
hostname: "godns.local"
# DNS 服务监听配置
dns:
ip: "0.0.0.0" # 监听 IP(0.0.0.0 = 所有网卡)
port: 53 # 监听端口
protocol: "udp" # 协议:udp
read_timeout: 2s
write_timeout: 2s
max_udp_size: 4096
# Web 管理后台
web:
enabled: true # 启用/禁用 Web 管理
ip: "127.0.0.1" # 监听 IP(建议仅本地访问)
port: 8530 # 监听端口
read_timeout: 10s
write_timeout: 10s
# Prometheus 指标
metrics:
enabled: true
ip: "0.0.0.0"
port: 9090
# 数据库
database:
driver: "sqlite" # 纯 Go SQLite
dsn: "godns.db" # 数据库文件路径
max_open_conns: 1
busy_timeout: 5000 # 忙等待超时(ms)
# 上游 DNS 服务器
upstream:
servers:
- "114.114.114.114" # 114 DNS
- "223.5.5.5" # 阿里 DNS
- "8.8.8.8" # Google DNS
strategy: "fastest" # 选择策略:fastest / round_robin / failover
probe_interval: 60s # 健康探测间隔
probe_timeout: 2s # 探测超时
max_fails: 3 # 连续失败次数标记不健康
fail_timeout: 30s # 不健康后重试间隔
# 缓存
cache:
enabled: true
max_entries: 10000 # 最大缓存条目
default_ttl: 600s # 默认 TTL
min_ttl: 60s # 最小 TTL
max_ttl: 86400s # 最大 TTL
# 安全
security:
acl:
enabled: false # 是否启用 ACL
mode: "whitelist" # whitelist / blacklist
clients: [] # IP 或 CIDR 列表
rate_limit:
enabled: true
default_rate: 100 # 每秒请求数
default_burst: 200 # 突发容量
per_client: true # 按客户端 IP 区分
circuit_breaker:
enabled: true
failure_threshold: 5 # 连续失败触发熔断
timeout: 30s # 熔断恢复等待
half_open_max: 3 # 半开最大探测数
# 日志
logging:
level: "info" # debug / info / warn / error
format: "text" # text / json
server_log: "logs/server.log"
query_log: "logs/query.log"
max_size: 100 # 单文件最大 MB
max_backups: 30 # 保留文件数
max_age: 30 # 保留天数
compress: true
# 系统服务
service:
name: "GoDNS"
display_name: "GoDNS Server"
description: "轻量级 DNS 中转服务"| 环境变量 | 对应配置 |
|---|---|
GODNS_DNS_IP |
server.dns.ip |
GODNS_DNS_PORT |
server.dns.port |
GODNS_WEB_PORT |
server.web.port |
GODNS_METRICS_PORT |
server.metrics.port |
GODNS_LOG_LEVEL |
logging.level |
GODNS_DB_DSN |
database.dsn |
环境变量优先级高于配置文件。
GoDNS 自动监听 config.yaml 文件变更,以下配置项支持运行时热加载(无需重启):
| 配置项 | 热加载 |
|---|---|
upstream.* |
✅ |
cache.* |
✅ |
security.* |
✅ |
logging.level |
✅ |
server.dns.* |
❌ 需重启 |
server.web.* |
❌ 需重启 |
# 前台启动(使用默认配置文件 config.yaml)
./godns serve
# 指定配置文件
./godns serve -c /etc/godns/config.yaml
# 仅监听特定 IP
./godns serve -ip 192.168.31.154
# 查看版本
./godns version
# 查看帮助
./godns help
# 重置 Web 管理密码
./godns resetpwd╔══════════════════════════════════════════════════════╗
║ GoDNS v2.0 - 轻量 DNS 服务 ║
║ Author: 刘大硕 ║
╠══════════════════════════════════════════════════════╣
║ ║
║ 🚀 DNS 服务: udp://192.168.31.154:53 ║
║ 🌐 Web 管理: http://127.0.0.1:8530 ║
║ 📊 Prometheus: http://0.0.0.0:9090/metrics ║
║ 📁 数据库: godns.db ║
║ 📋 日志目录: logs/server.log ║
║ ║
╠══════════════════════════════════════════════════════╣
║ 启动时间: 2026-06-20 10:00:00 ║
║ 已加载规则: 5 条 (5 启用, 0 禁用) ║
║ 上游服务器: 3 个 (3 健康, 0 离线) ║
║ 最快上游: 114.114.114.114 (3ms) ║
║ Go 版本: GoDNS v2.0.0 ║
║ 运行平台: windows/amd64 ║
╠══════════════════════════════════════════════════════╣
║ ║
║ 🔑 首次启动 - Web 管理密码: ║
║ 用户名: admin ║
║ 密码: nJsyp2AsOuFCiJ1V ║
║ 请妥善保管,可通过 Web 修改 ║
║ ║
╚══════════════════════════════════════════════════════╝
http://127.0.0.1:8530
- 用户名:
admin - 密码:首次启动时自动生成并打印到终端(见仪表盘
🔑部分)
⚠️ 首次启动后请立即登录 Web 修改密码。
| 页面 | 路径 | 功能 |
|---|---|---|
| 仪表盘 | / |
规则数、上游数、系统信息概览 |
| 规则管理 | /rules |
增删改查域名解析规则 |
| 添加规则 | /rules/add |
添加新规则(含重复检测) |
| 编辑规则 | /rules/edit/{id} |
修改已有规则 |
| 上游管理 | /upstream |
增删改上游 DNS 服务器 |
| 设置 | /settings |
修改 Web 登录密码 |
方式一:命令行重置
./godns resetpwd方式二:查看启动终端 密码在服务启动时打印到终端,可滚动回溯查看。
方式三:删除数据库重新启动
# 停止服务后
rm godns.db # Linux
del godns.db # Windows
# 重启服务,将生成新密码在 http://127.0.0.1:8530/rules/add 添加规则:
| 字段 | 说明 | 示例 |
|---|---|---|
| 域名模式 | 精确域名或通配符 | www.example.com、*.test.com |
| 记录类型 | DNS 记录类型 | A、AAAA、CNAME 等 |
| 解析值 | 目标 IP 或域名 | 192.168.1.100 |
| TTL | 缓存时间(秒) | 600 |
| 优先级 | 匹配优先级(越小越优先) | 0 |
| 模式 | 说明 | 匹配示例 |
|---|---|---|
*.example.com |
匹配一级子域名 | www.example.com、api.example.com |
(.*).example.com |
匹配任意级子域名 | a.b.example.com |
www.example.com |
精确匹配 | 仅 www.example.com |
# A 记录(IPv4)
*.dev.local A 10.0.0.50
# AAAA 记录(IPv6)
ipv6.test.local AAAA ::1
# CNAME 记录(别名)
cdn.test.local CNAME cdn.example.com
# MX 记录(邮件服务器,需设置 MX 优先级)
mail.test.local MX 192.168.1.200 (优先级: 10)
# TXT 记录(文本)
test.local TXT "v=spf1 ~all"
# SRV 记录(服务发现,需设优先级/权重/端口)
_sip._tcp.local SRV sipserver.local (优先级:0 权重:5 端口:5060)
# PTR 记录(反向解析)
PTR server.local
# NS 记录(名称服务器)
local NS ns1.local
当多条规则的域名模式可能同时匹配时,优先级数字越小越优先:
*.example.com A 10.0.0.1 priority=10 # 通配符,优先级较低
www.example.com A 10.0.0.2 priority=0 # 精确匹配,优先级最高
查询 www.example.com 时返回 10.0.0.2(优先级 0 胜出)。
添加规则时系统自动检测 域名模式 + 记录类型 + 解析值 三者组合是否已存在,防止重复添加。
在程序所在目录创建 host2ip.txt,每行一条规则,格式为 域名 空格 IP:
# host2ip.txt 示例
www.baidu.com 192.168.31.1
*.test.com 10.0.0.50
(.*).dev.local 172.16.0.1
启动时自动导入(已存在的规则会被跳过,不会重复)。
GoDNS 支持 13 种 DNS 记录类型的自定义解析:
| 类型 | DNS 类型码 | 说明 | 值格式 |
|---|---|---|---|
| A | 1 | IPv4 地址 | 有效的 IPv4 地址 |
| AAAA | 28 | IPv6 地址 | 有效的 IPv6 地址 |
| CNAME | 5 | 别名(规范名称) | 有效的域名 |
| TXT | 16 | 文本记录 | 任意文本 |
| MX | 15 | 邮件交换 | 域名 + MX 优先级 |
| SRV | 33 | 服务定位 | 域名 + 优先级/权重/端口 |
| NS | 2 | 名称服务器 | 有效的域名 |
| SOA | 6 | 授权起始 | 域名 |
| PTR | 12 | 反向解析 | 域名(将 IP 映射到域名) |
| DNAME | 39 | 域名别名(子树) | 有效的域名 |
| SPF | — | 发件人策略框架 | TXT 格式文本 |
| DKIM | — | 域名密钥标识 | TXT 格式文本 |
| DMARC | — | 邮件认证报告 | TXT 格式文本 |
SPF / DKIM / DMARC 在底层均使用 TXT 记录实现,与标准 DNS 行为一致。
# 使用 dig 测试 A 记录
dig @127.0.0.1 www.example.com
# 测试 AAAA 记录
dig @127.0.0.1 www.example.com AAAA
# 测试 MX 记录
dig @127.0.0.1 example.com MX
# 测试 TXT 记录
dig @127.0.0.1 example.com TXT
# 测试 PTR 反向解析
dig @127.0.0.1 -x 192.168.1.100
# 使用 nslookup
nslookup www.example.com 127.0.0.1限制哪些客户端可以使用 DNS 服务:
security:
acl:
enabled: true
mode: "whitelist" # 白名单模式
clients:
- "192.168.1.0/24" # 允许整个子网
- "10.0.0.50" # 允许单个 IP- whitelist:仅列表中的 IP 可查询
- blacklist:列表中的 IP 被拒绝
防止 DNS 放大攻击和滥用:
security:
rate_limit:
enabled: true
default_rate: 100 # 每秒 100 次请求
default_burst: 200 # 突发 200 次
per_client: true # 按客户端 IP 独立限流上游 DNS 服务器连续失败后自动熔断,防止级联故障:
security:
circuit_breaker:
enabled: true
failure_threshold: 5 # 连续 5 次失败 → 熔断
timeout: 30s # 熔断 30 秒后进入半开状态
half_open_max: 3 # 半开时最多 3 次探测请求状态转换:
正常(Closed)──5次连续失败──→ 熔断(Open)
│ 30秒后
▼
半开(HalfOpen)
成功→Closed / 失败→Open
- 密码使用 bcrypt 哈希(cost=12),不可逆
- Session Token 为 64 字符随机 hex,HttpOnly + SameSite Cookie
- 密码重置 Token 仅本机有效,10 分钟过期
- 登录失败 5 次后锁定 15 分钟(待实现)
访问 http://0.0.0.0:9090/metrics 获取 Prometheus 格式指标:
| 指标名 | 类型 | 说明 |
|---|---|---|
godns_dns_rules_loaded |
Gauge | 已加载规则数 |
godns_cache_entries |
Gauge | 当前缓存条目数 |
godns_cache_max_entries |
Gauge | 缓存最大容量 |
godns_upstream_total |
Gauge | 上游服务器总数 |
godns_upstream_healthy |
Gauge | 健康上游数 |
godns_upstream_latency_ms |
Gauge | 上游延迟(ms,按服务器) |
godns_goroutines |
Gauge | 当前 goroutine 数 |
godns_memory_alloc_bytes |
Gauge | 堆内存分配量 |
curl http://0.0.0.0:9090/health
# {"status":"ok","time":"2026-06-20T10:00:00Z"}curl http://0.0.0.0:9090/api/status返回 JSON:
{
"status": "running",
"time": "2026-06-20T10:00:00Z",
"version": "2.0.0",
"stats": {
"rules_loaded": 5,
"cache_entries": 128,
"upstream_total": 3,
"upstream_healthy": 3,
"goroutines": 24
}
}| 日志文件 | 内容 | 格式 |
|---|---|---|
logs/server.log |
服务运行日志(启动/关闭/错误/规则变更) | text/json |
logs/query.log |
DNS 查询日志 | TSV |
查询日志格式(制表符分隔):
时间\t客户端IP\t请求域名\t查询类型\t结果IP\t来源\t上游服务器\t响应时间(ms)
示例:
2026-06-20T10:00:00.123Z 192.168.1.100 www.baidu.com A 192.168.31.1 rule - 0.12
2026-06-20T10:00:01.456Z 192.168.1.100 github.com A 20.205.243.166 upstream 8.8.8.8 45.67
2026-06-20T10:00:02.789Z 192.168.1.100 api.test.com A 10.0.0.5 cache - 0.05
配置文件控制轮转策略:
logging:
max_size: 100 # 单文件超过 100MB 时轮转
max_backups: 30 # 保留最近 30 个文件
max_age: 30 # 保留 30 天
compress: true # 压缩旧文件GoDNS 使用 fsnotify 监听配置文件变更。修改 config.yaml 后保存即生效(部分配置项无需重启)。
支持热加载的配置项:
upstream.servers— 重新初始化上游连接池upstream.strategy— 切换选择策略security.acl.*— 原子替换 ACL 规则security.rate_limit.*— 更新限流器参数cache.*— 调整缓存策略logging.level— 运行时切换日志级别
监听端口变更(
server.dns.port、server.web.port)需要重启服务。
症状:dig @127.0.0.1 example.com 超时
排查步骤:
-
确认服务已启动:
netstat -ano | findstr ":53 " # Windows sudo ss -tulnp | grep :53 # Linux
-
检查防火墙:
- Windows:允许
godns.exe通过防火墙 - Linux:
sudo ufw allow 53/udp
- Windows:允许
-
检查上游 DNS 状态(查看启动仪表盘或
/metrics) -
查看日志
logs/server.log
症状:访问 http://127.0.0.1:8530 显示空白
排查步骤:
- 确认 Web 服务已启用:
config.yaml中server.web.enabled: true - 检查端口冲突:
netstat -ano | findstr ":8530" - 删除浏览器缓存后重试
/login
症状:配置了规则但查询不返回自定义 IP
排查步骤:
- Web 管理后台确认规则状态是"启用"
- 检查优先级设置(更精确的规则应设更低优先级)
- 查看 DNS 查询日志
logs/query.log,确认来源列是否为rule - 使用
dig替代nslookup测试(nslookup 会同时发送 AAAA 查询混淆判断)
症状:nslookup 显示 服务器: UnKnown
原因:nslookup 发送 PTR 查询获取服务器主机名,未配置 server.identity.hostname
解决:在 config.yaml 中配置:
server:
identity:
hostname: "godns.local" # 自定义服务器名称参考 4.2 解除本机 53 端口占用。
症状:日志出现 database is locked
解决:
- 增加
busy_timeout值:database.busy_timeout: 10000 - 确保只有一个 GoDNS 实例在运行
- 删除
godns.db重新启动(会丢失 Web 管理的规则,host2ip.txt 的规则会自动重新导入)
| 包 | 版本 | 用途 |
|---|---|---|
github.com/google/gopacket |
v1.1.19 | DNS 包解析和序列化 |
modernc.org/sqlite |
v1.52.0 | SQLite 数据库(纯 Go) |
github.com/fsnotify/fsnotify |
v1.7.0 | 配置文件热加载 |
golang.org/x/time/rate |
v0.15.0 | 令牌桶速率限制 |
golang.org/x/crypto |
v0.24.0 | bcrypt 密码哈希 |
golang.org/x/sys |
v0.42.0 | Windows Service API |
gopkg.in/natefinch/lumberjack.v2 |
v2.2.1 | 日志文件轮转 |
gopkg.in/yaml.v3 |
v3.0.1 | YAML 配置解析 |
# 完整编译命令
CGO_ENABLED=0 \ # 禁用 CGO,纯 Go 编译
GOOS=windows \ # 目标操作系统
GOARCH=amd64 \ # 目标架构
go build \
-ldflags "-s -w" \ # -s 去除符号表,-w 去除 DWARF 调试信息
-o godns-windows-amd64.exe # 输出文件名
.# 启动服务
godns serve
# 指定 IP 启动
godns serve -ip 192.168.31.154
# 安装系统服务
godns install
# 卸载系统服务
godns uninstall
# 查看版本
godns version
# 重置 Web 密码
godns resetpwd
# 查看帮助
godns help# 1. 启动服务
./godns serve
# 2. 另开终端,测试 DNS 解析
dig @127.0.0.1 www.baidu.com
# 3. 测试自定义规则(需先在 Web 添加规则)
dig @127.0.0.1 your-custom-domain.com
# 4. 检查 Web 管理
curl http://127.0.0.1:8530/login
# 5. 检查 Prometheus 指标
curl http://127.0.0.1:9090/metrics
# 6. 检查健康状态
curl http://127.0.0.1:9090/health以下是最小化可运行配置(复制保存为 config.yaml):
server:
identity:
hostname: "godns.local"
dns:
ip: "0.0.0.0"
port: 53
web:
enabled: true
ip: "127.0.0.1"
port: 8530
metrics:
enabled: true
ip: "0.0.0.0"
port: 9090
database:
driver: "sqlite"
dsn: "godns.db"
upstream:
servers:
- "114.114.114.114"
- "8.8.8.8"
strategy: "fastest"
cache:
enabled: true
max_entries: 10000
security:
rate_limit:
enabled: true
default_rate: 100
default_burst: 200
per_client: true
circuit_breaker:
enabled: true
logging:
level: "info"
server_log: "logs/server.log"
query_log: "logs/query.log"
max_size: 100文档版本:v2.0.0
最后更新:2026-06-20
作者:刘大硕
项目地址:`https://github.com/hackliu/godnsserver