Aiyeesha/log-anomaly-detector

GitHub: Aiyeesha/log-anomaly-detector

一个基于规则的认证日志异常检测引擎,通过透明且经过单元测试的规则实时发现暴力破解、不可能旅行、撞库和非工作时间访问等安全威胁。

Stars: 0 | Forks: 0

# 🕵️ 日志异常 Detector *[点击查看法语版本](#-log-anomaly-detector-1)* 一个用于认证日志的基于规则的检测引擎——用于发现暴力破解尝试、不可能旅行登录、撞库突发以及非工作时间访问,每一项都使用透明且经过单元测试的规则,而不是黑盒模型。 ## 为什么做这个项目 大多数“SOC 仪表板”演示显示的都是在其他地方已经存在的警报。而这个项目会*生成*警报:它接收原始认证事件,并通过检测逻辑进行处理,该逻辑必须对事件的*序列*进行推理——比如在短时间内聚集的失败尝试、同一个账户太快出现在两个国家、单个 IP 尝试许多不同的用户名。这与过滤或显示预先标记好的数据有着本质上的(也是更困难的)区别。 ## 功能 - **四个独立的检测规则**,每个都是一个无 I/O 的纯函数: - **暴力破解** — 同一账户在 5 分钟内有 5 次或以上的失败登录 - **不可能旅行** — 同一账户在比合理旅行时间(2 小时窗口)更短的间隔内,成功从两个不同的国家登录 - **撞库** — 同一源 IP 在 10 分钟内有 8 个或以上的*不同*用户名登录失败(这是暴力破解垂直模式对应的横向模式) - **非工作时间访问** — 在 UTC 时间 22:00 到 06:00 之间的成功登录 - **实时接收** — `POST /api/logs` 会在其实时窗口内,针对所有四个规则实时运行每个新事件 - **异常去重** — 如果源自某规则的未解决异常仍在其自身的时间窗口内,则该规则不会针对同一对象重新触发,因此持续的攻击不会产生重复的垃圾警报 - **“模拟攻击流量”按钮** — 重放一个特意触发所有四个规则各一次的合成场景,这对于演示引擎非常有用,免去手动构造大量请求的麻烦 - **持久化存储**(SQLite),用于原始事件和派生的异常 ## 架构 ``` ┌─────────────┐ REST (fetch) ┌───────────────────────────┐ │ React UI │ ───────────────► │ FastAPI routers │ │ (Vite/TS) │ ◄─────────────── │ logs / anomalies / simulate │ └─────────────┘ └──────────────┬─────────────┘ │ ┌───────▼───────┐ │ detection.py │ ← 4 pure rule functions, └───────┬───────┘ unit-tested with plain dicts ┌───────▼───────┐ │ crud.py │ (windowing + dedup + persistence) └───────┬───────┘ ┌───────▼───────┐ │ SQLAlchemy │ │ (SQLite) │ └────────────────┘ ``` `detection.py` 接收事件字典的普通列表,并返回普通的异常字典——没有数据库会话,也没有 FastAPI 请求上下文。`crud.py` 是唯一知道如何获取先前事件的正确时间窗口的地方(针对以账户为中心的规则按用户名获取,针对撞库规则按源 IP 获取),并将规则的输出转换为持久化、去重后的行。这种拆分使得 20 个规则边缘情况能在几毫秒内完成测试,且无需配置任何数据库。 ## 技术栈 | 层级 | 技术 | |-------|------------| | 后端 | Python 3.11+, FastAPI, SQLAlchemy | | 数据库 | SQLite (基于文件,零配置) | | 认证 | 在接收、解决和模拟端点上使用 API 密钥 | | 前端 | React 18, TypeScript, Vite | | 测试 | Pytest — 纯检测规则测试 + 完整 API 测试 | | 容器 | Docker Compose | ## 快速开始 ### 使用 Docker Compose ``` docker-compose up ``` 然后打开 [http://localhost:5176](http://localhost:5176)。后端在首次启动时会植入一个合成场景,以便立即显示所有四种规则类型。 ### 手动设置 **后端** ``` cd backend python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate cp .env.example .env pip install -r requirements.txt uvicorn app.main:app --reload --port 8003 ``` **前端** ``` cd frontend npm install npm run dev ``` ### 运行测试 ``` cd backend pip install -r requirements-dev.txt pytest -v ``` `test_detection.py` 通过手动构建的事件序列和固定的时间戳,覆盖了每条规则的触发和非触发条件——没有数据库,没有时钟依赖,不会出现不稳定性。`test_api.py` 对整个技术栈进行了测试,包括断言植入的场景会为每条规则精确生成一个异常(该场景锚定在一天中的固定时间点,而不是实际的挂钟时间,正是为了无论何时运行测试,该断言都是确定性的)。 ## API 参考 | 方法 | 端点 | 认证 | 描述 | |--------|----------|------|-------------| | `GET` | `/api/logs` | — | 最近的原始日志事件 (可选 `?username=&source_ip=&limit=100`) | | `POST` | `/api/logs` | `X-API-Key` | 接收一个事件;立即运行检测并返回任何新的异常 | | `GET` | `/api/anomalies` | — | 列出异常 (可选 `?severity=&resolved=&limit=100`) | | `PATCH` | `/api/anomalies/{id}/resolve` | `X-API-Key` | 将异常标记为已解决 | | `POST` | `/api/simulate` | `X-API-Key` | 重放演示场景 (每条规则一个异常) | | `GET` | `/api/stats` | — | 事件/异常总数、未解决的数量、每条规则的触发计数 | 后端启动后,可在 `/docs` 查看交互式 OpenAPI 文档。 ## 项目结构 ``` . ├── backend/ │ ├── app/ │ │ ├── main.py # App factory, lifespan (DB init + scenario seed) │ │ ├── config.py # Settings │ │ ├── database.py # SQLAlchemy engine/session │ │ ├── models.py # LogEventORM, AnomalyORM │ │ ├── schemas.py # Pydantic schemas │ │ ├── detection.py # The 4 detection rules (pure, unit-tested) │ │ ├── crud.py # Windowing, dedup, persistence, orchestration │ │ ├── security.py # API-key dependency │ │ ├── seed_data.py # Deterministic demo scenario builder │ │ └── routers/ │ │ ├── logs.py │ │ ├── anomalies.py │ │ ├── simulate.py │ │ └── stats.py │ ├── tests/ │ │ ├── test_detection.py # Pure rule tests, no DB, no clock dependency │ │ └── test_api.py │ ├── requirements.txt │ ├── requirements-dev.txt │ ├── .env.example │ └── Dockerfile ├── frontend/ │ └── src/ │ ├── api/client.ts │ ├── hooks/useAnomalies.ts │ └── components/ │ ├── StatsPanel.tsx │ ├── AnomalyTable.tsx │ ├── SimulateControls.tsx │ └── LogFeed.tsx └── docker-compose.yml ``` ## 已知限制 - 检测规则使用固定的阈值(5 次失败、8 个不同用户等),而不是基于每个用户/组织生成自适应基线——真实系统会根据环境调整这些参数,或者使用统计基线 - 没有地理位置查找功能——“国家”是接收事件中的一个字段,而不是从源 IP 推导出来的,因此“不可能旅行”规则信任日志源报告的任何内容 - 24 小时的回溯窗口是一个固定常量;生产系统可能会按规则进行索引和窗口化,而不是在每次接收事件时重新查询主体的完整历史记录 ## 许可证 MIT # 🕵️ 日志异常 Detector *[上方为英文版本](#-log-anomaly-detector)* 一个用于认证日志的基于规则的检测引擎——用于发现暴力破解尝试、不可能旅行登录、撞库突发以及非工作时间访问,每一项都使用透明且经过单元测试的规则,而不是黑盒模型。 ## 为什么做这个项目 大多数“SOC 仪表板”演示显示的都是在其他地方已经存在的警报。而这个项目会*生成*警报:它接收原始认证事件,并通过检测逻辑进行处理,该逻辑必须对事件的*序列*进行推理——比如在短时间内聚集的失败尝试、同一个账户太快出现在两个国家、单个 IP 尝试许多不同的用户名。这与过滤或显示预先标记好的数据有着本质上的(也是更困难的)区别。 ## 功能 - **四个独立的检测规则**,每个都是一个无 I/O 的纯函数: - **暴力破解** — 同一账户在 5 分钟内有 5 次或以上的失败登录 - **不可能旅行** — 同一账户在比合理旅行时间(2 小时窗口)更短的间隔内,成功从两个不同的国家登录 - **撞库** — 同一源 IP 在 10 分钟内有 8 个或以上的*不同*用户名登录失败(这是暴力破解垂直模式对应的横向模式) - **非工作时间访问** — 在 UTC 时间 22:00 到 06:00 之间的成功登录 - **实时接收** — `POST /api/logs` 会在其实时窗口内,针对所有四个规则实时运行每个新事件 - **异常去重** — 如果源自某规则的未解决异常仍在其自身的时间窗口内,则该规则不会针对同一对象重新触发,因此持续的攻击不会产生重复的垃圾警报 - **“模拟攻击流量”按钮** — 重放一个特意触发所有四个规则各一次的合成场景,这对于演示引擎非常有用,免去手动构造大量请求的麻烦 - **持久化存储**(SQLite),用于原始事件和派生的异常 ## 架构 ``` ┌─────────────┐ REST (fetch) ┌───────────────────────────┐ │ UI React │ ───────────────► │ Routers FastAPI │ │ (Vite/TS) │ ◄─────────────── │ logs / anomalies / simulate │ └─────────────┘ └──────────────┬─────────────┘ │ ┌───────▼───────┐ │ detection.py │ ← 4 fonctions de règles pures, └───────┬───────┘ testées avec de simples dicts ┌───────▼───────┐ │ crud.py │ (fenêtrage + dédup + persistance) └───────┬───────┘ ┌───────▼───────┐ │ SQLAlchemy │ │ (SQLite) │ └────────────────┘ ``` `detection.py` 接收事件字典的普通列表,并返回普通的异常字典——没有数据库会话,也没有 FastAPI 请求上下文。`crud.py` 是唯一知道如何获取先前事件的正确时间窗口的地方(针对以账户为中心的规则按用户名获取,针对撞库规则按源 IP 获取),并将规则的输出转换为持久化、去重后的行。这种拆分使得 20 个规则边缘情况能在几毫秒内完成测试,且无需配置任何数据库。 ## 技术栈 | 层级 | 技术 | |--------|-------------| | 后端 | Python 3.11+, FastAPI, SQLAlchemy | | 数据库 | SQLite (基于本地文件,零配置) | | 认证 | 在接收、解决和模拟端点上使用 API 密钥 | | 前端 | React 18, TypeScript, Vite | | 测试 | Pytest — 纯检测规则测试 + 完整 API 测试 | | 容器 | Docker Compose | ## 快速开始 ### 使用 Docker Compose ``` docker-compose up ``` 然后打开 [http://localhost:5176](http://localhost:5176)。后端在首次启动时会植入一个合成场景,以便立即显示所有四种规则类型。 ### 手动安装 **后端** ``` cd backend python -m venv .venv && source .venv/bin/activate # Windows : .venv\Scripts\activate cp .env.example .env pip install -r requirements.txt uvicorn app.main:app --reload --port 8003 ``` **前端** ``` cd frontend npm install npm run dev ``` ### 运行测试 ``` cd backend pip install -r requirements-dev.txt pytest -v ``` `test_detection.py` 通过手动构建的事件序列和固定的时间戳,覆盖了每条规则的触发和非触发条件——没有数据库,没有时钟依赖,不会出现不稳定性。`test_api.py` 对整个技术栈进行了测试,包括断言植入的场景会为每条规则精确生成一个异常(该场景锚定在一天中的固定时间点,而不是实际的挂钟时间,正是为了无论何时运行测试,该断言都是确定性的)。 ## API 参考 | 方法 | 端点 | 认证 | 描述 | |---------|----------|------|--------------| | `GET` | `/api/logs` | — | 最近的原始日志事件 (可选 `?username=&source_ip=&limit=100`) | | `POST` | `/api/logs` | `X-API-Key` | 接收一个事件;立即运行检测并返回任何新的异常 | | `GET` | `/api/anomalies` | — | 列出异常 (可选 `?severity=&resolved=&limit=100`) | | `PATCH` | `/api/anomalies/{id}/resolve` | `X-API-Key` | 将异常标记为已解决 | | `POST` | `/api/simulate` | `X-API-Key` | 重放演示场景 (每条规则一个异常) | | `GET` | `/api/stats` | — | 事件/异常总数、未解决的数量、每条规则的触发计数 | 后端启动后,可在 `/docs` 查看交互式 OpenAPI 文档。 ## 项目结构 ``` . ├── backend/ │ ├── app/ │ │ ├── main.py # Factory de l'app, lifespan (init DB + seed du scénario) │ │ ├── config.py # Configuration │ │ ├── database.py # Moteur/session SQLAlchemy │ │ ├── models.py # LogEventORM, AnomalyORM │ │ ├── schemas.py # Schémas Pydantic │ │ ├── detection.py # Les 4 règles de détection (pures, testées) │ │ ├── crud.py # Fenêtrage, dédup, persistance, orchestration │ │ ├── security.py # Dépendance clé API │ │ ├── seed_data.py # Générateur de scénario de démo déterministe │ │ └── routers/ │ │ ├── logs.py │ │ ├── anomalies.py │ │ ├── simulate.py │ │ └── stats.py │ ├── tests/ │ │ ├── test_detection.py # Tests purs des règles, sans DB, sans dépendance horloge │ │ └── test_api.py │ ├── requirements.txt │ ├── requirements-dev.txt │ ├── .env.example │ └── Dockerfile ├── frontend/ │ └── src/ │ ├── api/client.ts │ ├── hooks/useAnomalies.ts │ └── components/ │ ├── StatsPanel.tsx │ ├── AnomalyTable.tsx │ ├── SimulateControls.tsx │ └── LogFeed.tsx └── docker-compose.yml ``` ## 已知限制 - 检测规则使用固定的阈值(5 次失败、8 个不同用户等),而不是基于每个用户/组织生成自适应基线——真实系统会根据环境调整这些参数,或者使用统计基线 - 没有地理位置查找功能——“国家”是接收事件中的一个字段,而不是从源 IP 推导出来的,因此“不可能旅行”规则信任日志源报告的任何内容 - 24 小时的回溯窗口是一个固定常量;生产系统可能会按规则进行索引和窗口化,而不是在每次接收事件时重新查询主体的完整历史记录 ## 许可证 MIT
标签:AV绕过, FastAPI, React, Syscalls, 异常检测, 红队行动, 网络测绘, 请求拦截, 身份验证安全, 逆向工具