# 🚀 Go-DoT: 高性能 DNS-over-TLS 缓存代理

[![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)** 缓存代理服务器，专注于**隐私保护、极致性能与高可用性**。

---

## ✨ 特性概览

| 功能 | 描述 |
|------|------|
| 🔒 加密传输 | 支持 RFC 7858，默认强制 TLS 1.3 |
| ⚡ 高效匹配 | 基于 Trie（前缀树）实现百万级黑名单匹配，复杂度 O(L) |
| 🧠 请求合并 | 使用 Singleflight 防止缓存击穿 |
| 🚀 并发查询 | 并行请求上游 DNS，返回最快响应 |
| 📦 智能缓存 | 支持正向缓存 + NXDOMAIN 负缓存（LRU） |
| 🧹 优雅退出 | 支持 SIGTERM 信号 |
| 🧩 隐私保护 | 默认移除 ECS（EDNS Client Subnet） |

---

## 🏗️ 快速开始

### 1. 编译构建

需要 Go 1.22 或更高版本：

```bash
git clone https://git.aixiao.me/aixiao/dot.git
cd dot
go mod tidy
go build -ldflags="-s -w -X 'main.BuildDate=$(date)'" -o dot
```

### 2. 生成 TLS 证书（测试用）

```bash
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=dot.local"
```

### 3. 启动服务

```bash
./dot \
    -cert aixiao.me.cer \
    -key aixiao.me.key \
    -addr :853 \
    -upstream 119.29.29.29:53,223.5.5.5:53,114.114.114.114:53 \
    -blacklist-file blacklist.txt \
    -v 
```

---

## ⚙️ 参数说明

| 参数 | 默认值 | 描述 |
|------|--------|------|
| -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 | 启用详细日志模式 |

---

## 🧱 黑名单功能

支持 hosts + 通配符格式：

```text
# 注释
ad.doubleclick.net
*.tracking.com
127.0.0.1 malicious-site.io
```

命中后直接返回指定 RCODE，并附带 EDE 说明。

---

## 🔍 缓存机制

- 缓存键: Type|DO|CD|ECS|Domain 组合键，确保不同请求策略的结果物理隔离。

- TTL 策略:
  - ✅ 正向缓存: 取记录中最小 TTL 与配置上限的较小值。
  - 🚫 负面缓存: 遵循 RFC 2308，自动计算 SOA 的最小 TTL 进行缓存。

---

## 🧩 工作流程

```mermaid
flowchart TD
  A[客户端请求] --> B{黑名单匹配}
  B -- 命中 --> C[返回拦截]
  B -- 未命中 --> D{缓存命中}
  D -- 命中 --> E[返回缓存]
  D -- 未命中 --> F[Singleflight]
  F --> G[并发查询上游]
  G --> H[写入缓存]
  H --> I[返回结果]
```

---

## 🛡️ 生产建议

- 提高文件描述符限制：ulimit -n 65535
- 使用合法 CA 证书（Android/iOS 必须）
- 关闭 -v 日志提升性能
- 配置 ≥3 个上游 DNS

---

## 👨‍💻 作者

- Author: niuyuling
- Email: aixiao@aixiao.me
- License: MIT
- Repository: https://git.aixiao.me/aixiao/dot
