- 网络安全
【免费下载链接】Lists
Primary Block Lists
本文基于 Lists 仓库的实现总结文档 UPSTREAM_IMPLEMENTATION_SUMMARY.md,完整解析该项目"上游威胁源监控(Upstream Source Monitoring)"子系统的设计与落地:如何仅通过编辑config/lists.yml即可声明式地引入外部威胁情报源,由 scripts/monitor_upstream.py 完成拉取、归一化、比对与分支提交,再由 upstream-monitor.yml 工作流每日自动生成带分级标签的 Pull Request。读完后,你可以独立配置上游源、读懂监控脚本的缓存与比对逻辑,并按仓库给出的测试清单安全地把该自动化跑通。
整体架构与组件构成
原始总结文档(完成于 2026-07-03,状态为 "Complete and Ready to Use")将该体系划分为四大交付物:配置系统、监控脚本、GitHub 自动化工作流,以及配套文档。四者职责分工如下:
| 组件 | 文件 | 职责 |
|---|---|---|
| 配置 | config/lists.yml、config/upstream-sources-example.yml | 定义全局监控参数与每个列表的上游源清单 |
| 监控脚本 | scripts/monitor_upstream.py | 拉取上游、归一化域名、比对本地列表、创建更新分支 |
| 自动化工作流 | .github/workflows/upstream-monitor.yml | 定时触发、创建 PR、打标签、生成汇总 Issue、错误上报 |
| 配套文档 | UPSTREAM_MONITORING.md、IMPROVEMENT_PLAN.md | 完整用户指南与 Phase 7.4 实施记录 |
从源码结构看,数据流是一条清晰的单向管道:
- 工作流在每天 02:00 UTC(cron
0 2 * * *)触发,安装 requirements.txt 中的依赖(pyyaml、requests、PyGithub)后运行python scripts/monitor_upstream.py --all; - 脚本读取 config/lists.yml,找出所有配置了
upstream_sources的列表,逐个拉取并比对,把差异结果写入<列表名>.txt的更新分支; - 脚本把每个列表的 PR 元数据(标题、分支名、新域名数、PR 正文)保存为
pr_<列表名>.json; - 工作流的
github-script步骤扫描这些 JSON 文件,调用 GitHub API 创建 PR、按域名数量打标签,并生成一份汇总 Issue; - 若脚本退出码非 0,工作流自动创建带
needs-attention标签的错误 Issue,并上传完整日志 artifact。
这一设计的关键取舍是:脚本本身不直接调用 GitHub API 创建 PR,它只负责"生成分支 + 落盘 PR 描述",把 API 调用交给工作流的 Node 环境完成(见 monitor_upstream.py 中保存 PR 元数据的部分)。这样本地调试时脚本可以独立运行,CI 侧则统一拥有 token 与权限。
配置系统:全局参数与逐源参数两层设计
全局设置 settings.upstream
原始文档要求在 config/lists.yml 顶部的settings:段中加入全局监控配置,当前仓库的实际内容(config/lists.yml)即为:
settings: # Upstream monitoring configuration upstream: enabled: true check_frequency: "daily" auto_merge_threshold: 10 require_review_threshold: 100 cache_ttl: 86400各参数含义与脚本中的读取逻辑:
| 参数 | 当前值 | 含义 | 脚本中的使用位置 |
|---|---|---|---|
enabled | true | 监控功能总开关 | 配置层面的语义开关 |
check_frequency | "daily" | 全局检查频率(daily / weekly / hourly) | 与工作流 cron 配合使用 |
auto_merge_threshold | 10 | 新增域名 ≤ 该值时视为可自动合并的小变更 | generate_pr_body 中生成合并策略说明 |
require_review_threshold | 100 | 新增域名 > 该值时强制人工审查 | PR 正文分级(≤10 / 11–100 / >100 三档) |
cache_ttl | 86400(24 小时,单位秒) | 上游响应缓存有效期 | check_upstream_updates 中通过config.get("settings", {}).get("upstream", {}).get("cache_ttl", 86400)读取,缺省回退为 86400 |
逐列表的 upstream_sources 配置
每个列表可在自身定义下追加upstream_sources列表。以当前仓库 config/lists.yml 中的ads列表为例:
lists: ads: description: "Ad serving domains" category: advertising status: stable upstream_sources: - url: "https://raw.githubusercontent.com/ShadowWhisperer/BlockLists/refs/heads/master/Lists/Ads" format: domains trusted: true update_frequency: daily - url: "https://media.githubusercontent.com/media/zachlagden/Pi-hole-Optimized-Blocklists/main/lists/advertising.txt" format: hosts trusted: true update_frequency: daily脚本侧通过 UpstreamSource 数据类承载这些字段。对照 check_upstream_updates 中的解析代码,可以确认每个字段的默认值(原始文档未列全,这是源码级补充):
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | 必填 | — | 上游块列表的完整 URL |
format | 字符串 | domains | 上游格式:hosts/domains/adguard/dnsmasq |
trusted | 布尔 | False | 是否受信;未显式声明时按"不信任"处理,属保守默认 |
update_frequency | 字符串 | daily | daily/weekly/hourly |
filter_comments | 布尔 | True | 跳过以#开头的注释行 |
filter_category | 可选 | None | 面向多类别列表的过滤标记(示例配置中ads、tracking有使用) |
max_domains | 可选 | None | 单源域名上限,防止超大合并 |
config/upstream-sources-example.yml 提供了可直接复制粘贴的现成配置:覆盖abuse、crypto、fraud、malware、phishing、ransomware、scam等安全类列表,以及ads、gambling、porn、tracking等内容/隐私类列表,并逐条注明了格式与频率建议(例如 ransomware 的 RansomwareTracker 源特意标注trusted: false # Requires manual review)。文件末尾还附有字段速查表与"如何并入 lists.yml"的分步说明(CONFIGURATION OPTIONS EXPLAINED 段)。
四种上游格式如何被识别
format字段声明上游文件格式,实际解析由 src/normalize.py 完成。normalize_line 内置了四组正则(正则定义处),能同时识别0.0.0.0 domain/127.0.0.1 domain(hosts)、||domain^(adguard)、server=/domain/与address=/domain/0.0.0.0(dnsmasq)以及裸域名(domains),统一输出小写域名。这意味着即便个别源的实际格式与声明略有出入,只要落入上述模式之一即可被正确解析;对不符合任何模式的行则静默丢弃并返回None。
monitor_upstream.py 核心机制深读
原始文档将该脚本概括为"600+ 行"(当前为 645 行),下面按其内部调用链逐段展开。
智能缓存:MD5 哈希文件名 + mtime 判定 TTL
缓存是文档强调的核心特性("Smart Caching - Reduces bandwidth and respects upstream servers")。实现上:
- 缓存文件路径由 URL 的 MD5 哈希生成:
get_cache_path()返回TEMP_DIR / "upstream_cache_<md5>.txt"(get_cache_path)。TEMP_DIR来自 src/config.py,默认为系统/tmp,可用环境变量TEMP_DIR覆盖; - 缓存有效性由文件 mtime 与
cache_ttl比较判定(is_cache_valid),未过期则直接parse_file_to_set读缓存,命中时输出Using cached data for ...; - 每次成功抓取后,原文整体写入缓存文件(fetch_upstream_domains),后续比对基于缓存内容重新解析,而非复用解析结果——这保证了
filter_comments、max_domains等参数调整后无需清缓存即可生效。
命令行侧另有--no-cache参数可强制绕过缓存重新抓取(见下文 CLI 一节)。
抓取与域名上限
抓取使用requests.get(url, timeout=30, headers={"User-Agent": "BlockListProject-Upstream-Monitor/1.0"}),显式声明 User-Agent 并设置了 30 秒超时(抓取代码)。任何RequestException都会被捕获、打印错误并返回空集合,随后该源记为error="Failed to fetch upstream domains"的UpdateResult(错误分支),不会中断其他源的处理。
max_domains上限的生效细节值得注意(限流代码):当解析出的域名数超过上限时,脚本先对域名集合排序,再取前 N 个(set(sorted(domains)[:max_domains]))。排序保证多次运行截断结果一致,避免每次 PR 的"新增集合"随机漂移。
与本地列表比对:只增不删 + 排除名单
比对逻辑在 compare_with_local 中,包含两个关键设计决策:
其一,永不建议删除域名。函数签名声明返回(new_domains, removed_domains),但removed_domains恒为空集,源码注释(L198-L199、L225-L231)解释了原因:本地列表中的域名可能来自多个上游源、手工添加或社区贡献,仅凭"某上游源里没有了"就建议删除会误伤。这也解释了 PR 模板中 "Removed domains: 0" 恒成立的原因。
其二,排除名单(exclusions)在比对前介入。load_exclusions 读取config/exclusions/<列表名>.txt,把其中的域名从上游集合中扣除后再计算差集。这套机制与 config/exclusions/README.md 描述的流程闭环:被人工判定为误报、经 scripts/remove_domain.py 移除的域名会自动写入对应排除文件,从而"上游再出现也不会被自动加回来"。仓库中已存在ads.txt、malware.txt、tracking.txt等 7 个排除文件(见 config/exclusions/)。
比对结果new_domains = upstream_domains - local_domains即该源建议新增的域名集合,本地文件不存在时按空集合处理。
分支创建与多格式再生成
真正落盘更新时,create_pr_branch 依次执行:
- 清理旧分支:
git branch -r扫描所有upstream-update/<列表名>/前缀的远程分支并逐个删除,避免堆积历史分支(L406-L436); - 新建时间戳分支:命名格式
upstream-update/<列表名>/<YYYYMMDD-HHMMSS>; - 重写列表文件:合并
existing_domains | all_new_domains后排序,以 hosts 格式(0.0.0.0 <domain>)写入<列表名>.txt,并带上 "Updated by upstream monitoring" 头注释(L461-L474); - 再生成全部输出格式:调用
python3 build.py --list <列表名>(L476-L491),由 build.py 按 config/lists.yml 中formats:段定义同步产出alt-version(domains)、adguard(ags)、dnsmasq-version(dnsmasq)等各目录下的对应文件。若该步失败仅告警不中断,注释说明格式可由 CI 兜底再生成; - 提交并推送:commit message 为
chore: update <列表名> from upstream sources,附新增域名数量; - 落盘 PR 元数据:非 dry-run 且有新增时,把
{list_name, title, branch, new_domains, body}写入TEMP_DIR/pr_<列表名>.json(L621-L631),供工作流的 github-script 步骤消费。
PR 正文与三档合并策略
generate_pr_body 生成的 PR 描述包含:汇总统计(列表名、新增/移除数、检查的源数)、每个源的明细(URL、上游总数、新增数,≤20 个时全量列出、否则抽样 10 个)、一个 4 项的验证清单(类别相关性、误报、校验通过、构建成功),以及按新增总量划分的合并策略三档:
| 新增域名数 | PR 中标注 | 工作流附加标签 |
|---|---|---|
| ≤ 10 | Auto-merge eligible | size:small+auto-merge-candidate |
| 11–100 | Manual review recommended | size:medium |
| > 100 | Manual review required | size:large+needs-review |
所有 PR 固定携带automation与upstream-update两个基础标签(github-script 中的标签逻辑)。
命令行用法
脚本入口 main() 定义的完整参数集为(原始文档仅列了--list/--all/--dry-run,此处按源码补全):
# 检查单个列表(可加 --dry-run 只报告不建 PR) python scripts/monitor_upstream.py --list ads --dry-run # 检查所有配置了上游源的列表 python scripts/monitor_upstream.py --all --dry-run # 正式运行:创建分支并落盘 PR 元数据(去掉 --dry-run) python scripts/monitor_upstream.py --all # 忽略缓存强制重新抓取 python scripts/monitor_upstream.py --all --no-cache参数约束:--list(-l)与--all(-a)必须至少指定其一,否则parser.error直接报错退出(L550-L551);--all模式下脚本自动过滤出配置了upstream_sources的列表(L558-L563)。运行结束会打印全局汇总(各列表新增/移除数、总计),dry-run 模式下明确输出 "No PRs created" 提示。
GitHub Actions 工作流逐段解析
.github/workflows/upstream-monitor.yml 与原始文档描述的七步流程一一对应,且比文档多出了两个细节:
触发与输入(L3-L18):除cron: '0 2 * * *'每日定时外,workflow_dispatch提供两个手动输入——list_name(指定单个列表,留空则全量)与dry_run(布尔,默认 false)。权限声明为contents、pull-requests、issues三项写权限(L20-L23)。
执行步骤(L26-L81):
actions/checkout@v4且fetch-depth: 0(完整历史,脚本要清理旧远程分支);actions/setup-python@v5安装 Python 3.12 +pip install -r requirements.txt;actions/setup-node@v4安装 Node 24(供 github-script 使用);- 以
github-actions[bot]身份配置 git; - 运行监控脚本,shell 侧用
set +e容错、tee /tmp/monitor_output.log留存日志,并把退出码与error=true/false写入步骤输出,供后续步骤的if:条件分流。
PR 创建(L83-L190):github-script 步骤扫描/tmp/pr_*.json(即脚本写入的元数据),逐文件创建 PR(base 固定main)、按域名数追加标签、记录创建结果;随后把所有 PR 汇总成一张 Markdown 表格创建 "Upstream Updates Summary" Issue(标签automation、report),并写 Job Summary 表格。日志中list_name为空且dry_run=true时该步骤整体跳过。
错误与日志(L192-L235):脚本失败时自动创建 "Upstream Monitor Failed" Issue(标签automation、error、needs-attention),正文附带日志尾部 2000 字符与四条排查建议;Upload logs步骤以if: always()保证无论成败都上传monitor-logs-<run_id>artifact,保留 7 天。
快速上手:四步启用监控
这一节完整继承原始文档的 "How to Get Started" 流程。
Step 1 — 为列表添加上游源:编辑 config/lists.yml,在目标列表定义下(status:之后)加入upstream_sources段,可参考 config/upstream-sources-example.yml 中"copy-paste ready"的段落。原始文档给出的最小示例:
lists: ads: description: "Ad serving domains" category: advertising status: stable upstream_sources: # 新增这一段 - url: "https://adaway.org/hosts.txt" format: hosts trusted: true update_frequency: dailyStep 2 — 补齐全局设置:确认settings.upstream段存在且取值合理(当前仓库已就绪,见上文全局参数表)。
Step 3 — 手工验证:
# dry-run 单列表测试 python scripts/monitor_upstream.py --list ads --dry-run # 校验 YAML 语法 python -c "import yaml; yaml.safe_load(open('config/lists.yml'))"检查输出中各源的 Upstream / Local / New 统计是否符合预期。
Step 4 — 启用自动化:工作流文件已在仓库中,提交并推送含上游源配置的改动后,次日 02:00 UTC 自动生效;也可在 Actions 面板选择 "Upstream Source Monitor" 通过 Run workflow 手动触发(可指定list_name或开启dry_run)。
推荐的起步源与类别对齐
原始文档给出的"高价值、低风险"起步组合为:
lists: malware: upstream_sources: - url: "https://urlhaus.abuse.ch/downloads/hostfile/" format: hosts trusted: true update_frequency: daily phishing: upstream_sources: - url: "https://phishing.army/download/phishing_army_blocklist.txt" format: domains trusted: true update_frequency: daily ads: upstream_sources: - url: "https://adaway.org/hosts.txt" format: hosts trusted: true update_frequency: weekly文档同时给出当前仓库的类别对齐表,确保域名进入正确的列表:
| 类别 | 列表 | 目的 |
|---|---|---|
| Security | abuse, crypto, fraud, malware, phishing, ransomware, scam | 防护威胁 |
| Advertising | ads | 拦截广告域 |
| Content | gambling, porn, piracy, drugs, vaping | 内容类别过滤 |
| Privacy | tracking | 拦截跟踪与分析 |
| Social | facebook, twitter, tiktok, whatsapp | 社交平台屏蔽 |
| Gaming | fortnite | 游戏相关屏蔽 |
| Telemetry | adobe, smart-tv | 遥测与激活拦截 |
对照当前 config/lists.yml,实际已启用上游源的是 8 个列表(ads、crypto、fraud、gambling、malware、porn、scam、tracking),合计 12 个源,来源以 ShadowWhisperer/BlockLists、Pi-hole-Optimized-Blocklists 与 hagezi/dns-blocklists 为主。而示例配置文件中还收录了 URLhaus、AdAway、phishing.army、Spam404、frogeye 等更多备选源,原始文档标注其覆盖了 23 个受信源、10 个列表——两者差异说明示例文件是"候选池",lists.yml是"已启用子集",可按需增删。
预期效果与自定义选项
原始文档对上线效果的描述(作为预期参考,而非实测数据):首周以小型 PR 为主(每列表 5–15 个域名),约 80% 的变更落在自动合并阈值内(≤10 域名),单次全量运行 2–5 分钟;UPSTREAM_MONITORING.md 的 Statistics 段进一步给出无缓存抓取约 5–10 秒/源、缓存命中 <1 秒/源、PR 生成 <30 秒等参考值。
三个常用自定义入口:
# 1. 调整全局检查频率 settings: upstream: check_frequency: "weekly" # 由 daily 改为 weekly # 2. 收紧或放宽自动合并阈值 settings: upstream: auto_merge_threshold: 5 # 保守:≤5 才允许自动合并 # auto_merge_threshold: 20 # 激进# 3. 修改工作流触发节奏(.github/workflows/upstream-monitor.yml) on: schedule: - cron: '0 2 * * *' # 每天 02:00 UTC(现值) # - cron: '0 2 * * 1' # 改为每周一 02:00 UTC测试清单与实操守则
原始文档的上线前测试清单,结合源码行为补充了验证要点:
- 给一个测试列表添加一个上游源
- 运行
python scripts/monitor_upstream.py --list <name> --dry-run - 确认输出中的 Upstream / Local / New 三项统计正确(New = 上游集合 − 本地集合,且已扣除
config/exclusions/中域名) - 检查输出无
✗ Error fetching报错 - 验证 YAML 语法:
python -c "import yaml; yaml.safe_load(open('config/lists.yml'))" - 提交并推送改动
- 在 Actions 面板手动触发一次工作流
- 确认有差异时 PR 已创建(分支名
upstream-update/<列表>/前缀、旧分支已清理) - 检查 PR 正文的源明细、验证清单与合并策略档位,以及标签是否符合域名数
- CI 通过后合并测试 PR
DO / DON'T 守则(原文档原样继承,并附源码依据):
- ✅ 从一两个受信源起步;✅ 测试时多用
--dry-run;✅ 首周密切关注每个 PR;✅ 为大规模源设置max_domains(截断逻辑见上文);✅ 大变更人工审查;✅ 记录每个源的信任理由。 - ❌ 立即添加不受信源并开自动合并(源码默认
trusted: False,正是此精神);❌ 把所有源设为 auto-merge;❌ 忽略构建失败(build.py再生成失败会告警);❌ 跳过测试直接上生产;❌ 无谓地关闭缓存;❌ 不必要的hourly频率。
故障排查与后续规划
UPSTREAM_MONITORING.md 的故障排查章节与脚本实现可相互印证,四类常见问题:
- 源 URL 不可达:症状为
✗ Error fetching或 PR 明细中出现⚠️ Error: Failed to fetch upstream domains(对应 UpdateResult.error 字段),排查 URL、限流与 Actions 日志(monitor-logs-*artifact); - 变更量过大:优先为该源配置
max_domains,或拆分大源,其次核对该源格式声明是否正确; - 误报:把源标记
trusted: false、向源上游反馈,并借助 config/exclusions/ 排除机制固化人工裁决结果; - 缓存导致检测滞后:用
--no-cache强制刷新,或删除TEMP_DIR下upstream_cache_*.txt缓存文件。
原始文档"Future Enhancements"部分列出的计划项(与 IMPROVEMENT_PLAN.md Phase 7.4 一致):VirusTotal API 信誉检查、基于 last-seen 的增量更新、源健康监控、IP 列表(.ip文件)支持、持续失败源的自动下线、定期健康报告。这些能力在当前 monitor_upstream.py 中尚未实现,属于规划中的增强方向。
相关文件索引
| 文件 | 说明 |
|---|---|
| UPSTREAM_IMPLEMENTATION_SUMMARY.md | 本文档所依据的实现总结 |
| UPSTREAM_MONITORING.md | 完整用户指南(架构、格式表、合并策略、排错) |
| scripts/monitor_upstream.py | 监控脚本主实现(645 行) |
| .github/workflows/upstream-monitor.yml | 定时/手动触发的自动化工作流 |
| config/lists.yml | 当前生效的全局参数与已启用上游源 |
| config/upstream-sources-example.yml | 备选上游源示例与字段速查 |
| src/normalize.py | 四种格式的域名归一化实现 |
| src/config.py | PROJECT_ROOT/TEMP_DIR/CONFIG_DIR路径约定 |
| config/exclusions/README.md | 排除名单机制说明 |
| IMPROVEMENT_PLAN.md | Phase 7.4 实施记录与后续规划 |
- 网络安全
【免费下载链接】Lists
Primary Block Lists
相关推荐
CVAT监控体系:全链路监控配置
CVAT监控体系:全链路监控配置 概述 CVAT(Computer Vision Annotation Tool)作为业界领先的机器学习数据引擎,其监控体系设计
数据标注计算机视觉数据集AI 应用后端前端Model-Optimizer PTQ 预设配置体系深度解析:从 YAML 配置源到 `*_CFG` 常量的量化链路全解
Model Optimizer PTQ 预设配置体系深度解析:从 YAML 配置源到 _CFG 常量的量化链路全解 导读 :本文围绕 Model Optimiz
人工智能大模型模型优化模型量化模型压缩3 步做出专业级 U 盘启动盘:免费工具 Rufus 完整指南
3 步做出专业级 U 盘启动盘:免费工具 Rufus 完整指南 重装系统、修电脑,第一件事都是先做一张 U 盘启动盘。Rufus 是一款完全免费开源的 U 盘格
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考