Nabil201-ctrl/log-pulse
GitHub: Nabil201-ctrl/log-pulse
一个用 Bash 和 Python 构建的轻量日志分析工具,从 SSH 认证日志中提取失败登录记录并按 IP 识别凭据爆破和撞库行为。
Stars: 0 | Forks: 0
# log-pulse
每次服务器看起来有些异常时,我都要手动去 grep `auth.log`,我已经厌倦了这样做。这是一个微型 pipeline,可以从日志转储中提取失败的 SSH 尝试记录,并告诉我哪些 IP 是在真正地 spray 凭据,而哪些只是因为有人不小心输错了一两次密码。
**技术栈:** 使用 Bash 进行收集,使用 Python 进行解析和评分。
## 它的功能
1. Shell 脚本会抓取看起来像 auth 事件的行(或者如果你在服务器上没有 root 权限,它会保留样本文件)。
2. Python 将每一行转换为结构化事件:时间、主机、用户、IP、失败/成功。
3. 失败记录会按源 IP 进行分组。
4. 如果某个 IP 的记录超过了阈值,它将生成一个带有严重级别的警报。
就这样。没有 agent,没有花哨的模型——只有计数和一些我能够解释清楚的阈值。
## 评分机制是如何工作的
我故意让这部分保持简单。
| 信号 | 我关注的原因 |
|--------|------------|
| 单个 IP 的失败次数 | Brute force / bot |
| 尝试的不同用户名数量 | Credential spray (admin、root、ubuntu、oracle…) |
| 两者的结合 | 通常比单个用户重复尝试更严重 |
默认规则:
- 失败次数低于 3 次 → 忽略
- 失败 3 到 7 次左右且用户数较少 → 低/中级别
- 大量失败 **或** 尝试了许多不同的用户名 → 高级别
输错一次密码是人为失误。而同一个 IP 尝试六个用户名则绝非偶然。
## 流程
```
flowchart TD
A[auth.log or sample dump] --> B[collect_auth.sh]
B --> C{Readable system log?}
C -->|yes| D[grep fail/accept lines]
C -->|no| E[keep sample_data]
D --> F[auth_events.log]
E --> F
F --> G[parser.py]
G --> H[AuthEvent list]
H --> I[detector.py]
I --> J{fails per IP >= min?}
J -->|no| K[quiet]
J -->|yes| L[severity + reason]
L --> M[CLI text or JSON]
```
## 仓库结构
```
log-pulse/
scripts/collect_auth.sh
src/
parser.py
detector.py
main.py
sample_data/auth_events.log
tests/
```
## 我的构建过程(大致顺序)
1. 针对类似真实的 sshd 日志行编写了一些正则表达式,直到解析不再报错。
2. 将事件转储到一个列表中,并在 notebook 风格的脚本中按 IP 统计失败次数,然后将其移至 `detector.py`。
3. 在我发现“同一个用户失败 5 次”和“7 个用户失败 5 次”是截然不同的情况后,添加了严重级别。
4. 使用 `--json` 将其封装为 CLI,以便我以后需要时可以通过管道处理。
5. 最后编写 Bash 收集器——因为在 Python 端能够处理静态文件之后才进行这一步。
## 运行它
```
git clone https://github.com/Nabil201-ctrl/log-pulse.git
cd log-pulse
# 可选:尝试 live logs(需要对 /var/log/auth.log 或 secure 的读取权限)
chmod +x scripts/collect_auth.sh
./scripts/collect_auth.sh sample_data
python3 src/main.py
python3 src/main.py -i sample_data/auth_events.log --json
```
快速检查:
```
python3 -c "
import sys
from pathlib import Path
sys.path.insert(0, str(Path('src').resolve()))
sys.path.insert(0, str(Path('tests').resolve()))
from test_detector import test_parse_fail, test_spike_flags_noisy_ip
test_parse_fail(); test_spike_flags_noisy_ip()
print('ok')
"
```
## 示例输出
```
parsed 22 auth events from sample_data/auth_events.log
2 alert(s):
[HIGH ] 45.33.32.156
fails=9 users=admin, ftp, guest, mysql, pi, root, user
9 failed attempts across 7 username(s) — looks like credential spray or a noisy bot
```
## 以后可能会添加的内容
- 滑动时间窗口,而不是对整个文件进行统计
- 对源 IP 进行 GeoIP 解析
- Webhook / 将命中记录写入 sqlite
如果你刚刚开始学习日志分析,在接触更庞大的工具之前,请从这里开始。
标签:Bash, Python, SSH, 免杀技术, 安全运营, 应用安全, 扫描框架, 文档结构分析, 无后门, 暴力破解检测, 逆向工具