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界面, 依赖管理, 内核监控, 后端开发, 威胁情报, 威胁情报收集, 威胁情报整合, 威胁情报标准化, 开发模式, 开发者工具, 开源项目, 数据聚合, 机器学习, 热重载, 独立软件, 虚拟环境, 轻量级应用, 逆向工具