# 🧩 DNS-over-TLS Cache Proxy

一个用 **Go** 编写的高性能 **DNS-over-TLS (DoT)** 缓存代理服务，  
专为隐私保护与性能优化而设计。支持多上游并发解析、智能缓存、ECS 剥离和优雅关闭。

## 🚀 特性概览

| 功能 | 描述 |
|------|------|
| 🔒 **加密传输** | 完全支持 DNS-over-TLS（RFC 7858），支持 TLS 1.2/1.3 |
| ⚡ **多上游并发解析** | “快乐眼球”机制并行查询多个上游 DNS，取最快响应 |
| 🧠 **智能缓存系统** | 支持正向与负面缓存（RFC 2308），动态 TTL 调整 |
| 🧹 **自动清理机制** | 定期清理过期缓存项（默认每 5 分钟） |
| 🧩 **隐私保护** | 默认剥离 ECS (EDNS Client Subnet)，防止地理泄露 |
| 🧱 **黑名单过滤** | 支持域名黑名单（后缀匹配、文件或命令行加载） |
| 🪶 **轻量高效** | 单一可执行文件，无外部依赖，易于容器化部署 |

## 🏗️ 快速开始

### 从源码构建

```bash
git clone https://git.aixiao.me/aixiao/dot.git
cd dot
go build -o dot main.go
```

### 使用 Docker 构建与运行

```bash
# 构建镜像
bash build.sh build

# 运行容器
bash build.sh run

# 查看日志
bash build.sh logs

# 停止与清理
bash build.sh stop
bash build.sh clean
```

> 🧩 默认镜像名为 `dot:latest`，监听 `853` 端口，可通过 `PORT` 环境变量修改。

## ⚙️ 启动示例

```bash
./dot   -cert=server.crt   -key=server.key   -addr=":853"   -upstream="8.8.8.8:53,1.1.1.1:53"   -cache-ttl=120s   -timeout=3s   -max-parallel=2   -strip-ecs=true   -tcp-fallback=true   -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` | 启用详细日志模式 |

## 🔍 缓存机制详解

**缓存键格式：**

```sh
domain|type|class|DO|CD
```

**缓存策略：**

- ✅ **正向缓存**：取最小 TTL 与配置上限的较小值  
- 🚫 **负面缓存**：遵循 RFC 2308，从 SOA.MINIMUM 计算 TTL  
- 🧭 **动态 TTL 调整**：返回时按剩余时间递减 TTL  
- 🧹 **自动清理**：每 5 分钟扫描并删除过期条目  
- 🔒 **隔离逻辑**：DO/CD 不同查询独立缓存空间  

## 🧱 黑名单功能

支持两种配置方式：

1. 命令行参数：

   ```bash
   ./dot -blacklist="*.ads.com,*.tracking.net"
   ```

2. 文件加载（每行一个域名或后缀）：

   ```sh
   # blacklist.txt
   *.ads.com
   *.malware.net
   ```

   启动命令：

   ```bash
   ./dot -blacklist-file=blacklist.txt -blacklist-rcode=NXDOMAIN
   ```

黑名单命中后不再上游查询，直接返回指定 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]
```

## 🧰 开发与维护

- 语言：**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
  ```

## 🧪 测试方法

使用 `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)
