alextorq/dns-filter

GitHub: alextorq/dns-filter

一个基于 Go 的自建 DNS sinkhole 服务器,通过三层高性能过滤架构和威胁情报聚合实现广告与恶意域名拦截。

Stars: 1 | Forks: 0

``` ██████╗ ███╗ ██╗███████╗ ███████╗██╗██╗ ████████╗███████╗██████╗ ██╔══██╗████╗ ██║██╔════╝ ██╔════╝██║██║ ╚══██╔══╝██╔════╝██╔══██╗ ██║ ██║██╔██╗ ██║███████╗█████╗█████╗ ██║██║ ██║ █████╗ ██████╔╝ ██║ ██║██║╚██╗██║╚════██║╚════╝██╔══╝ ██║██║ ██║ ██╔══╝ ██╔══██╗ ██████╔╝██║ ╚████║███████║ ██║ ██║███████╗██║ ███████╗██║ ██║ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝ ``` # DNS Filter [![Tests](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/93228a3d66115530.svg)](https://github.com/alextorq/dns-filter/actions/workflows/test.yml) [![codecov](https://codecov.io/gh/alextorq/dns-filter/branch/main/graph/badge.svg)](https://codecov.io/gh/alextorq/dns-filter) [![Go Report Card](https://goreportcard.com/badge/github.com/alextorq/dns-filter)](https://goreportcard.com/report/github.com/alextorq/dns-filter) [![Go version](https://img.shields.io/github/go-mod/go-version/alextorq/dns-filter)](https://github.com/alextorq/dns-filter/blob/main/go.mod) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Last commit](https://img.shields.io/github/last-commit/alextorq/dns-filter)](https://github.com/alextorq/dns-filter/commits/main) [![GitHub stars](https://img.shields.io/github/stars/alextorq/dns-filter?style=social)](https://github.com/alextorq/dns-filter/stargazers) 这是一个简单的 DNS 服务,用于拦截广告和恶意内容。 您需要导入拦截域名库,并将其设置为网络中的 DNS 服务器。 ``` sequenceDiagram autonumber participant C as Device (Client) participant DNS as Your DNS Server (Sinkhole) participant Upstream as Upstream DoH (Cloudflare) participant Web as Legitimate Website participant Ad as Ad Server Note over C, Ad: Scenario 1: Requesting an allowed (legitimate) domain C->>DNS: DNS Query: "What is the IP of example.com?" DNS->>DNS: Check domain against Blocklist Note right of DNS: Domain NOT found (Allowed) DNS->>Upstream: Forward query for example.com Upstream-->>DNS: Response: IP address 93.184.216.34 DNS-->>C: Response: IP address 93.184.216.34 C->>Web: HTTP/HTTPS request to 93.184.216.34 Web-->>C: Return content (Page loaded) Note over C, Ad: Scenario 2: Requesting an ad or tracking domain C->>DNS: DNS Query: "What is the IP of ads.domain.com?" DNS->>DNS: Check domain against Blocklist Note right of DNS: Domain FOUND in list! (Blocked) DNS-->>C: Response: 0.0.0.0 (or NXDOMAIN) C-xAd: Connection attempt to 0.0.0.0 fails Note left of Ad: Ad or tracker fails to load ``` ## 架构 DNS 请求路径采用三层检查机制,旨在让热点路径远离数据库——大多数查询在无需触及 SQLite 的情况下即可得到应答。拦截/放行事件以异步方式发出,因此数据库写入永远不会阻塞 DNS 应答。 ``` flowchart TD Q[DNS Query] --> CK{Client in
exclusion list?} CK -->|no| BF{Bloom filter
10M elements
0.1% false-positive} BF -->|miss| DC{Response cache
LRU 1500} CK -->|yes| DC BF -->|hit| LRU{Verdict cache
LRU 1500} LRU -->|allowed| DC LRU -->|blocked| NX[NXDOMAIN] LRU -->|miss| DB[(SQLite
blocked_domain)] DB -->|found| NX DB -->|not found| DC DC -->|hit| RESP[DNS response] DC -->|miss| DOH[DoH upstream
Cloudflare] DOH --> RESP NX -. async .-> EV[(events log)] RESP -. async .-> EV ``` ## 功能特性 - 基于拦截列表的 DNS 过滤 - DNS-over-HTTPS 上游解析器,具备 singleflight 合并和 stale-while-revalidate 缓存功能 (RFC 8767) —— 在 Cloudflare/DoH 发生短暂故障期间保持应答,并在 TTL 到期时吸收惊群效应 - 基于 Web 的管理界面 (Vue.js 前端) - RESTful API (Go 后端) - 域名检查:信誉、注册时间、证书透明度、VirusTotal、urlscan.io 和 Google Safe Browsing —— 在将域名添加到拦截列表之前,会聚合成一个单一的判定结果(`/inspect` 页面,`GET /api/domain/inspect`) - 建议拦截启发式收集器(每 12 小时运行一次)—— 将可疑的已放行域名标记为待审查。高置信度候选项(得分 ≥ 60,或任何已被拦截域名的子域名)会以 `Source = AutoBlocked` 自动提升至拦截列表;其余项将进入 `suggest_blocks` 以便通过 UI 进行人工审批。有关评分规则,请参见 [ARCHITECTURE.md §11](ARCHITECTURE.md)。 - 事件指标 - 可配置的日志级别 - SQLite 数据库用于持久化存储 - Docker 容器化部署 ### 用于域名检查的可选 API 密钥 检查端点会执行一系列独立的扇出检查。其中四项始终处于开启状态(无需设置);另外三项则由第三方 API 密钥控制,并在缺少密钥时优雅降级 —— 在没有密钥的情况下,检查会返回 `status: skipped`,聚合并判定结果将由其余信号计算得出。**这三个服务**对个人使用都是**免费的**(Safe Browsing 具有非商业性使用限制)。 | 环境变量 | 服务 | 免费额度 | | ------------------------------ | -------------------------------------------------- | -------------------- | | `DNS_FILTER_VT_KEY` | [VirusTotal](https://www.virustotal.com) | 4 次请求/分钟,500 次/天 | | `DNS_FILTER_URLSCAN_KEY` | [urlscan.io](https://urlscan.io) | ~1000 次搜索/天 | | `DNS_FILTER_SAFE_BROWSING_KEY` | [Google Safe Browsing v4](https://developers.google.com/safe-browsing/v4) | 额度充足,仅限非商业用途 | 每个提供商的逐步注册流程、评分规则、故障排除和验证说明详见 **[docs/inspect-keys.md](docs/inspect-keys.md)**。 密钥存放在 `.env` 文件中(有关模板请参见 `.env.example`)。该文件已被 git 忽略,因此机密信息不会被提交到代码仓库中。 ## 入门指南 ### 前置条件 - Go 1.20+ - Node.js & npm (用于前端) - Docker (可选) ### 后端设置 1. 安装 Go 依赖项: go mod tidy 2. 运行后端服务器: go run main.go ### 前端设置 1. 进入前端目录: cd web/front 2. 安装依赖项: npm install 3. 启动前端服务器: npm run dev ### Docker 部署 1. 构建并启动所有服务: docker-compose up --build ## 监控与日志 - Prometheus 指标端点 - Loki 日志集成 - `docs/` 中的 Grafana 仪表板 ![img](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/a43731eef0115537.png) ![img](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/9daaadaffe115544.png) ![img](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/6df7edbe14115552.png) ## 许可证 MIT *生成于 2025 年 9 月 26 日*
标签:Bloom Filter, DNS over HTTPS, DNS Sinkhole, DNS服务器, DNS解析, DNS过滤, DoH, EVTX分析, Golang, Go语言, LRU缓存, Self-hosted, Sinkhole, SQLite, TCP SYN 扫描, Web UI, 三级过滤, 去广告, 图形化管理, 安全编程, 家庭网关, 布隆过滤器, 广告拦截, 开源项目, 恶意软件拦截, 日志审计, 监控指标, 程序破解, 网络安全, 网络安全, 网络过滤, 自定义请求头, 自托管, 请求拦截, 防追踪, 隐私保护, 隐私保护