P1rate5ec/floodlight
GitHub: P1rate5ec/floodlight
Floodlight 是一款轻量级防御性异常流量检测工具,基于真实日志时间戳和统计突发检测,帮助小团队在告警响起之前快速发现 DDoS 洪水攻击。
Stars: 0 | Forks: 0
# 🌊 Floodlight
### 用于防御性 DDoS 监控的异常流量速率检测。
     
*洪水不会事先宣告。它只会突然降临。*
Floodlight 替你紧盯水位线,这样你就不必死死盯着数据包计数,直到你的灵魂悄然出窍。
它会根据可调的速率阈值*以及*时间峰值检测器对数据包/请求流量进行评分,将证据存储在 SQLite
中,将其渲染为带有颜色标记的终端报告,并且可以提供一个只读的 Web
仪表板。
它是一个**防御性**工具,适用于你**拥有或获得明确授权进行**
监控的系统。它绝不会生成流量、探测或攻击任何东西——它只会观察并对你指定的目标进行评分。
## 为什么需要它
小团队需要一种轻量级的方法,在*日志变成一团乱麻且警报器响起之前*察觉到洪水。现成的 DDoS 缓解方案通常很笨重,且往往处于 CDN 边缘节点;floodlight 则恰恰相反——它是一个单文件支持的 CLI,你可以在跳板机上针对访问日志运行它,或者在你控制的接口上嗅探一段时间的实时流量,并获得一个直接且可解释的判定结果:
- **谁**在过度通信(首要通信源,按来源的速率)。
- **总计多少**,对比你的基线。
- 流量呈现**什么形态**(半开放 SYN 洪水,突发的时间峰值)。
它的构建目的是为了验证基线、记录事件,并向利益相关者解释异常情况,而无需让他们就着冷掉的咖啡阅读原始的数据包转储。
## 工作原理
```
access log / live interface
│
▼
┌───────────────┐ TrafficEvent(timestamp, src_ip, dst_ip,
│ capture / │──▶ protocol, dst_port, length, flags)
│ parse layer │
└───────────────┘
│ list[TrafficEvent]
▼
┌───────────────┐ detect(events, Thresholds):
│ detector │ • aggregate-rate (total per window)
│ (scoring) │ • source-rate (per source per window)
│ │ • syn-flood (SYN without ACK per source)
│ │ • rate-spike (z-score over the rate series)
└───────────────┘
│ list[DetectionAlert] + report dict
├────────────▶ SQLite store (events + alerts) [store.py]
├────────────▶ rich terminal render / pure JSON [ui.py / cli.py]
└────────────▶ Flask dashboard + /api/summary [app.py]
```
### 检测窗口
所有的评分都在锚定于最新事件的 `--window` 秒滑动**窗口**内进行。在该窗口内,floodlight 会检查:
| 告警类型 | 严重程度 | 触发条件… |
| ---------------- | --------- | ----------- |
| `aggregate-rate` | high | 窗口内的事件总数超过 `--max-total`。 |
| `source-rate` | high | 任何单一来源的事件超过 `--max-per-source`。 |
| `syn-flood` | critical | 某来源发送了超过 `--max-syn-per-source` 的无 ACK 的 SYN 事件(典型的半开放握手特征)。 |
| `rate-spike` | medium | 最繁忙窗口的值高于按窗口速率序列均值 `--spike-sigma` 个标准差,**并且**至少是均值的两倍(统计突发检测——可捕获从未越过绝对上限的急剧峰值)。 |
### 访问日志时间戳(正确性说明)
Floodlight 会解析**真正的 Common/Combined Log Format 时间戳**
(`[20/Jun/2026:13:55:36 +0000]`),因此检测窗口测量的是真实的秒数,
而不是“最后 N 行”。没有可解析时间的行会沿用前一个时间戳;完全没有时间戳的文件会回退到以行号作为秒数,以便该工具仍能执行合理的操作。
### 内置的安全加固
- **授权门槛。** `monitor`(用于嗅探接口)和非环回地址的
`serve` 在没有明确的 `--i-am-authorized` 确认
或 `FLOODLIGHT_AUTHORIZED=1` 的情况下将拒绝运行。
- **恶意输入处理。** 访问日志被视为受攻击者影响的数据:
大小限制(`--max-bytes`,默认 200 MiB)和行数限制(`--max-lines`)
可防止巨大/恶意文件导致服务器 OOM;截断操作会在
stderr 上公布,绝不静默处理。
- **安全的默认设置。** 仪表板绑定到 `127.0.0.1`;进一步向外暴露会受到
门槛限制和警告。响应会携带 `Content-Security-Policy`、
`X-Content-Type-Options`、`X-Frame-Options`、`Referrer-Policy`。
- **无敏感信息,无堆栈跟踪。** 错误会显示为单行可操作的提示。
- **输入验证。** 窗口/阈值必须为正数;错误的值会被
解析器拒绝并附带明确的提示,而不是产生异常行为。
## 安装
```
cd floodlight
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
pip install -e . # provides the `floodlight` entry point
cp .env.example .env # optional: pre-set thresholds / auth
```
实时抓包(`monitor`)还需要 **Scapy** 和操作系统的抓包
权限(Linux 下需要 root / `CAP_NET_RAW`,或者 Windows 下需要带有 Npcap 的提权
shell)。离线模式下的 `analyze-log`、`summary` 和 `serve` 不需要 Scapy 即可工作。
## 用法
全局标志(可在子命令**之前**或**之后**使用):`--db PATH`、
`--plain`、`--no-color`、`--no-banner`。`NO_COLOR` 和非 TTY 输出会被自动
识别。每个输出数据的命令都支持 `--json`,以便提供适用于 `jq`/脚本的
纯净、无样式的 JSON 路径。
**退出码:** `0` = 正常,`2` = 发现告警,`1` = 错误,`3` = 拒绝
(授权),`130` = 中断。
### `analyze-log` — 离线评估访问日志
```
floodlight analyze-log --log /var/log/nginx/access.log
floodlight analyze-log --log access.log --window 60 --max-per-source 500
floodlight analyze-log --log access.log --json | jq '.alerts'
```
示例输出:
```
╭─────────────────────────────────────────────────────────────────╮
│ 🌊 floodlight abnormal traffic-rate detection for authorized … │
╰─────────────────────────────────────────────────────────────────╯
╭─ scan summary ──────────────────────────────────────────────────╮
│ source log:access.log │
│ events 354 (288 in last 10s window) │
│ distinct sources 14 │
│ peak rate 270 events / 10s window │
│ alerts 1 │
╰─────────────────────────────────────────────────────────────────╯
top talkers
source ip events share
198.51.100.9 270 93.8%
203.0.113.3 3 1.0%
…
alerts
severity type source observed threshold detail
HIGH source-rate 198.51.100.9 270 100 / 10s 198.51.100.9 produced 270 events…
```
选项:`--window`, `--max-total`, `--max-per-source`, `--max-syn-per-source`,
`--spike-sigma`, `--max-bytes`, `--max-lines`, `--json`。
### `monitor` — 抓取实时数据包并进行评分
```
sudo FLOODLIGHT_AUTHORIZED=1 floodlight monitor --interface eth0 --duration 30
sudo floodlight monitor --interface eth0 --duration 20 --i-am-authorized --json
```
未经授权将被拒绝(退出码 `3`):
```
Refusing to capture on interface 'eth0' without an explicit authorization acknowledgement.
Floodlight is a DEFENSIVE tool for systems you own or are explicitly authorised to monitor.
Re-run with --i-am-authorized or set FLOODLIGHT_AUTHORIZED=1 to confirm.
```
选项:`--interface`, `--duration`, `--filter` (BPF), 阈值标志,
`--i-am-authorized`, `--json`。
### `summary` — 渲染存储的证据
```
floodlight summary # pretty table of stored events + alerts
floodlight summary --json | jq '.critical_count'
floodlight summary --watch --interval 5 # live-refreshing terminal dashboard
```
`--watch` 使用实时更新视图(按 Ctrl-C 停止)。`--json` 始终输出
纯净的 JSON:`{ "alerts": [...], "event_count", "source_count", "critical_count" }`。
### `serve` — 只读 Web 仪表板
```
floodlight serve # binds 127.0.0.1:5067
floodlight serve --host 0.0.0.0 --port 5067 --i-am-authorized
```
| 方法 | 路径 | 用途 |
| ------ | -------------- | ------------------------------- |
| `GET` | `/` | 告警仪表板(自动刷新)。 |
| `GET` | `/api/summary` | 事件/告警汇总 JSON。 |
绑定到环回地址之外会暴露来源 IP 和告警详情,因此它被置于
`--i-am-authorized` 门槛之后并会发出警告。`--debug` 会启用 Flask 的交互式
调试器(可执行代码)——仅供本地开发使用,floodlight 会对此予以
重点提示。
## 调优
阈值的好坏仅取决于你的基线。首先在一个已知安静的日志上运行 `analyze-log`
以查看正常的单源和总速率,然后在此基础上
留出舒适的余量来设置阈值。注意 **NAT、代理和**
负载均衡器** ——它们会将许多真实的客户端折叠成一个源 IP,这
既可能隐藏分布式的洪水攻击,也可能在繁忙的
出口节点上导致错误的 `source-rate` 告警。所有的阈值也都可以通过 `FLOODLIGHT_*` 环境变量进行设置
(参见 `.env.example`)。
## 开发与测试
```
cd floodlight
PYTHONPATH=src python -m pytest -q
# 直接从源码运行 CLI:
PYTHONPATH=src python -m floodlight.cli --help
PYTHONPATH=src python -m floodlight.cli analyze-log --log access.log
```
测试套件运行快且依赖极少(无网络、无 sleep、无 Scapy):
它涵盖了每个检测器、真实的 CLF 时间戳解析、大小上限、速率峰值
计算、参数验证、JSON 纯净度、退出码以及授权门槛。
### 目录结构
```
floodlight/
src/floodlight/
detector.py # event model, thresholds, detection + log parsing
capture.py # Scapy packet-capture adapter (lazy import)
store.py # SQLite events and alerts
ui.py # shared rich theme, banner, table/panel renderers
cli.py # analyze-log · monitor · summary · serve
app.py # Flask dashboard + JSON summary + security headers
templates/dashboard.html
tests/
```
## 安全 / 授权
Floodlight **仅用于授权的防御性监控**。在接口上抓取
流量会从网络中读取其他方的数据包;仅在你拥有
或有明确书面授权监控的系统上执行此操作。设置 `monitor` 和
非环回地址的 `serve` 门槛是为了让这种确认成为有意为之——
不要在你无法担保的自动化任务中强行绕过它们。
```
---
## 🏷️ 为什么叫 "Floodlight"?
Point a floodlight at the water and you can watch the level rise. Static thresholds only ever catch the flood you thought to predict; the one that takes you down is the one shaped differently than your rule. So this reads real access-log timestamps and adds statistical burst detection on top of the fixed limits — the boring threshold catches the obvious, and the statistics catch the rest.
---
## 🔬 这个工具是如何构建的
> One of ten defensive tools rebuilt to a single standard — *understand, reimagine,
> build the CLI, harden, document, verify*. The goal was never to change what these
> tools **are**, but to take each one as far as it could honestly go on correctness,
> safety and the experience of the person actually running it at 2am.
**Purpose.** A trustworthy, explainable traffic-rate flood detector. It reads real
access-log timestamps (so its window means seconds), adds statistical burst
detection on top of static thresholds, and gates the interface-sniffing and
dashboard behind explicit authorization.
**How it works.** `analyze-log` parses Common/Combined-Log timestamps, buckets
requests into time windows, and flags any window whose per-source rate crosses the
static ceiling *or* spikes statistically. `monitor` does the same over live
capture. Both emit a structured report (events, windowed counts, peak rate, top
talkers, alerts).
**Standout CLI.** A color-coded alerts table, a scan-summary panel, a top-talkers
table with per-source share, `console.status` spinners around parsing/capture, and
a `summary --watch` live-refreshing dashboard via `rich.Live`; global
`--plain`/`--no-color`/`--no-banner` accepted before or after the subcommand.
**Key improvements.** *Functional:* the correctness fix — `parse_access_log` reads
the real CLF timestamp so the window measures **seconds, not line count** (carries
forward on gaps, falls back to index-as-seconds only when a file has no timestamps
at all); a new z-score rate-spike detector (mean + `spike_sigma`×stddev, guarded
by a ≥2× floor) catches sharp bursts that never cross the ceiling; `monitor` gained
`--json` for parity. *Security:* the authorization gate on `monitor` and
non-loopback `serve` (`--i-am-authorized` / `FLOODLIGHT_AUTHORIZED=1`, exit 3);
hostile-input caps on logs (`--max-bytes` default 200 MiB, `--max-lines`, streamed
not slurped, truncation announced on stderr); the standard loopback + header
hardening on the dashboard.
**Example.**
```bash
PYTHONPATH=src python -m floodlight.cli analyze-log \
--log access.log --window 10 --max-per-source 100
```
## ⚖️ 授权使用与安全准则
**这些是针对你拥有所有权或获得明确授权的系统、文件、网络和人员的防御性工具。** 在运行任何程序之前,请阅读以下内容:
- **授权不是可选项。** 钓鱼模拟、网络扫描、IP
信誉查询以及 Web 应用探测都会触及他人的系统或
数据。请先获得书面授权。部分工具在你声明授权之前*拒绝执行任何操作*(`--yes`、`--authorized-training`、`--i-have-authorization`、
`--i-am-authorized` 等)。
- **默认安全。** 每个 Web UI 都绑定到 `127.0.0.1`(环回地址)。出站流量、
实时发送和主动扫描都受到显式标志的控制——试运行、
被动模式或拒绝并警告始终是默认行为。
- **避免意外的危险操作。** Flask `--debug`(Werkzeug 交互式
调试器在任何堆栈跟踪上都具有远程代码执行能力)会被重点警告,并且
在环回地址之外被完全拒绝。不受信任的输入有大小限制、经过验证,
并被无害化渲染,因此恶意的文件或日志行无法导致你的终端崩溃——或被接管。
- **输出中不包含敏感信息。** API key 保留在请求头中,password 来自
环境变量,并且不会记录或打印任何敏感信息。
这些不是攻击性工具。它们不包含任何漏洞利用代码、不包含凭证
收集器、也不包含任何 payload。如果某个工具*可能*被滥用,其构造机制本身就是为了抵抗这种滥用而设计的。
## 🧪 开发
```
python -m venv .venv && source .venv/bin/activate
pip install -e .
pytest -q # 20 tests, no network, no sleeps
floodlight --help
```
## 📄 许可证
基于 **MIT License** 发布。参见 [LICENSE](LICENSE)。
防御性工具。无漏洞利用代码,无 payload,无凭证收集器。
标签:DDoS检测, Python, 动态分析, 无后门, 流量监控, 逆向工具