gorkemgun/sgb-blocklist

GitHub: gorkemgun/sgb-blocklist

将土耳其网络安全总统府的恶意地址 API 数据每小时镜像为按类型和分类拆分的纯文本列表,方便安全工具直接订阅消费。

Stars: 1 | Forks: 0

# 恶意地址列表 (T.C. Siber Güvenlik Başkanlığı) 每小时镜像一次由土耳其网络安全总统府 (Turkish Cyber Security Presidency) 发布的恶意地址数据,从其 API 拉取并以纯文本列表写出,按地址类型(domain, URL, IPv4, IPv6)和恶意类别进行拆分。 曾位于 `usom.gov.tr/url-list.txt` 的纯文本订阅源已于 **2026 年 6 月 1 日**停用。该 URL 现在提供一个 Swagger 页面。API 是获取数据的唯一剩余途径: ## 列表 ### 按类型 | 文件 | API 类型 | 内容 | |---|---|---| | [domains.txt](domains.txt) | `domain` | 恶意 domain,每行一个 | | [urls.txt](urls.txt) | `url` | 完整的 URL 记录,无 scheme,例如 `example.com/bad/path` | | [ipv4.txt](ipv4.txt) | `ip` | IPv4 地址,按数字排序 | | [ipv6.txt](ipv6.txt) | `ip6` | IPv6 地址,按数字排序 | | [ipv6net.txt](ipv6net.txt) | `ip6net` | IPv6 网络块,上游目前为空 | | [url-list.txt](url-list.txt) | all | 旧版 `url-list.txt` 的直接替代品。无头部,所有类型合并在一个文件中 | | [domains-from-urls.txt](domains-from-urls.txt) | `url` 主机名 | 从 URL 记录中提取的主机名。请参阅下方的注意事项 | | [state.json](state.json) | n/a | 每个文件的同步状态和记录计数 | 类型文件以 `#` 注释行开头。如果你的消费程序不跳过注释行,请使用没有注释行的 `url-list.txt`。 头部的 `Last change` 行是指该列表记录实际发生变化的最后时间,而不是同步运行的最后时间。记录未发生更改的文件将保持不变,因此如果每小时运行一次未发现新内容,则完全不会产生差异 (diff)。`state.json` 中保存了最近一次同步的时间戳。 ### 按类别 [categories/](categories/) 为每个 `-` 对保存一个文件。当前带有记录计数的文件列表位于 [categories/README.md](categories/README.md)。 | 代码 | 类别 | |---|---| | `PH` | 钓鱼 | | `BP` | 金融钓鱼 | | `MD` | 恶意软件传播 domain | | `MI` | 恶意软件传播 IP | | `MU` | 恶意软件传播 URL | | `MC` | 恶意软件命令控制中心 (C&C) | | `CA` | 网络攻击(端口扫描、暴力破解等) | 仅包含金融钓鱼 domain 的文件位于 [categories/domains-BP.txt](categories/domains-BP.txt)。仅包含 C&C IPv4 地址的文件 位于 [categories/ipv4-MC.txt](categories/ipv4-MC.txt)。 代码来自记录的 `desc` 字段。如果 API 添加了新代码,其文件会自动出现,而在下一次完整抓取时,失去记录的类别其文件将被删除。带有空或无法识别的 `desc` 的记录将被归入 `UNKNOWN` 分类中。 ### 原始 URL ``` https://raw.githubusercontent.com/gorkemgun/sgb-blocklist/main/domains.txt https://raw.githubusercontent.com/gorkemgun/sgb-blocklist/main/ipv4.txt https://raw.githubusercontent.com/gorkemgun/sgb-blocklist/main/categories/domains-PH.txt ``` ### 值得了解的事项 - `raw.githubusercontent.com 的大致缓存时间为 5 分钟,对于每小时的更新频率来说这不成问题。 - domain 列表包含**超过 462,000**条记录。在低内存设备上,列表编译可能需要一些时间。如果你需要较小的集合,请选择单个类别文件。 - IDN domain 会被转换为 punycode (`xn--...`),因为这是在 DNS 中解析的形式。 - IP 地址绝不会混入 domain 列表中。上游被错误归类为 `type=domain` 的 IPv4 记录将被跳过。 - `domains-from-urls.txt` 中的条目涵盖**整个 domain**,而源记录被列出是因为某个特定的 URL 路径是恶意的,例如一个在其他方面合法的网站上的单个被入侵页面。使用该文件可能会导致合法网站被拦截,这就是默认情况下它不被合并到 `domains.txt` 中的原因。 ## API 的工作原理 无需身份验证、API 密钥或配额。一个 endpoint 即可完成所有操作: ``` GET https://siberguvenlik.gov.tr/api/address/index ``` | 参数 | 描述 | |---|---| | `type` | `domain`, `url`, `ip`, `ip6`, `ip6net` | | `q` | 全文搜索 | | `desc` | 恶意类别代码(见上表) | | `source` | `US` USOM/TR-CERT, `SO` CERT, `RS` RSA, `IH` 公开报告, `SB` SGB | | `connectiontype` | `AC` APT C&C, `BC` 僵尸网络 C&C, `EK` Exploit Kit, `MC` 移动端 C&C, `MF` 恶意软件下载, `MM` 挖矿恶意软件, `PH` 钓鱼, `OT` 其他 | | `criticality_level` | 1(最高)到 10(最低) | | `date_gte`, `date_lte` | `YYYY-MM-DD` 或 `YYYY-MM-DD HH:MM:SS` | | `page` | **从 1 开始**。`page=0` 和 `page=1` 都返回第一页 | | `per-page` | 1 到 9999。超过 9999 的任何值都会返回 **HTTP 429** | 响应: ``` { "totalCount": 462318, "count": 9999, "models": [ { "id": 1147406, "url": "uyari-detaylar-tr.ink", "type": "domain", "desc": "PH", "source": "IH", "date": "2026-07-29 16:13:35.809423", "criticality_level": 4, "connectiontype": "PH" } ], "page": 0, "pageCount": 47 } ``` 在构建此项目时发现的一些坑: - `page` 参数从 1 开始,但响应中的 `page` 字段从 0 开始。 - 记录按 `id` 降序排列,并且新记录会被添加到前面,因此在长时间抓取期间,同一行可能会出现在两个连续的页面上。这会产生重复项而不是间隙,脚本会通过 set 进行去重。 - `date` 字段似乎是 UTC,因为记录的时间戳与 HTTP `Date` 头部一致。增量查询仍会向后追溯 6 小时。 - API 不会报告删除情况。这就是为什么每天运行一次完整抓取并从头开始重建每个列表的原因。 用于代码到标题映射的查找 endpoint: `/api/address-description/index`, `/api/address-source/index`, `/api/address-connection-type/index` ## 同步策略 [.github/workflows/update.yml](.github/workflows/update.yml) 在每小时的第 17 分钟运行 [scripts/sgb_sync.py](scripts/sgb_sync.py): - **delta**(每小时默认):查询 `date_gte = last run - 6h`,因此每种类型一次请求,总共几十条记录,合并到现有列表中。 - **full**(每 24 小时一次,由 `state.json` 中的 `last_full` 决定):在大约 4 分钟内遍历所有 52 个页面并重建每个列表,这就是清除已取消记录的方法。输出布局版本的更改也会强制进行一次 full 运行。 每小时运行一次完整抓取意味着每次都要从 API 拉取大约 90 MB 的数据,因此刻意避免了这种情况。Delta 加上每日 full 运行会产生相同的结果。 只有记录发生更改的文件才会被重写,因此如果一小时没有新数据,则除了 `state.json` 之外不会触及任何文件;如果连它也没有变化,则不会提交任何内容。 ### 手动运行 在 GitHub 上:**Actions -> Update malicious address lists -> Run workflow**。模式是可选的。 在本地: ``` python scripts/sgb_sync.py --mode full --out . # rebuild everything python scripts/sgb_sync.py --mode delta --out . # only add what is new python scripts/sgb_sync.py --mode full --max-pages 1 # quick smoke test python scripts/sgb_sync.py --mode delta --force-write # rewrite files after a header format change python scripts/sgb_sync.py --mode full --include-url-hosts # merge URL hosts into domains.txt ``` 仅使用标准库,无其他依赖项(Python 3.9+)。 想要改为按 `connectiontype` 或 `criticality_level` 拆分文件?`scripts/sgb_sync.py` 中的 `clean_desc(rec.get("desc"))` 调用是决定记录归属哪个类别文件的唯一位置。 ## 运行你自己的副本 消费这些列表无需安装任何东西。要运行你自己的镜像: 1. Fork 或 clone 此 repo。 2. 在 **Settings -> Actions -> General -> Workflow permissions** 下,启用 *Read and write permissions*。 3. 从 Actions 标签页以 `full` 模式手动触发一次工作流,或者等待每小时一次的定时任务来执行它。 ### 关于仓库大小 这些列表总计约 30 MB,并且每小时提交一次。Git 对相似的文本压缩得很好,但随着时间的推移,repo 确实会变大。如果这变得令人困扰,可以折叠历史记录: ``` git checkout --orphan clean && git add -A && git commit -m "reset history" git branch -D main && git branch -m main && git push -f origin main ``` ## 许可证 此 repo 中的代码,即 `scripts/`、`.github/` 和文档,均采用 MIT 许可证。请参阅 [LICENSE](LICENSE)。 地址数据不受该许可证的约束。它由 T.C. Siber Güvenlik Başkanlığı 制作和拥有,此处仅进行抓取和重新格式化。使用条款由发布者设定: 上游:
标签:威胁情报, 开发者工具, 恶意地址, 数据镜像, 网络安全, 逆向工具, 隐私保护, 黑名单