一个功能强大、高性能的自定义 DNS 服务器,支持自定义域名解析、智能缓存、配置热重载和多后端负载均衡。
*.example.com、api.*.domain.com 等复杂模式darkit/zcli 的强大 CLI# 克隆项目
git clone https://github.com/yourusername/fkdns.git
cd fkdns
# 下载依赖
go mod download
# 运行(使用默认配置)
go run .
# 构建
make build
# 运行
./bin/fkdns
# 使用自定义 hosts 文件
./bin/fkdns -hosts /path/to/hosts
# 配置上游 DNS 服务器
./bin/fkdns -upstream 8.8.8.8:53
# 设置缓存 TTL(秒)
./bin/fkdns -cache-ttl 60
# 构建 Linux amd64
make build-linux-amd64
# 构建 macOS ARM64 (Apple Silicon)
make build-darwin-arm64
# 构建所有平台
make build-all
# 开发环境
make docker-dev
# 生产环境
make docker-prod
创建 /etc/systemd/system/fkdns.service:
[Unit]
Description=FKDNS Custom DNS Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/fkdns
ExecStart=/opt/fkdns/fkdns -hosts /etc/fkdns/hosts
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable fkdns
sudo systemctl start fkdns
sudo systemctl status fkdns
FKDNS 使用标准的 hosts 文件格式,支持多种高级特性:
# 格式:IP [端口:]域名 [域名2] [域名3]... 192.168.1.100 example.com 192.168.1.101 api.example.com
# 格式:IP:端口 域名 192.168.1.102:8080 app.example.com 192.168.1.103:8443 api.example.com
# 一个域名对应多个 IP(负载均衡) 192.168.1.10 api.example.com 192.168.1.11 api.example.com 192.168.1.12 api.example.com
# 单级通配符 192.168.1.20 *.example.com # 多级通配符 192.168.1.21 *.api.example.com 192.168.1.22 api.*.example.com
# 格式:IP:端口:权重 域名 192.168.1.30:8080:10 weighted.example.com 192.168.1.31:8080:5 weighted.example.com
# GitHub 相关域名
140.82.121.3 www.github.com
140.82.121.4 github.com
140.82.121.5 api.github.com
185.199.108.133 raw.githubusercontent.com
# 本地开发环境
127.0.0.1:3000 dev.local.com
127.0.0.1:3001 api.dev.local.com
127.0.0.1:5432 db.dev.local.com
# 生产环境多后端
192.168.1.10:8080 api.production.com
192.168.1.11:8080 api.production.com
192.168.1.12:8080 api.production.com
# 通配符域名
192.168.1.20 *.services.local
192.168.1.21 *.api.services.local
# IPv6 支持
2001:db8::1 ipv6.example.com
2001:db8::2 ipv6.example.com
| 参数 | 说明 | 默认值 |
|---|---|---|
-hosts | Hosts 配置文件路径 | 空(使用上游 DNS) |
-upstream | 上游 DNS 服务器 | 223.6.6.6:53 |
-cache-ttl | 缓存 TTL(秒) | 30 |
-help | 显示帮助信息 | - |
-version | 显示版本信息 | - |
FKDNS 实现了智能缓存机制:
优先级顺序:
cache-ttl 参数缓存清理:
域名:查询类型缓存命中:
创建 dev.hosts:
# 前端服务 127.0.0.1:3000 app.local 127.0.0.1:3000 admin.local # 后端 API 127.0.0.1:8080 api.local 127.0.0.1:8080 api.admin.local # 数据库 127.0.0.1:5432 db.local 127.0.0.1:6379 redis.local
启动服务:
./bin/fkdns -hosts dev.hosts
配置系统 DNS:
# macOS
sudo networksetup -setdnsservers Wi-Fi 127.0.0.1
# Linux (NetworkManager)
nmcli con mod "有线连接 1" ipv4.dns "127.0.0.1"
nmcli con up "有线连接 1"
# Windows
netsh interface ip set dns "本地连接" static 127.0.0.1
创建 production.hosts:
# API 服务多后端 192.168.1.10:8080 api.company.com 192.168.1.11:8080 api.company.com 192.168.1.12:8080 api.company.com # Web 服务多后端 192.168.1.20:443 www.company.com 192.168.1.21:443 www.company.com 192.168.1.22:443 www.company.com # 带权重的后端(权重越高,流量越大) 192.168.1.30:8080:10 heavy-api.company.com 192.168.1.31:8080:3 heavy-api.company.com
创建 multi-env.hosts:
# 开发环境 192.168.1.100 *.dev.company.com 192.168.1.101 api.dev.company.com # 测试环境 192.168.1.200 *.staging.company.com 192.168.1.201 api.staging.company.com # 生产环境 192.168.1.300 *.prod.company.com 192.168.1.301 api.prod.company.com
使用 dig 或 nslookup 验证:
# 使用 dig
dig @127.0.0.1 api.local
# 使用 nslookup (Windows)
nslookup api.local 127.0.0.1
# 使用 drill
drill @127.0.0.1 api.local
FKDNS 支持多种负载均衡策略:
默认策略,按顺序依次分配请求。
随机选择一个后端服务器。
根据权重分配请求,权重越高获得越多请求。
# 配置示例 192.168.1.10:8080:10 server1.example.com 192.168.1.11:8080:5 server2.example.com
选择当前连接数最少的后端。
按顺序选择第一个健康的后端。
FKDNS 内置健康检查机制:
使用 fsnotify 监控配置文件变化:
日志示例:
2024/01/07 12:00:00 配置已从文件重载: /etc/fkdns/hosts
当自定义解析器无法解析域名时:
-upstream,转发到上游 DNS# 增加缓存 TTL 减少上游查询
./bin/fkdns -cache-ttl 300
在代码中配置连接池参数:
// 每个主机的最大连接数
MaxConnsPerHost: 20
// 空闲连接超时
IdleConnTimeout: 90 * time.Second
// 最大空闲连接数
MaxIdleConns: 100
# 安装开发依赖
make install-dev-deps
# 运行测试
make test
# 运行竞态检测
make test-race
# 查看测试覆盖率
make cover
# 运行基准测试
make benchmark
# 格式化代码
make fmt
# 静态检查
make lint
# 安全检查
make vet
fkdns/ ├── main.go # 主程序入口 ├── zcli.go # CLI 配置 ├── internal/ │ └── dns/ # DNS 解析模块 │ ├── resolver.go # 解析器 │ ├── config.go # 配置管理 │ ├── endpoint.go # 端点管理 │ ├── dialer.go # 连接管理 │ ├── healthchecker.go # 健康检查 │ └── watcher.go # 文件监控 ├── bin/ # 构建输出 │ └── hosts # 示例配置文件 ├── Makefile # 构建脚本 ├── go.mod # Go 模块定义 └── README.md # 项目文档
internal/dns/ 添加新功能模块# 运行所有测试
go test ./...
# 运行特定包的测试
go test ./internal/dns/...
# 运行特定测试
go test -run TestCustomResolver ./internal/dns/
# 生成覆盖率报告
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
问题:bind: permission denied
解决方案:
# 使用 sudo 运行
sudo ./bin/fkdns
# 或者使用 systemd 服务(推荐)
sudo systemctl start fkdns
问题:修改 hosts 文件后 DNS 解析没有更新
解决方案:
sudo systemctl restart fkdns
问题:DNS 查询响应时间长
解决方案:
-cache-ttl 参数问题:特定域名返回 NXDOMAIN
解决方案:
问题:配置了 *.example.com 但无法解析
解决方案:
欢迎提交 Issue 和 Pull Request!
git checkout -b feature/AmazingFeature)git commit -m 'feat: 添加某功能')git push origin feature/AmazingFeature)本项目采用 MIT 许可证 - 详见 LICENSE 文件
⚡ Powered by Go 1.25+ | 🚀 高性能 DNS 服务器