20 KiB
20 KiB
YLTX-DNS 智能防污染系统架构设计文档
📋 目录
1. 项目概述
1.1 项目背景
传统DNS解析存在污染问题,特别是在访问国际服务时容易受到干扰。本项目旨在基于成熟的MosDNS引擎,开发一套智能防污染DNS系统,实现:
- 智能污染检测:自动识别DNS污染行为
- 动态策略切换:根据域名特征和IP归属智能选择解析策略
- 可视化管理:提供直观的Web界面进行配置管理
- 自动化运维:支持配置热重载和实时监控
1.2 项目目标
🎯 核心目标
- 零配置崩溃:解决MosDNS配置顺序敏感导致的崩溃问题
- 智能防污染:实现基于CN IP地址表的智能污染检测和自动切换
- 可视化管理:提供完整的Web界面进行域名规则管理
- 热重载配置:无需重启服务即可生效配置变更
📊 性能指标
- 响应时间:< 200ms(国内DNS),< 500ms(国际DNS)
- 准确率:> 95%(污染检测准确率)
- 可用性:> 99.9%(服务可用性)
- 并发数:> 1000 QPS
1.3 项目范围
✅ 包含功能
- 基于MosDNS的二次开发改造
- 智能防污染插件开发
- 配置智能加载和验证系统
- Web管理界面开发
- 域名规则管理API
- CN IP地址表集成
- MikroTik推送集成
❌ 不包含功能
- 完全自主DNS协议栈开发
- 硬件加速优化
- 多地域部署方案
- 商业化SaaS版本
2. 需求分析
2.1 用户痛点
- 配置复杂:MosDNS配置语法复杂,顺序敏感,容易出错
- 污染检测困难:传统防污染方案依赖人工判断或简单黑名单
- 管理不便:缺乏直观的配置管理界面
- 运维成本高:配置变更需要重启服务,可用性差
2.2 功能需求
核心功能需求
| 功能模块 | 优先级 | 描述 |
|---|---|---|
| 智能防污染 | P0 | 先国内DNS查询,返回国外IP则自动切换国际DNS |
| 配置智能加载 | P0 | 自动分析依赖关系,解决配置顺序问题 |
| 可视化规则管理 | P1 | Web界面管理域名路由规则 |
| CN IP地址表集成 | P1 | 自动判断IP归属,实现精准污染检测 |
| MikroTik推送 | P2 | 支持RouterOS地址列表自动更新 |
| 热重载配置 | P2 | 无需重启即可生效配置变更 |
非功能需求
| 需求类型 | 具体要求 |
|---|---|
| 性能 | 响应时间<200ms,QPS>1000 |
| 可靠性 | 服务可用性>99.9%,自动故障恢复 |
| 可扩展性 | 支持插件化扩展,支持多DNS策略 |
| 安全性 | 支持HTTPS管理接口,支持API认证 |
| 可维护性 | 模块化设计,详细日志记录 |
2.3 用户场景
场景1:日常上网防护
用户访问各种网站,系统自动:
- 国内网站 → 国内DNS加速解析
- 国际网站 → 自动检测污染并切换国际DNS
- 未知网站 → 智能判断并选择最优解析策略
场景2:管理员配置管理
管理员通过Web界面:
- 添加域名规则(支持域名文件导入)
- 配置DNS策略(国内/国际/智能防污染)
- 设置MikroTik推送参数
- 查看实时统计和日志
场景3:故障排查
系统出现异常时:
- 详细错误日志便于定位问题
- 实时监控指标帮助诊断
- 配置验证防止人为错误
- 热重载快速恢复服务
3. 系统架构设计
3.1 总体架构
┌─────────────────────────────────────────────────────────────────┐
│ 用户层 │
├─────────────────────────────────────────────────────────────────┤
│ 🌐 Web浏览器 → Vue前端 → RESTful API → 业务逻辑层 │
├─────────────────────────────────────────────────────────────────┤
│ 服务层 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web管理界面 │ │ 配置生成器 │ │ 智能验证器 │ │ 规则引擎 │ │
│ │ Vue3 + TS │ │ Go API │ │ 依赖分析 │ │ 策略路由 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 核心层 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ MosDNS引擎 │ │ 防污染插件 │ │ 缓存系统 │ │ 上游管理 │ │
│ │ DNS协议栈 │ │ SmartFallback│ │ LRU Cache │ │ 连接池 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 数据层 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 域名文件 │ │ CN IP表 │ │ 配置存储 │ │ 日志存储 │ │
│ │ .txt格式 │ │ CIDR格式 │ │ YAML文件 │ │ 文件系统 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
3.2 模块划分
前端模块 (Vue3 + TypeScript)
- RulesView.vue:域名规则管理界面
- DashboardView.vue:系统状态监控面板
- ConfigView.vue:配置管理界面
- api/:HTTP客户端和服务接口
后端模块 (Go)
- coremain/:核心业务逻辑
config.go:配置加载和智能排序config_validator.go:配置验证器config_builder.go:配置生成器api_handlers.go:Web API接口
- plugin/executable/smart_fallback/:智能防污染插件
- pkg/:通用工具包
数据存储
- 域名文件:
/data/mikrotik/*.txt - CN IP表:
/data/chn_ip.txt - 配置文件:
config.yaml+config.d/rules/*.yaml - 日志文件:
/var/log/mosdns.log
3.3 数据流设计
配置管理流程
1. 用户在Web界面添加规则
2. 前端发送POST请求到 /api/rules
3. API调用配置生成器生成YAML
4. 验证器检查配置合法性
5. 保存到 config.d/rules/ 目录
6. 用户点击重载,热重载配置
7. MosDNS重新加载配置,无需重启
DNS查询流程
1. 客户端发起DNS查询
2. MosDNS主序列接收请求
3. 根据域名匹配对应规则
4. 执行对应DNS策略
├─ 国内DNS → 直接转发到国内上游
├─ 国际DNS → 转发到国际上游
└─ 智能防污染 → 执行SmartFallback逻辑
5. 返回解析结果
6. 可选:推送IP到MikroTik
4. 技术方案详述
4.1 核心技术方案
4.1.1 配置智能加载系统
问题解决:MosDNS配置顺序敏感导致崩溃
技术方案:
// 核心算法:拓扑排序
func (c *Config) loadPlugins() error {
// 1. 构建依赖图
graph := buildDependencyGraph(c.Plugins)
// 2. 拓扑排序
sorted := topologicalSort(graph)
// 3. 按正确顺序加载
for _, plugin := range sorted {
c.loadPlugin(plugin)
}
}
依赖图构建:
// 分析 $plugin_name 引用关系
func buildDependencyGraph(plugins []PluginConfig) map[string][]string {
graph := make(map[string][]string)
for _, p := range plugins {
graph[p.Tag] = extractDependencies(p.Args)
}
return graph
}
4.1.2 智能防污染插件
核心算法:
func (s *SmartFallback) Exec(ctx context.Context, qCtx *QueryContext) error {
// 1. 先查询国内DNS
err := s.primary.Exec(ctx, qCtx)
// 2. 检查返回IP是否在CN地址表
if s.isResponseFromChina(qCtx.Response()) {
return nil // 是CN IP,直接返回
}
// 3. 非CN IP,重新查询国际DNS
return s.secondary.Exec(ctx, qCtx)
}
CN IP检测:
func (s *SmartFallback) isResponseFromChina(resp *dns.Msg) bool {
for _, ans := range resp.Answer {
if a, ok := ans.(*dns.A); ok {
ip := netip.AddrFrom4([4]byte(a.A))
// 检查是否在CN地址表
if matched, _ := s.chinaIPList.Match(ip); !matched {
return false // 国外IP
}
}
}
return true // 全部为CN IP
}
4.1.3 配置生成器
规则定义:
type DomainRule struct {
Name string // 规则名称
DomainFile string // 域名文件路径
DNSStrategy string // DNS策略:china-dns/overseas-dns/smart-fallback
EnableMikroTik bool // 是否启用MikroTik推送
MikroTikConfig MikroTikConfig // MikroTik配置
}
自动生成配置:
func (b *ConfigBuilder) AddDomainRule(rule DomainRule) error {
// 1. 创建domain_set插件
domainSet := PluginConfig{
Tag: "domains_" + rule.Name,
Type: "domain_set",
Args: map[string]interface{}{
"files": []string{rule.DomainFile},
},
}
// 2. 创建sequence插件
sequence := PluginConfig{
Tag: "rule_" + rule.Name,
Type: "sequence",
Args: map[string]interface{}{
"exec": []map[string]interface{}{
{
"matches": "qname $" + domainSet.Tag,
"exec": "$" + rule.DNSStrategy,
},
},
},
}
// 3. 添加到主序列
b.addToMainSequence(sequence.Tag)
return nil
}
4.2 前端技术方案
4.2.1 界面设计原则
- 用户友好:向导式配置,减少技术门槛
- 实时反馈:即时验证和错误提示
- 状态可视:实时显示系统运行状态
- 响应式设计:支持桌面和移动端访问
4.2.2 核心界面组件
规则管理表单:
<template>
<!-- 基础信息卡片 -->
<el-card class="form-section">
<template #header>基础信息</template>
<el-form-item label="规则名称" prop="name">
<el-input v-model="form.name" placeholder="请输入规则名称" />
</el-form-item>
</el-card>
<!-- DNS策略卡片 -->
<el-card class="form-section">
<template #header>DNS解析策略</template>
<el-radio-group v-model="form.dnsStrategy">
<el-radio value="china-dns">🇨🇳 国内DNS</el-radio>
<el-radio value="overseas-dns">🌐 国外DNS</el-radio>
<el-radio value="smart-fallback">🛡️ 智能防污染</el-radio>
</el-radio-group>
</el-card>
<!-- MikroTik配置卡片 -->
<el-card class="form-section">
<template #header>
RouterOS推送配置
<el-switch v-model="form.enableMikrotik" />
</template>
<div v-if="form.enableMikrotik">
<!-- MikroTik参数表单 -->
</div>
</el-card>
</template>
4.3 数据存储方案
4.3.1 域名文件格式
# /data/mikrotik/openai.txt
openai.com
api.openai.com
chat.openai.com
*.openai.com
4.3.2 CN IP地址表格式
# /data/chn_ip.txt (CIDR格式)
1.0.1.0/24
1.0.2.0/23
1.1.0.0/24
# ... 更多地址段
4.3.3 配置文件结构
config.yaml # 主配置文件
config.d/
└── rules/
├── openai.yaml # OpenAI规则
├── netflix.yaml # Netflix规则
└── game-cn.yaml # 国内游戏规则
5. 开发计划
5.1 总体时间线
第1-7天:核心功能开发
第8-14天:管理层开发
第15-21天:前端开发与集成
第22-28天:测试与优化
5.2 详细开发计划
第一阶段:核心功能改造(1周)
| 任务 | 负责人 | 时间 | 交付物 |
|---|---|---|---|
| 配置拓扑排序实现 | 后端开发 | 2天 | coremain/config.go |
| 智能防污染插件开发 | 后端开发 | 3天 | plugin/executable/smart_fallback/ |
| 配置验证器开发 | 后端开发 | 2天 | coremain/config_validator.go |
里程碑:核心DNS功能正常工作,配置顺序不敏感
第二阶段:管理层开发(1周)
| 任务 | 负责人 | 时间 | 交付物 |
|---|---|---|---|
| 配置生成器开发 | 后端开发 | 3天 | coremain/config_builder.go |
| 规则管理API开发 | 后端开发 | 2天 | API接口文档 |
| 基础Web界面集成 | 前端开发 | 2天 | 基本CRUD界面 |
里程碑:可通过Web界面管理域名规则
第三阶段:前端开发与集成(1周)
| 任务 | 负责人 | 时间 | 交付物 |
|---|---|---|---|
| Vue界面优化 | 前端开发 | 3天 | 完整管理界面 |
| 实时状态显示 | 前端开发 | 2天 | 监控面板 |
| 用户体验完善 | 前端开发 | 2天 | 交互优化 |
里程碑:完整的管理界面,支持所有功能
第四阶段:测试与优化(1周)
| 任务 | 负责人 | 时间 | 交付物 |
|---|---|---|---|
| 功能测试 | 测试工程师 | 2天 | 测试报告 |
| 性能测试 | 测试工程师 | 2天 | 性能报告 |
| 用户体验测试 | 产品经理 | 1天 | UX反馈 |
| 部署测试 | 运维工程师 | 2天 | 部署指南 |
里程碑:系统稳定可用,性能达标
5.3 人力资源配置
| 角色 | 人数 | 职责 |
|---|---|---|
| 后端开发工程师 | 1 | Go核心功能开发 |
| 前端开发工程师 | 1 | Vue界面开发 |
| 测试工程师 | 1 | 功能和性能测试 |
| 产品经理 | 1 | 需求分析和用户体验 |
| 运维工程师 | 1 | 部署和运维支持 |
6. 风险评估与应对
6.1 技术风险
高风险
-
配置兼容性:二次开发可能破坏现有配置
- 应对:保留原有API,向后兼容,提供迁移指南
-
性能回归:新功能可能影响DNS解析性能
- 应对:性能基准测试,建立性能监控体系
中风险
-
CN IP表准确性:IP地址表可能过期或不准确
- 应对:提供自动更新机制,多数据源验证
-
MikroTik集成稳定性:RouterOS API可能不稳定
- 应对:添加重试机制,异步处理,避免阻塞DNS响应
低风险
- 前端兼容性:不同浏览器可能表现不一致
- 应对:使用主流UI框架,确保跨浏览器兼容
6.2 项目风险
高风险
-
时间延误:核心功能开发可能超出预期
- 应对:采用敏捷开发,定期review,及时调整计划
-
需求变更:用户需求可能在开发过程中变化
- 应对:建立变更控制流程,优先级管理
中风险
-
人员变动:核心开发人员可能变动
- 应对:知识共享,建立文档体系,交叉培训
-
技术选型错误:技术方案可能不符合实际需求
- 应对:快速原型验证,建立技术评审机制
6.3 应对策略
风险监控
- 建立风险登记册,定期评估风险状态
- 设置风险阈值,超过阈值立即采取行动
- 定期向项目组汇报风险状态
应急预案
- 核心功能失败:回退到原版MosDNS
- 性能问题:优化算法或降低功能复杂度
- 时间延误:压缩测试时间或减少非核心功能
7. 质量保障
7.1 测试策略
单元测试
- 每个核心函数和模块都需要单元测试
- 测试覆盖率 > 80%
- 边界条件和异常情况必须覆盖
集成测试
- 测试完整的功能流程
- 测试配置生成和加载过程
- 测试防污染逻辑的准确性
性能测试
- 基准性能测试(响应时间、吞吐量)
- 负载测试(高并发场景)
- 稳定性测试(长时间运行)
用户验收测试
- 实际使用场景测试
- 用户体验评估
- 功能完整性验证
7.2 代码质量
编码规范
- 遵循Go官方编码规范
- 使用 golint、gofmt 等工具检查
- 统一的错误处理模式
文档要求
- 每个函数和模块必须有注释
- 复杂算法需要详细说明
- 配置文件格式需要文档说明
版本控制
- 使用Git进行版本管理
- 建立分支管理策略(master/develop/feature)
- 代码审查流程(PR审查)
7.3 质量指标
| 指标类型 | 具体指标 | 目标值 |
|---|---|---|
| 功能性 | 功能覆盖率 | 100% |
| 性能 | 平均响应时间 | < 200ms |
| 可靠性 | 服务可用性 | > 99.9% |
| 可维护性 | 技术债务比 | < 5% |
| 安全性 | 安全漏洞数 | 0 |
8. 部署与运维
8.1 部署方案
开发环境
- 本地开发:Go 1.19+,Node.js 16+
- 代码管理:Git + GitHub
- CI/CD:GitHub Actions
测试环境
- Docker容器部署
- 自动化测试流水线
- 性能监控集成
生产环境
- 二进制文件部署(推荐)
- Docker容器部署(备选)
- Systemd服务管理
8.2 运维方案
监控体系
- 应用指标监控(响应时间、错误率、QPS)
- 系统资源监控(CPU、内存、磁盘、网络)
- 日志聚合和分析
运维工具
- 配置管理:Ansible或脚本自动化
- 日志管理:ELK Stack或Loki
- 监控告警:Prometheus + Grafana
备份策略
- 配置文件自动备份
- 日志文件定期归档
- 域名文件和IP表备份
8.3 升级策略
小版本升级
- 配置热重载,无需停机
- 新功能逐步上线,灰度发布
大版本升级
- 蓝绿部署或滚动升级
- 升级前数据备份和兼容性检查
- 升级后全面验证和监控
📞 联系方式
- 项目负责人:yltx
- 技术支持:相关技术群组
- 文档维护:GitHub Wiki
本文档最后更新时间:2025年10月15日