jusafing/ThreatFeeds-Lite

GitHub: jusafing/ThreatFeeds-Lite

轻量级威胁情报源聚合器,整合异构情报。

Stars: 0 | Forks: 0

# 威胁情报轻量版 一个轻量级、独立的威胁情报源聚合器,拥有一个 **基于LLM的规范化引擎** —— 它不仅收集源,还使用LLM将异构的威胁情报整合到单个规范模式中。它 监听、拉取和规范化来自多个来源的威胁情报,在SQLite中本地存储数据,并公开一个Web UI用于查看和配置。 ## 前置条件 | 依赖 | 版本 | 备注 | |---|---|---| | Python | 3.10+ | 适用于后端 | | Node.js | 18+ | 适用于前端 | | npm | 9+ | 与Node.js捆绑 | | uv | 最新版 | 推荐的Python包管理器 | ### 安装uv **macOS / Linux** ``` curl -LsSf https://astral.sh/uv/install.sh | sh ``` **Windows** ``` powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` **Homebrew** ``` brew install uv ``` ## 快速入门 ``` # 1. 克隆仓库 git clone cd OSS-Project-SimpleFeedIngestor # 2. 启动应用程序 ./threatfeeds-lite start ``` 运行脚本将自动: - 使用`uv`创建Python虚拟环境(`.venv/`) - 从`backend/requirements.txt`安装所有Python依赖项 - 如果`frontend/dist/`不存在,则构建前端 - 在**`127.0.0.1:8000`**(默认为localhost)上启动后端 在**http://localhost:8000**打开您的浏览器 ## 开发模式 分别运行后端和Vite开发服务器,以便在前端更改时进行热重载: ``` ./threatfeeds-lite start --dev ``` | 服务 | URL | |---|---| | 前端(Vite) | http://localhost:5173 | | 后端API | http://localhost:8000/api | | API文档(Swagger) | http://localhost:8000/docs | ## 命令 ``` ./threatfeeds-lite start [options] Start the application ./threatfeeds-lite stop Stop all running processes ./threatfeeds-lite restart [options] Stop then start (options forwarded to start) ./threatfeeds-lite status Show running process status ./threatfeeds-lite --reset-db Delete and recreate all source databases ./threatfeeds-lite --reset-source Reset a single source database ./threatfeeds-lite --reset-admin-password Reset the admin password (see Authentication) ./threatfeeds-lite help Show full usage ``` ### `start` / `restart`选项 | 选项 | 描述 | |---|---| | `--dev` | 在**前台**运行uvicorn,将日志流式传输到终端(Ctrl+C停止)。没有它,服务器在后台运行。 | | `--bind ` | 绑定的地址(和可选的端口号)。接受`ip`、`ip:port`或`:port`。如果没有指定端口号,则使用**8000**。默认:`127.0.0.1:8000`。见[绑定和端口](#binding--ports)。 | | `--base-prefix ` | 仅在此次运行中覆盖`app_base_prefix`(来自`config/application.yaml`),通过`SIMPLE_FEED_BASE_PREFIX`。必须以`/`开头,不能以`/`结尾,不能包含`//`。使用`""`(空字符串)在根目录上安装。 | | `--enable-auth` | 强制在此次运行中启用身份验证(通过`SIMPLE_FEED_ENABLE_AUTH=1`,覆盖yaml)。见[身份验证](#authentication-optional)。 | ## 绑定和端口 默认情况下,服务器绑定到**`127.0.0.1:8000`**——只能从本地机器访问。使用`--bind`更改地址和/或端口号: ``` ./threatfeeds-lite start --bind 0.0.0.0 # all interfaces, port 8000 ./threatfeeds-lite start --bind 0.0.0.0:9000 # all interfaces, port 9000 ./threatfeeds-lite start --bind :9000 # localhost (127.0.0.1), port 9000 ./threatfeeds-lite start --bind 192.168.1.10:8000 # a specific interface ``` - 语法是`ip:port`。一个裸`ip`保留默认端口号(8000);一个裸`:port` 保留默认地址(`127.0.0.1`)。 - 端口号必须在**1到65535**之间——超出范围的值将被拒绝。 - 绑定到`0.0.0.0`将在**所有网络接口**上公开服务。仅在受信任的网络上这样做,并考虑启用[身份验证](#authentication-optional)。 ## 身份验证(可选) 默认情况下,身份验证是**禁用的**——UI和API都是开放的。可以通过以下方式启用它: - 在每次运行时使用`--enable-auth` - 通过`SIMPLE_FEED_ENABLE_AUTH=1`环境变量 - 在`config/application.yaml`中 CLI标志和环境变量优先于yaml。 ``` ./threatfeeds-lite start --enable-auth ``` 启用后: - **角色**。三个角色:`admin`(完全访问权限,包括配置、规范化器和用户管理)、`normal`(查看范围,只读)和`sender`(一个仅监听的机器账户,可能**仅**向`/api/ingest/listener` POST ——非常适合无人值守的推送自动化)。侧边栏和API在服务器端强制执行角色门控。自然语言查询端点(`POST /api/query/nl`)是一个对`admin`和`normal`可用的只读操作,但对`sender`不可用。 - **会话**。登录基于会话cookie;所有API `401`都通过单个处理程序路由,UI重定向到登录屏幕。 - **首次运行的admin**。在启用身份验证的首次启动时,将创建一个`admin`账户,随机密码写入`data/first-run-admin-credentials.txt`(模式`0600`,**gitignored**,从未登录)。您必须在首次登录时更改此密码;之后删除文件。 - **重置admin密码**而无需启动服务器: ./threatfeeds-lite --reset-admin-password 这将生成一个新的随机密码,打印它,将其写入相同的`0600` 凭证文件,并在下一次admin登录时强制更改密码。 - **密码策略**。最小长度和组成规则在后端和前端上强制执行(创建用户、自助更改和admin 重置都要求有一个确认匹配字段)。 - **自助服务帐户**页面(更改您的密码)和一个仅限管理员 **用户管理**选项卡(创建/删除用户,重置密码)位于应用程序中。 ## 支持的源格式 本地上传和远程拉取都接受: - **JSON**(对象或对象数组;自动提取众所周知的信封键,如 `vulnerabilities`、`data`、`results`) - **NDJSON**(每行一个JSON对象) - **CSV / TSV**(自动检测分隔符,如`,`、`\t`、`;`、`|`) - **XML**(扁平的一级信封) 两种摄取路径还透明地解压缩: - **`.gz`**(单层gzip) - **`.zip`**(必须包含恰好一个常规文件成员;拒绝空和多个成员的存档) 解压缩后的有效负载在解析之前被验证为上述四种纯文本格式之一。默认解压缩大小限制为**100 MiB**,可在`config/application.yaml`下的`max_decompressed_bytes`中配置。`.7z`故意不支持(避免非stdlib依赖)。 ## 推送监听器(API端点) 推送监听器允许外部工具通过HTTP直接将威胁情报事件POST到应用程序。它运行在主应用程序端口上(没有单独的端口)并从**配置→监听器端点**(`config/sources.yaml`中的`listener.enabled`,默认启用)切换。 **通用接收**——将任何JSON(单个对象或对象数组)POST到: ``` curl -X POST http://127.0.0.1:8000/api/ingest/listener \ -H 'Content-Type: application/json' \ -d '[{"indicator": "1.2.3.4", "threat_type": "c2"}]' ``` 事件被索引到以**推送它们的认证用户**命名的源(prompts-058)。当禁用身份验证时,请求是匿名的,并回退到**名为`Received Feed `**的源(接收的Unix时间)。每个有效负载都会被记录(`logs/audit.log`中的INFO接收摘要;DEBUG级别的完整正文),并且每个条目的失败都会在`logs/app.log`中详细记录。 要将事件推送到**显式命名的**源,请POST到`/api/ingest/push/`(单个对象)或`/api/ingest/push-batch/`(数组)。 ## 监视器 **监视器**是用户定义的保存的过滤器,它持续评估摄取事件并将匹配项发布到**每个监视器的公共源URL**(可选地,推送到webhook)。使用监视器从洪流中切割出专注的馈送——例如,*"影响nginx的严重CVE"*或*"来自feedA的任何标记勒索软件"*——下游工具可以轮询而无需接触管理员API。 监视器从管理员仅有的**监视器**页面(摘要/配置/活动选项卡)和管理员门控的`/api/watchers/*` API管理。定义和触发事件历史记录存储在专门的`data/watchers.db`中,与`normalized.db`分开,以便在规范化模式重建时保持一致。 ### 匹配方式 每个监视器有一个或多个**条件**,AND组合。条件是`field` + `value`加上`match_type`: | `match_type` | 匹配时… | |---|---| | `exact` | 字段等于值 | | `contains` | 值是字段的子串 | | `wildcard` | 字段与`*`/`?`glob匹配 | | `regex` | 字段与正则表达式匹配 | | `gte` / `lte` | 数字字段是≥ / ≤数字值 | - 留空`field`(或`*`/`all`/`any`)以将值与**任何**字段匹配。`case_sensitive`(默认关闭)适用于`exact`、`wildcard`和`contains`。 - **范围**按监视器设置:`dataset`(`all`、`raw`或`normalized`)和`feeds`(源名称列表;空=所有源)。 - `severity`(`low`/`medium`/`high`/`critical`)是**分类标签**仅——它不阻止匹配。 ### 评估模式 | `mode` | 何时评估 | |---|---| | `realtime` | 在每次摄取或规范化器运行完成后自动。 | | `scheduled` | 每`interval_sec`秒(最小5)固定定时器。 | 每个监视器跟踪每个源的高水位标记,因此每次遍历时只考虑**新**事件。您还可以在UI中按**触发**(或`POST /api/watchers/{id}/trigger`)立即评估——即使在禁用的监视器上也是如此。 ### 公共源 匹配的事件在**未认证**的馈送URL上发布(它位于`/api/`之外,因此认证层不保护它): ``` # JSON(默认);也通过监视器的`format`支持CSV和XML/RSS curl http://127.0.0.1:8000/feed/watcher// ``` ``是从监视器名称派生的slug。该源提供最新的匹配项,受监视器的`max_feed_events`(以及全局`watcher_max_events`上限)限制。 ### Webhook / HTTP投递(可选) 将`publish_target`设置为`webhook`或`http`以将每个匹配项**推送到**外部端点。有效负载由`webhook_format`塑造: | `webhook_format` | 目标 | |---|---| | `generic` | 纯JSON POST | | `discord` | Discord webhook | | `slack` | Slack incoming webhook | | `teams` | Microsoft Teams连接器 | 格式从webhook URL的主机自动检测(可覆盖)。可选的`auth_header` / `auth_value`对附加自定义认证头。 投递是按事件尽力而为,并自动重试;失败在**活动**选项卡中显示,并提供最后错误详情以供检查。 ### 保留 - **每个监视器**:`max_feed_events`限制源保留的匹配项数量;定期清理作业每`cleanup_interval_sec`秒(10–86400)修剪存储的源。 - **全局上限**:`config/application.yaml`中的`watcher_max_events`限制每个监视器的保留(默认**1000**,范围**10–100000**)。它可以从UI或通过`GET`/`POST /api/app/watcher-max-events`编辑。 ## 查看器 & 规范化UI 除了API和监视器之外,Web UI还公开了核心的日常界面: - **查看器**——浏览**原始**和**规范化**事件表,具有可配置的列选择器、全文搜索和自然语言(LLM)查询框。原始和规范化是独立的存储(见[原始与规范化](#get-normalized--normalized-events))。 - **规范化器**——运行和监控基于LLM的规范化引擎,并审查每次运行的记录(计数、状态、时间)。 - **智能映射**——一个管理员工作区,用于LLM辅助的字段映射建议,具有手动覆盖,这些覆盖为规范模式提供数据(见[规范模式协调](#canonical-schema-reconciliation))。 ## API客户端脚本 `scripts/api_client.py`是API的独立、无依赖(仅Python标准库)客户端。使用任何Python 3运行它——无需虚拟环境。每个命令将JSON文档打印到stdout。 ``` scripts/api_client.py --help # full syntax for all commands ``` **全局选项** - `--url` — 基础API端点URL(默认`http://127.0.0.1:8000`)。包含方案;使用`https://…` URL(可选带有路径前缀)来访问位于反向代理/别名后面的服务器。值必须不包含空白——从`.env`模板中复制的任何散列注释都会被拒绝,并返回一个清晰的错误而不是模糊的urllib回溯。 - `--username` / `-u`,`--password` / `-p` — 身份验证启用的服务器的凭据(当禁用身份验证时,完全省略——见下面的[身份验证](#authentication))。 - `--insecure` / `-k` — 跳过TLS证书验证(接受自签名/不受信任的证书)。**不安全**:禁用请求的MITM保护;仅在受信任的网络中对您可以信任的服务器使用。 ### `get-` — 原始事件 以JSON数组的形式检索原始事件表。 ``` # 所有源,最多1000个事件(默认) scripts/api_client.py get-raw # 仅两个命名源 scripts/api_client.py get-raw feedA feedB # 限制返回的事件数量 scripts/api_client.py get-raw --max 50 # 精确列过滤器:仅关键严重性行(可重复,AND组合) scripts/api_client.py get-raw --field severity=critical scripts/api_client.py get-raw --field severity=critical --field indicator_type=url ``` ### `get-normalized` — 规范化事件 与`get-raw`的相同接口,但读取规范化数据表。 ``` # 所有标准化事件,最多1000个 scripts/api_client.py get-normalized # 单个源,最多20个事件 scripts/api_client.py get-normalized feedA --max 20 # 精确列过滤器,与标准化模式验证 scripts/api_client.py get-normalized --field indicator_type=ipv4-addr ``` ### `send` —将事件推送到监听器 将通用JSON(单个对象或对象数组)POST到`/api/ingest/listener`。服务器将其索引到以认证用户命名的源(或当禁用身份验证时,名为`Received Feed `的源)。有效负载可以来自文件、内联字符串或stdin: ``` scripts/api_client.py send --file events.json scripts/api_client.py send --data '[{"indicator": "1.2.3.4"}]' cat events.json | scripts/api_client.py send ``` 当启用身份验证时,`send`需要**admin**或**sender**帐户(`normal`用户获得`403`)。 ### `search` —全文搜索 通过服务器端的`?search=`查询搜索原始或规范化表。术语与索引的文本字段(指标、标题、描述、标签、行为者、活动、…)匹配。接受与`get-*`命令相同的可选源名称和`--max`。 ``` # 在原始事件中搜索“npm”(默认 --type raw) scripts/api_client.py search "npm" --max 20 # 在标准化表中搜索,限制为一个源 scripts/api_client.py search "ransomware" feedA --type normalized ``` ### `query` —自然语言查询(LLM) 用普通英语提出问题。服务器LLM将其转换为**约束的、白名单的过滤器**(永远不会原始SQL),在该过滤器上运行本地数据库,通过与API其余部分相同的参数化查询层运行,并返回匹配的行以及解释的过滤器。这需要在服务器上配置LLM提供程序(与智能模式规范化使用的相同);如果没有,端点返回`503`。 `--type {raw,normalized}`、`--source `和`--max `是可选覆盖:当提供时,它们优先于LLM的选择。响应是包含`dataset`、`count`、`interpreted_filter`和`results`的JSON。 当启用身份验证时,`query`是一个**读取**操作——对`admin`和`normal`帐户可用;`sender`帐户获得`403`(仅推送)。 ### `list-feeds` —可用源 从摘要端点列出可用源及其每个源条目计数(加上`__total__`行)。 ``` scripts/api_client.py list-feeds # raw catalogue (default) scripts/api_client.py list-feeds --type normalized ``` ### 演示运行器——使用一个命令运行整个测试计划 `scripts/client_tests_demo/run_tests.sh`通过`api_client.py`驱动T1–T11测试计划,针对正在运行的服务器运行,并将每个结果保存到磁盘。这是查看客户端从头到尾操作的最简单方法。 **1. 配置连接 + 凭据。**复制示例env文件并填写它(默认情况下,它从`scripts/client_tests_demo/.env.test`读取): ``` cp scripts/client_tests_demo/.env.example scripts/client_tests_demo/.env.test # 然后编辑 .env.test: # host [+ 端口] — 目标主机;端口是可选的(默认:80 http / 443 https)。 # host可能包含方案(https://host);裸主机 -> http。或者 # url — 包含方案的完整基本URL(反向代理别名/路径前缀); # 覆盖host/port,必须包含http://或https:// # skip_tls_verify=true — 接受自签名/不受信任的TLS(不安全;或使用-k) # user_push / pass_push — 用于推送事件的账户(T1;发送者或管理员) # user_read / pass_read — 用于读取/搜索/查询的账户(T2–T11;普通或管理员) ``` **2. 运行它。** ``` bash scripts/client_tests_demo/run_tests.sh # uses .env.test bash scripts/client_tests_demo/run_tests.sh --env /path/to/other.env bash scripts/client_tests_demo/run_tests.sh -k # also skip TLS verification ``` **3. 读取结果。**每个运行在`scripts/client_tests_demo/`内部创建一个名为`test-client
标签:Apex, DNS解析, MITM代理, Node.js开发, Python开发, SQLite数据库, Web界面, 依赖管理, 内核监控, 后端开发, 威胁情报, 威胁情报收集, 威胁情报整合, 威胁情报标准化, 开发模式, 开发者工具, 开源项目, 数据聚合, 机器学习, 热重载, 独立软件, 虚拟环境, 轻量级应用, 逆向工具