feat(blacklist): 实现基于Trie树的高性能黑名单匹配系统

重构黑名单匹配算法,采用Trie前缀树数据结构替换原有的后缀匹配,
将百万级域名匹配复杂度从O(n)降至O(L),显著提升性能。

同时优化黑名单文件加载机制,支持hosts格式和通配符匹配,
并实现文件修改自动重载功能,提升系统的灵活性和实用性。

refactor: 重构README文档结构和内容展示

更新项目介绍文档,优化整体布局结构,添加项目徽章标识,
精简功能特性描述,改进快速开始指南,提供更清晰的使用说明。

chore(deps): 更新项目依赖库至最新版本

升级github.com/miekg/dns至v1.1.72版本,
更新golang.org/x/net至v0.52.0版本,
升级golang.org/x/sync至v0.20.0版本,
以及其他相关依赖库的版本更新。
This commit is contained in:
2026-03-20 14:39:29 +08:00
parent 77bea1e99e
commit f5bf77927d
6 changed files with 458 additions and 963 deletions

191
README.md
View File

@@ -1,50 +1,47 @@
# DNS-over-TLS Cache Proxy
# 🚀 Go-DoT: 高性能 DNS-over-TLS 缓存代理
一个用 **Go** 编写的高性能 **DNS-over-TLS (DoT)** 缓存代理服务,
专为隐私保护与性能优化而设计。支持多上游并发解析、智能缓存、ECS 剥离和优雅关闭。
[![Go Version](https://img.shields.io/badge/Go-1.22+-00ADD8?style=flat&logo=go)](https://golang.org)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Security](https://img.shields.io/badge/TLS-1.3_Only-green.svg)](https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3)
## 🚀 特性概览
**Go-DoT** 是一个用 Go 语言编写的生产级 **DNS-over-TLS (DoT)** 缓存代理服务器,专注于**隐私保护、极致性能与高可用性**。
---
## ✨ 特性概览
| 功能 | 描述 |
|------|------|
| 🔒 **加密传输** | 完全支持 DNS-over-TLSRFC 7858),支持 TLS 1.2/1.3 |
| ⚡ **多上游并发解析** | “快乐眼球”机制并行查询多个上游 DNS取最快响应 |
| 🧠 **智能缓存系统** | 支持正向与负面缓存RFC 2308动态 TTL 调整 |
| 🧹 **自动清理机制** | 定期清理过期缓存项(默认每 5 分钟) |
| 🧩 **隐私保护** | 默认剥离 ECS (EDNS Client Subnet),防止地理泄露 |
| 🧱 **黑名单过滤** | 支持域名黑名单(后缀匹配、文件或命令行加载) |
| 🪶 **轻量高效** | 单一可执行文件,无外部依赖,易于容器化部署 |
| 🔒 加密传输 | 支持 RFC 7858,默认强制 TLS 1.3 |
| ⚡ 高效匹配 | 基于 Trie前缀树实现百万级黑名单匹配复杂度 O(L) |
| 🧠 请求合并 | 使用 Singleflight 防止缓存击穿 |
| 🚀 并发查询 | 并行请求上游 DNS返回最快响应 |
| 📦 智能缓存 | 支持正向缓存 + NXDOMAIN 负缓存LRU |
| 🧹 优雅退出 | 支持 SIGTERM 信号 |
| 🧩 隐私保护 | 默认移除 ECSEDNS Client Subnet |
---
## 🏗️ 快速开始
### 从源码构建
### 1. 编译构建
需要 Go 1.22 或更高版本:
```bash
git clone https://git.aixiao.me/aixiao/dot.git
cd dot
bash build.sh bin
go mod tidy
go build -ldflags="-s -w -X 'main.BuildDate=$(date)'" -o dot
```
### 使用 Docker 构建与运行
### 2. 生成 TLS 证书(测试用)
```bash
# 构建镜像
bash build.sh build
# 运行容器
bash build.sh run
# 查看日志
bash build.sh logs
# 停止与清理
bash build.sh stop
bash build.sh clean
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=dot.local"
```
> 🧩 默认镜像名为 `dot:latest`,监听 `853` 端口,可通过 `PORT` 环境变量修改。
## ⚙️ 启动示例
### 3. 启动服务
```bash
./dot \
@@ -52,119 +49,79 @@ bash build.sh clean
-key aixiao.me.key \
-addr :853 \
-upstream 119.29.29.29:53,223.5.5.5:53,114.114.114.114:53 \
-cache-ttl 300s \
-timeout 3s \
-max-parallel 3 \
-blacklist-file blacklist.txt
-blacklist-file blacklist.txt \
-v
```
启动日志示例:
```bash
🚀 starting DNS-over-TLS on :853
[req] A www.example.com. (id=40192 cd=false do=true from=127.0.0.1:58877)
[cache] MISS A www.example.com.
[answer] www.example.com. 300 IN A 93.184.216.34
```
---
## ⚙️ 参数说明
| 参数 | 默认值 | 描述 |
|------|---------|------|
| `--addr` | `:853` | 监听地址(支持 IPv4/IPv6 |
| `--cert` | `server.crt` | TLS 证书路径 |
| `--key` | `server.key` | TLS 私钥路径 |
| `--upstream` | `8.8.8.8:53,1.1.1.1:53` | 上游 DNS 服务器列表 |
| `--cache-ttl` | `60s` | 缓存最大 TTL正向/负面均适用) |
| `--timeout` | `3s` | 上游查询超时 |
| `--max-parallel` | `3` | 最大并发上游查询数 |
| `--strip-ecs` | `true` | 是否剥离 ECS 信息 |
| `--tcp-fallback` | `true` | UDP 截断时是否自动 TCP 回退 |
| `--blacklist` | 空 | 逗号分隔的黑名单域名或通配后缀 |
| `--blacklist-file` | 空 | 黑名单文件路径(每行一个规则) |
| `--blacklist-rcode` | `REFUSED` | 黑名单命中返回码:`REFUSED` / `NXDOMAIN` / `SERVFAIL` |
| `--cache-size` | `10000` | LRU 缓存最大条目数 |
| `--v` | `false` | 启用详细日志模式 |
|------|--------|------|
| -addr | :853 | DoT 监听地址 |
| -cert | server.crt | TLS 证书路径 |
| -key | server.key | TLS 私钥路径 |
| -upstream | 8.8.8.8:53,1.1.1.1:53 | 上游 DNS |
| -blacklist-file | 空 | 黑名单文件路径 |
| -blacklist-rcode | REFUSED | 命中黑名单返回码REFUSED / NXDOMAIN / SERVFAIL |
| -v | false | 启用详细日志模式 |
## 🔍 缓存机制详解
**缓存键格式:**
```sh
domain|type|class|DO|CD
```
**缓存策略:**
-**正向缓存**:取最小 TTL 与配置上限的较小值
- 🚫 **负面缓存**:遵循 RFC 2308从 SOA.MINIMUM 计算 TTL
- 🧭 **动态 TTL 调整**:返回时按剩余时间递减 TTL
- 🧹 **自动清理**:每 5 分钟扫描并删除过期条目
- 🔒 **隔离逻辑**DO/CD 不同查询独立缓存空间
---
## 🧱 黑名单功能
支持两种配置方式:
支持 hosts + 通配符格式:
1. 命令行参数:
```text
# 注释
ad.doubleclick.net
*.tracking.com
127.0.0.1 malicious-site.io
```
```bash
./dot -blacklist="*.ads.com,*.tracking.net"
```
命中后直接返回指定 RCODE并附带 EDE 说明。
2. 文件加载(每行一个域名或后缀):
---
```sh
# blacklist.txt
*.ads.com
*.malware.net
```
## 🔍 缓存机制
启动命令:
- 缓存键: Type|DO|CD|ECS|Domain 组合键,确保不同请求策略的结果物理隔离。
```bash
./dot -blacklist-file=blacklist.txt -blacklist-rcode=NXDOMAIN
```
- TTL 策略:
- ✅ 正向缓存: 取记录中最小 TTL 与配置上限的较小值。
- 🚫 负面缓存: 遵循 RFC 2308自动计算 SOA 的最小 TTL 进行缓存。
黑名单命中后不再上游查询,直接返回指定 RCODE。
---
## 🧩 架构与运行原理
## 🧩 工作流程
```mermaid
flowchart TD
A[Client (DoT Request)] --> B[DNS-over-TLS Server]
B --> C[Cache Lookup]
C -- HIT --> D[Return Cached Response]
C -- MISS --> E[Upstream Resolver Pool]
E -->|Fastest Response| F[DNS Response]
F --> G[Cache Write]
G --> H[Return to Client]
A[客户端请求] --> B{黑名单匹配}
B -- 命中 --> C[返回拦截]
B -- 未命中 --> D{缓存命中}
D -- 命中 --> E[返回缓存]
D -- 未命中 --> F[Singleflight]
F --> G[并发查询上游]
G --> H[写入缓存]
H --> I[返回结果]
```
## 🧰 开发与维护
---
- 语言:**Go 1.22+**
- 依赖:
- [`github.com/miekg/dns`](https://github.com/miekg/dns)
- [`github.com/hashicorp/golang-lru/v2`](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2)
- 推荐编译参数:
## 🛡️ 生产建议
```bash
go build -ldflags="-s -w" -o dot main.go
```
- 提高文件描述符限制ulimit -n 65535
- 使用合法 CA 证书Android/iOS 必须)
- 关闭 -v 日志提升性能
- 配置 ≥3 个上游 DNS
## 🧪 测试方法
---
使用 `kdig` 或 `dig` 测试解析:
## 👨‍💻 作者
```bash
kdig @127.0.0.1 +tls-ca +tls-host=dot.local www.example.com
```
## 👨‍💻 作者信息
**Author:** niuyuling
**Email:** [aixiao@aixiao.me](mailto:aixiao@aixiao.me)
**License:** MIT
**Repository:** [git.aixiao.me/aixiao/dot](https://git.aixiao.me/aixiao/dot)
- Author: niuyuling
- Email: aixiao@aixiao.me
- License: MIT
- Repository: https://git.aixiao.me/aixiao/dot