Skip to content

hackliu/Go_DNS_Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GoDNS v2.0 — 轻量级 DNS 中转服务

作者:刘大硕
语言:Go 1.21+
许可:MIT License
代码量:~5800 行(50+ 源文件)


目录

  1. 项目简介
  2. 核心功能
  3. 系统架构
  4. 编译与安装
  5. 配置说明
  6. 使用方法
  7. DNS 记录类型支持
  8. 安全体系
  9. 监控与运维
  10. 配置热加载
  11. 故障排查
  12. 附录

1. 项目简介

GoDNS 是一款用 Go 语言编写的轻量级 DNS 中转服务器,旨在替代手动维护本机 hosts 文件。

业务场景

  • 开发测试环境中需要将非真实域名(如 *.test.com)解析到内网测试服务器
  • 域名数量多、变更频繁、需要在团队内共享配置
  • 传统修改 hosts 文件方式维护成本高且易出错

工作原理

客户端 DNS 请求(:53)
      │
      ▼
┌──────────────┐    命中     ┌──────────────┐
│  规则匹配器   │──────────→│  返回自定义 IP  │
│ (预编译正则)  │           └──────────────┘
└──────┬───────┘
       │ 未命中
       ▼
┌──────────────┐
│  上游 DNS 转发 │──→ 114.114.114.114 / 8.8.8.8 / ...
│ (连接池+熔断) │
└──────────────┘
  • 命中规则:返回配置文件 / 数据库中预设的自定义 IP
  • 未命中:转发到上游公共 DNS 服务器解析
  • 缓存加速:上游解析结果自动缓存(TTL 感知 + LRU 淘汰)

2. 核心功能

2.1 功能清单

模块 功能 状态
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 依赖)

2.2 性能指标

指标 数值
最大并发请求 10000+ QPS(取决于硬件)
缓存容量 可配置(默认 10000 条)
上游测速间隔 可配置(默认 60s)
规则匹配延迟 < 1μs(预编译正则)
二进制体积 ~15 MB(静态编译,无外部依赖)

3. 系统架构

3.1 分层架构图

┌──────────────────────────────────────────────────────┐
│                  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  │  │                  │   │
│  └──────────┘  └──────────┘  └──────────────────┘   │
└──────────────────────────────────────────────────────┘

3.2 项目目录结构

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 安装脚本

4. 编译与安装

4.1 编译

前置要求

本地编译

# 克隆项目(或解压源码到目录)
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 实现),可直接拷贝到目标机器运行。

4.2 解除本机 53 端口占用

DNS 服务需要监听 53 端口(UDP),该端口经常被系统服务占用。以下提供 Windows 和 Linux 的解决方法。

Windows

方法一:停止 DNS Client 服务(推荐)

Windows 的 DNS Client 服务(dnscache)默认占用 53 端口。

通过服务管理器(GUI)

  1. Win+R,输入 services.msc,回车
  2. 找到 DNS Client 服务
  3. 右键 → 停止
  4. 右键 → 属性 → 启动类型改为 禁用
  5. 点击确定

通过命令行(管理员 PowerShell)

# 停止 DNS Client 服务
Stop-Service -Name Dnscache -Force

# 禁用开机自启
Set-Service -Name Dnscache -StartupType Disabled

# 验证 53 端口已释放
netstat -ano | findstr ":53 "
方法二:停止 Internet Connection Sharing (ICS)

ICS 服务也可能占用 53 端口:

Stop-Service -Name SharedAccess -Force
Set-Service -Name SharedAccess -StartupType Disabled
方法三:关闭 WinDns 或 mDNSResponder

某些 Windows 版本有其他 DNS 相关服务:

# 查看占用 :53 的进程
netstat -ano | findstr ":53 "

# 假设 PID 是 1234,查看进程名
tasklist | findstr "1234"

# 强制结束该进程(将 1234 替换为实际 PID)
taskkill /F /PID 1234
方法四:使用替代端口(如果无法停用 53 端口)

如果必须保留系统 DNS 服务,可将 GoDNS 部署在另一台机器上,或使用其他端口:

# config.yaml
server:
  dns:
    port: 5353  # 使用非标准端口

然后配置客户端使用 192.168.31.154:5353

Linux

方法一:停止 systemd-resolved(Ubuntu/Debian)
# 查看 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.conf
方法二:停止 dnsmasq
sudo systemctl stop dnsmasq
sudo systemctl disable dnsmasq
方法三:停止 named (BIND)
sudo systemctl stop named
sudo systemctl disable named
方法四:关闭 NetworkManager 的 DNS
# 编辑 NetworkManager 配置
sudo nano /etc/NetworkManager/NetworkManager.conf

[main] 段添加:

dns=none
sudo systemctl restart NetworkManager
方法五:使用 setcap 授权非 root 用户绑定 53 端口

如果无法释放 53 端口,也可以让其他程序使用高端口:

# 允许 GoDNS 绑定 53 端口(无需 root)
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/godns

4.3 安装为系统服务

Windows Service

# 安装服务(管理员 PowerShell/CMD)
godns-windows-amd64.exe install

# 启动服务
sc start GoDNS

# 查看状态
sc query GoDNS

# 停止服务
sc stop GoDNS

# 卸载服务
godns-windows-amd64.exe uninstall

Linux systemd

# 安装服务(需要 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 uninstall

5. 配置说明

5.1 配置文件结构

GoDNS 使用 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 中转服务"

5.2 环境变量覆盖

环境变量 对应配置
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

环境变量优先级高于配置文件。

5.3 配置热加载

GoDNS 自动监听 config.yaml 文件变更,以下配置项支持运行时热加载(无需重启):

配置项 热加载
upstream.*
cache.*
security.*
logging.level
server.dns.* ❌ 需重启
server.web.* ❌ 需重启

6. 使用方法

6.1 命令行使用

# 前台启动(使用默认配置文件 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 修改                       ║
║                                                      ║
╚══════════════════════════════════════════════════════╝

6.2 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
# 重启服务,将生成新密码

6.3 域名规则配置

通过 Web 界面添加

http://127.0.0.1:8530/rules/add 添加规则:

字段 说明 示例
域名模式 精确域名或通配符 www.example.com*.test.com
记录类型 DNS 记录类型 AAAAACNAME
解析值 目标 IP 或域名 192.168.1.100
TTL 缓存时间(秒) 600
优先级 匹配优先级(越小越优先) 0

通配符语法

模式 说明 匹配示例
*.example.com 匹配一级子域名 www.example.comapi.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 胜出)。

重复检测

添加规则时系统自动检测 域名模式 + 记录类型 + 解析值 三者组合是否已存在,防止重复添加。

6.4 导入 host2ip.txt 文件

在程序所在目录创建 host2ip.txt,每行一条规则,格式为 域名 空格 IP

# host2ip.txt 示例
www.baidu.com 192.168.31.1
*.test.com 10.0.0.50
(.*).dev.local 172.16.0.1

启动时自动导入(已存在的规则会被跳过,不会重复)。


7. DNS 记录类型支持

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 行为一致。

验证 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

8. 安全体系

8.1 ACL 访问控制

限制哪些客户端可以使用 DNS 服务:

security:
  acl:
    enabled: true
    mode: "whitelist"       # 白名单模式
    clients:
      - "192.168.1.0/24"   # 允许整个子网
      - "10.0.0.50"        # 允许单个 IP
  • whitelist:仅列表中的 IP 可查询
  • blacklist:列表中的 IP 被拒绝

8.2 速率限制

防止 DNS 放大攻击和滥用:

security:
  rate_limit:
    enabled: true
    default_rate: 100      # 每秒 100 次请求
    default_burst: 200     # 突发 200 次
    per_client: true       # 按客户端 IP 独立限流

8.3 上游熔断器

上游 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

8.4 Web 认证

  • 密码使用 bcrypt 哈希(cost=12),不可逆
  • Session Token 为 64 字符随机 hex,HttpOnly + SameSite Cookie
  • 密码重置 Token 仅本机有效,10 分钟过期
  • 登录失败 5 次后锁定 15 分钟(待实现)

9. 监控与运维

9.1 Prometheus 指标

访问 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 堆内存分配量

9.2 健康检查

curl http://0.0.0.0:9090/health
# {"status":"ok","time":"2026-06-20T10:00:00Z"}

9.3 状态 API

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
  }
}

9.4 日志文件

日志文件 内容 格式
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

9.5 日志轮转

配置文件控制轮转策略:

logging:
  max_size: 100       # 单文件超过 100MB 时轮转
  max_backups: 30     # 保留最近 30 个文件
  max_age: 30         # 保留 30 天
  compress: true      # 压缩旧文件

10. 配置热加载

GoDNS 使用 fsnotify 监听配置文件变更。修改 config.yaml保存即生效(部分配置项无需重启)。

支持热加载的配置项:

  • upstream.servers — 重新初始化上游连接池
  • upstream.strategy — 切换选择策略
  • security.acl.* — 原子替换 ACL 规则
  • security.rate_limit.* — 更新限流器参数
  • cache.* — 调整缓存策略
  • logging.level — 运行时切换日志级别

监听端口变更(server.dns.portserver.web.port)需要重启服务。


11. 故障排查

11.1 DNS 查询超时

症状dig @127.0.0.1 example.com 超时

排查步骤

  1. 确认服务已启动:

    netstat -ano | findstr ":53 "    # Windows
    sudo ss -tulnp | grep :53       # Linux
  2. 检查防火墙:

    • Windows:允许 godns.exe 通过防火墙
    • Linux:sudo ufw allow 53/udp
  3. 检查上游 DNS 状态(查看启动仪表盘或 /metrics

  4. 查看日志 logs/server.log

11.2 Web 管理页面空白

症状:访问 http://127.0.0.1:8530 显示空白

排查步骤

  1. 确认 Web 服务已启用:config.yamlserver.web.enabled: true
  2. 检查端口冲突:netstat -ano | findstr ":8530"
  3. 删除浏览器缓存后重试 /login

11.3 规则不生效

症状:配置了规则但查询不返回自定义 IP

排查步骤

  1. Web 管理后台确认规则状态是"启用"
  2. 检查优先级设置(更精确的规则应设更低优先级)
  3. 查看 DNS 查询日志 logs/query.log,确认 来源 列是否为 rule
  4. 使用 dig 替代 nslookup 测试(nslookup 会同时发送 AAAA 查询混淆判断)

11.4 nslookup 显示 UnKnown

症状nslookup 显示 服务器: UnKnown

原因:nslookup 发送 PTR 查询获取服务器主机名,未配置 server.identity.hostname

解决:在 config.yaml 中配置:

server:
  identity:
    hostname: "godns.local"   # 自定义服务器名称

11.5 53 端口被占用

参考 4.2 解除本机 53 端口占用

11.6 SQLite 数据库锁定

症状:日志出现 database is locked

解决

  1. 增加 busy_timeout 值:database.busy_timeout: 10000
  2. 确保只有一个 GoDNS 实例在运行
  3. 删除 godns.db 重新启动(会丢失 Web 管理的规则,host2ip.txt 的规则会自动重新导入)

12. 附录

12.1 依赖清单

版本 用途
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 配置解析

12.2 编译参数说明

# 完整编译命令
CGO_ENABLED=0 \              # 禁用 CGO,纯 Go 编译
GOOS=windows \                # 目标操作系统
GOARCH=amd64 \                # 目标架构
go build \
  -ldflags "-s -w" \          # -s 去除符号表,-w 去除 DWARF 调试信息
  -o godns-windows-amd64.exe  # 输出文件名
  .

12.3 常用命令速查

# 启动服务
godns serve

# 指定 IP 启动
godns serve -ip 192.168.31.154

# 安装系统服务
godns install

# 卸载系统服务
godns uninstall

# 查看版本
godns version

# 重置 Web 密码
godns resetpwd

# 查看帮助
godns help

12.4 验证安装成功的标准流程

# 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

12.5 快速配置模板

以下是最小化可运行配置(复制保存为 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

About

轻量级 DNS 中转服务 - 支持自定义域名解析、上游转发、Web管理、13种DNS记录类型 | GoDNS v2.0 by 刘大硕

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages