fabs-net/swarmnoise

GitHub: fabs-net/swarmnoise

自动从 GreyNoise Swarm 传感器收集针对 Fortinet 的攻击流量,生成可直接接入 FortiGate 防火墙的 IP 威胁情报源。

Stars: 0 | Forks: 0

# swarmnoise 自动收集器,用于获取 GreyNoise Project Swarm 传感器数据,专门针对位于德国法兰克福的传感器所观测到的针对 Fortinet 的攻击流量。 生成纯文本 IP 情报源,兼容 **FortiGate External Threat Feed**(以及任何其他通过 HTTPS 消费以换行符分隔的 IP 黑名单的防火墙)。 ## 威胁情报源 ### 完整情报源 ``` https://raw.githubusercontent.com/fabs-net/swarmnoise/main/feeds/fortinet_ips.txt ``` 过去 30 天内观测到攻击该传感器的所有源 IP。覆盖范围最广,但存在略高的误报风险。 ### 过滤后的情报源 ``` https://raw.githubusercontent.com/fabs-net/swarmnoise/main/feeds/fortinet_ips_filtered.txt ``` 完整情报源的子集,其中会话被 GreyNoise 分类为 **malicious**。数据源自 [GreyNoise v3 Sessions API](https://docs.greynoise.io/reference/getsessions) 并通过 Lucene 查询进行过滤——不涉及任何受速率限制的富化 API。每个 IP 在 `feeds/filtered_metadata.json` 中包含富化的元数据(标签、CVE、来源地理位置、Suricata 签名)。 两种情报源均: - 每行一个 IP,无注释,无标头 - 滚动的 30 天时间窗口 —— 超过 30 天未被观测到的 IP 会自动修剪 - 每天在随机时间更新 1 到 10 次 ### FortiGate 设置 **Security Fabric → External Connectors → Threat Feeds → IP Address** | 字段 | 值 | |---|---| | 名称 | `swarmnoise-fortinet` | | URI | `https://raw.githubusercontent.com/fabs-net/swarmnoise/main/feeds/fortinet_ips.txt` | | HTTP 基本认证 | 关闭 | | 刷新频率 | 60 分钟 | 若要使用误报率较低的过滤情报源,请改用 `fortinet_ips_filtered.txt` 作为 URI。 然后在防火墙策略中引用此连接器,动作为 **Deny**,或在 IPS 传感器中引用。 ## 工作原理 GitHub Actions 工作流**每小时**触发一次。每天 UTC 午夜时分它会: 1. 选择一个介于 **1 到 10** 之间的随机数 —— 作为当天的获取次数 2. 将这些获取任务随机分配到当天剩余的小时中 3. 将计划持久化到 `state/today.json` 中 随后的每小时检查会将当前小时与计划进行比较,并在到期时触发获取。在 `workflow_dispatch`(手动触发)时,计划检查门会被绕过,始终执行一次获取。 提交模式是**有机且不可预测的** —— 每天随机时间产生 1 到 10 次提交。 ### 双 API 架构 收集器使用两个独立的 GreyNoise API 端点: | | 完整情报源 | 过滤情报源 | |---|---|---| | **API** | v1 Swarm (`/v1/workspaces/{id}/sensors/activity`) | v3 Sessions (`/v3/sessions`) | | **过滤器** | 无 —— 所有会话 | `classification:malicious`(Lucene 查询) | | **分页大小** | 1,000 | 100 | | **分页方式** | 30 分钟时间块(无法使用滚动令牌) | 标准基于页面的分页 | | **元数据** | 基础(IP、端口、协议) | 丰富(标签、CVE、地理位置、Suricata) | ### 首次运行(引导) 首次运行时 `feeds/ip_metadata.json` 不存在,因此脚本会通过获取过去 30 天的数据来自动引导情报源。此过程大约需要 37 分钟(以 0.5 秒/次的速度进行 1,437 次 API 调用)。 ### 分页 GreyNoise API 将每次请求的响应上限设定为 1,000 个会话。它返回的滚动/游标令牌大约为 8 KB 的 base64 数据 —— 太大而无法作为查询参数(HTTP 414)或请求标头(HTTP 400)传回。因此未使用滚动分页。 相反,每次获取的时间窗口被分割成 **30 分钟的块**。根据观测到的传感器速率(约 2,000 个会话/30 分钟),某些数据块仍然会达到 1,000 个会话的上限,这些时间窗口中的部分会话可能会被遗漏。尽管如此,IP 情报源依然全面 —— 唯一的攻击者 IP 在多次获取过程中会迅速收敛。 ## 仓库结构 ``` swarmnoise/ ├── .github/workflows/ │ └── scheduler.yml # Hourly trigger, randomised schedule logic + fetch ├── scripts/ │ └── fetch_sessions.py # v1 full feed + v3 filtered feed, run log ├── feeds/ │ ├── fortinet_ips.txt # Full IP blocklist (one IP per line) │ ├── fortinet_ips_filtered.txt # Filtered feed (malicious IPs only) │ ├── ip_metadata.json # Per-IP first_seen/last_seen (full feed) │ └── filtered_metadata.json # Per-IP enriched metadata (filtered feed) ├── runs/ # Run log JSON files (always written) ├── state/ │ └── today.json # Daily schedule state ├── requirements.txt └── README.md ``` ## 所需的 GitHub Secrets 在 **Settings → Secrets and variables → Actions** 下设置以下内容: | Secret | 描述 | |---|---| | `GREYNOISE_API_KEY` | GreyNoise API 密钥 (viz.greynoise.io → Settings → API Key) | | `WORKSPACE_ID` | GreyNoise 工作区 UUID | | `SENSOR_ID` | Swarm 传感器 UUID (viz.greynoise.io → Observe → Sensors) | `GITHUB_TOKEN` 会被 Actions 自动用于提交 —— 无需个人访问令牌(PAT)。 ## 文件结构 **`feeds/ip_metadata.json`** —— 滚动的 30 天 IP 索引 ``` { "1.2.3.4": { "first_seen": "2026-04-05T09:00:00Z", "last_seen": "2026-05-05T10:26:00Z" } } ``` **`runs/YYYY-MM-DD_HHMM_run_log.json`** —— 即使未发现会话也始终会写入 ``` { "timestamp": "2026-05-05T12:00:00Z", "time_window_start": "2026-05-05T06:00:00Z", "time_window_end": "2026-05-05T12:00:00Z", "sessions_found": 412, "feed_ip_count": 1349, "filtered_ip_count": 87, "duration_seconds": 8.3, "error": null } ``` **`feeds/filtered_metadata.json`** —— 每个 IP 的富化元数据(仅限过滤情报源) ``` { "1.2.3.4": { "first_seen": "2026-04-05T09:00:00Z", "last_seen": "2026-05-05T10:26:00Z", "classification": "malicious", "tags": ["Mirai TCP Scanner", "Mirai"], "tag_categories": ["worm"], "tag_intentions": ["malicious"], "cves": [], "country": "United States", "country_code": "US", "asn": "AS32181", "org": "GigeNET", "is_vpn": false, "is_tor": false, "is_bot": false, "rdns": "host.example.com", "destination_ports": [23, 80], "protocols": ["tcp"], "suricata_signatures": ["Mirai TCP Scanner"] } } ``` ## 本地查询数据 ``` # 显示当前 Feed IP 数量 wc -l feeds/fortinet_ips.txt # 显示所有恶意 IP 的 enriched metadata jq '.' feeds/filtered_metadata.json ```
标签:CISA项目, CVE, FortiGate, Fortinet, GitHub Actions, GreyNoise, IPS, IP 地址批量处理, IP黑名单, Suricata, 外部威胁源, 威胁情报, 威胁检测与响应, 威胁源, 开发者工具, 恶意流量, 攻击流量, 数字签名, 现代安全运营, 网络传感器, 自动化采集, 自动笔记, 逆向工具, 防火墙策略