一个用 Go 编写的简易高性能 DNS 代理服务器,支持基于域名列表的 DNS 分流、缓存、本地 hosts,并支持多种 DNS 协议(UDP、TCP、TLS)和 SOCKS5 代理转发。
- 🚀 智能 DNS 分流:基于配置的域名列表智能选择不同的 DNS 服务器
- 📦 多协议支持:支持传统 UDP/TCP 协议和现代 TLS 加密协议(DNS over TLS)
- 🔧 灵活的服务器格式:支持多种 DNS 服务器配置格式,自动端口补全
- 💾 高效缓存机制:LRU 缓存机制显著提升查询性能
- 🌐 代理支持:支持 SOCKS5 代理转发,可为不同 DNS 服务器组配置独立代理
- 📋 本地 hosts 支持:支持本地 hosts 文件解析
- 🔗 IPv4/IPv6 支持:可配置的 IPv4 和 IPv6 协议支持
- 📊 详细日志记录:完整的查询日志和性能统计
- 🔄 HTTPS 域名列表:支持从 URL 自动下载 GFWList 等域名列表
- ❤️ 健康检查:内置 HTTP 健康检查和统计端点
- ⚡ 优雅关闭:支持 SIGINT/SIGTERM 信号,平滑终止连接
- 当查询域名匹配
filtered_server_list文件中的记录时,使用filtered_servers进行解析 - 其他域名使用
primary_servers进行解析 - 支持为不同服务器组配置独立的 SOCKS5 代理
下载仓库 Releases 中适合的架构二进制文件,运行方法如下:
easydns -c config.yamlconfig.yaml 根据需要自行修改,示例文件位于本仓库的 .config.yaml。
配置文件使用 YAML 格式,默认为 config.yaml。配置项按功能模块划分,例如:
server:
port: 53 # DNS服务监听端口
udp_size: 1492 # UDP包最大大小
ipv4: true # 启用IPv4支持
ipv6: true # 启用IPv6支持
dns:
primary_servers: # 主DNS服务器列表(用于一般域名查询)
- "114.114.114.114" # 自动补全为 114.114.114.114:53
- "119.29.29.29:53" # 标准UDP格式
- "tcp://1.1.1.1" # TCP协议,自动补全为 tcp://1.1.1.1:53
filtered_servers: # 过滤DNS服务器列表(用于特定域名查询)
- "tls://8.8.8.8" # DNS over TLS,自动补全为 tls://8.8.8.8:853
- "tls://1.1.1.1:853" # DNS over TLS,指定端口
primary_proxy: "socks5://proxy1.example.com:1080" # 主DNS SOCKS5代理(可选)
filter_proxy: "socks5://proxy2.example.com:1081" # 过滤DNS SOCKS5代理(可选)
max_concurrent_queries: 50 # 最大并发上游查询数(默认50)
cache:
limit: 4096 # DNS缓存条目数
paths:
# 方式1: 单个本地文件
filtered_server_list: "/path/to/filtered_servers.txt"
# 方式2: 多个数据源,支持本地路径或HTTPS URL(推荐)
# 系统会自动下载HTTPS内容、解析域名格式、合并去重
filtered_server_lists:
- "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"
- "/path/to/local/domains.txt"
hosts: "/etc/hosts" # 系统hosts文件路径服务提供 HTTP 健康检查端点:
# 健康检查端点(端口 = DNS端口 + 10000)
curl http://localhost:15353/health
# 返回: OK
# 统计信息端点
curl http://localhost:15353/stats
# 返回: {"primary_servers":2,"filtered_servers":2,"cache_primary_size":10,"cache_minor_size":5}对于被屏蔽的 dns 服务器,可以为其配置 SOCKS5 代理,例如:
dns:
primary_servers:
- "114.114.114.114"
- "119.29.29.29"
filtered_servers:
- "tls://8.8.8.8"
- "tls://1.1.1.1"
# 为主DNS服务器配置代理(可选)
primary_proxy: "socks5://proxy1.example.com:1080"
# 为过滤DNS服务器配置代理(可选)
filter_proxy: "socks5://proxy2.example.com:1081"域名列表(由 paths.filtered_server_list 或 paths.filtered_server_lists 指定)用于控制 DNS 分流,每行一个域名:
github.com
google.com
youtube.com
| 格式 | 示例 | 说明 |
|---|---|---|
| 纯文本 | github.com |
每行一个域名 |
| Base64 编码 | Z2l0aHViLmNvbQo= |
GFWList 等使用 Base64 编码,系统自动解码 |
| AdGuard 格式 | ||github.com^ |
系统自动提取域名部分 |
| 通配符 | *.google.com |
自动去除 * 前缀 |
filtered_server_lists 支持直接填写 HTTPS URL,系统会自动:
- 下载内容
- 检测并解码 Base64
- 解析各种域名格式
- 合并去重
匹配规则:
- 精确匹配:
github.com只匹配github.com - 子域名不自动匹配:需要单独添加
api.github.com
dns:
primary_servers: # 国内DNS(用于一般域名)
- "114.114.114.114"
- "119.29.29.29"
filtered_servers: # 国外DNS(用于国外域名)
- "tls://8.8.8.8" # 使用TLS加密
- "tls://1.1.1.1"dns:
primary_servers:
- "tls://1.1.1.1" # Cloudflare DNS over TLS
- "tls://8.8.8.8" # Google DNS over TLS
filtered_servers:
- "tls://9.9.9.9" # Quad9 DNS over TLSdns:
primary_servers:
- "114.114.114.114" # 国内UDP,速度快
- "tcp://119.29.29.29" # 国内TCP,稳定性好
filtered_servers:
- "tls://8.8.8.8" # 国外TLS,隐私保护
- "udp://1.1.1.1:53" # 国外UDP,备用paths:
filtered_server_lists:
- "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt"├── cmd/easydns/ # 主程序入口
├── internal/ # 内部包
│ ├── cache/ # DNS缓存实现 (LRU)
│ ├── config/ # 配置管理、域名列表、hosts解析
│ └── dns/ # DNS请求处理、转发、协议实现
├── pkg/ # 公共包
│ └── util/ # 工具函数 (IP提取、域名提取)
└── scripts/ # 辅助脚本
┌─────────────────────────────────────────────────────────────────────────┐
│ DNS 请求流程 │
└─────────────────────────────────────────────────────────────────────────┘
Client DNS Query (UDP/TCP)
│
▼
┌─────────────────┐
│ IPv4/IPv6 过滤 │ ──► 如果禁用,返回 NotImplemented
└────────┬────────┘
│
▼
┌─────────────────┐
│ 检查 Hosts 文件 │ ──► 命中则返回本地解析结果
└────────┬────────┘
│
▼
┌─────────────────┐
│ 检查缓存 │ ──► 命中且未过期则返回缓存结果
└────────┬────────┘
│
▼
┌─────────────────────────────────────────┐
│ 域名匹配 & 上游选择 │
│ • filtered_server_list 命中 ──► filtered_servers + CacheMinorDNS │
│ • 其他 ────────────────────► primary_servers + CachePrimaryDNS │
└────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 并发查询所有上游服务器 │
│ • UDP/TCP 直连 │
│ • DNS-over-TLS (DoT) │
│ • SOCKS5 代理转发 │
│ • 3秒超时控制 │
└────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 返回最快有效响应 │
│ • 优先返回有结果的响应 │
│ • IPv4 响应优先(减少延迟) │
│ • 缓存结果并返回给客户端 │
└─────────────────────────────────────────┘
# 编译
go build -o easydns ./cmd/easydns
# 运行
go run ./cmd/easydns -c config.yaml
# 格式化代码
gofmt -w .
# 代码检查
go vet ./...# 运行所有测试
go test ./...
# 运行测试(详细输出)
go test -v ./...
# 运行单个包的测试
go test -v ./internal/dns
# 运行单个测试函数
go test -v -run TestFunctionName ./internal/dns
# 测试覆盖率
go test -cover ./...# 使用dig测试(Linux/macOS)
dig @127.0.0.1 +tcp +tls-ca=/etc/ssl/certs/ca-certificates.crt google.com
# 使用nslookup测试(Windows)
nslookup google.com 127.0.0.1- 检查代理服务器是否正常运行
- 验证代理地址格式:
socks5://host:port - 确认防火墙没有阻止连接
- 查看日志获取详细错误信息
- 证书验证失败: 检查系统时间是否正确
- SNI 不匹配: 确保 DNS 服务器支持 TLS
- 网络问题: 检查 853 端口是否被阻止
- 代理问题: TLS through proxy 需要代理支持 CONNECT 方法
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
- 提交前运行
gofmt -w .格式化代码 - 提交前运行
go vet ./...检查代码问题 - 新功能需附带单元测试
- 保持代码简洁,避免不必要的复杂度
此项目采用 MIT 许可证。详见 LICENSE 文件。