mobinert/ssh-fortress
GitHub: mobinert/ssh-fortress
一个模块化的 SSH 安全加固框架,集成暴力破解防护、行为威胁评分、SIEM 集成与多通道告警,用于全面保护 Linux 服务器的 SSH 访问安全。
Stars: 0 | Forks: 0
## 什么是 SSH Fortress?
SSH Fortress 是一个**可用于生产环境的 SSH 安全框架**,它集成了通常需要 3-4 个独立工具才能完成的所有功能:
- 自动将你的 SSH daemon 加固至 **CIS Level 2 / NSA** 标准
- 在暴力破解攻击者耗尽你的身份验证尝试**之前**检测并封禁他们
- 使用**行为威胁引擎**对每个源 IP 进行评分,并自适应地进行封禁 🆕
- 将每个 SSH 事件转发到你的 **SIEM**(Elasticsearch、Splunk、Syslog、Kafka)
- 通过 **Telegram、Email、Discord、Slack 或 ntfy** 即时向你发送警报 🆕
- 为 Grafana / Alertmanager 暴露 **Prometheus metrics** 🆕
- 按需生成设计精美的 **HTML / JSON 安全报告** 🆕
- 检测**异常行为** —— 不可能完成的旅行、IP 扫射、异常登录时间、root 尝试
- **审计你的 SSH 密钥**,查找弱、旧或重复的条目
- 根据 **AbuseIPDB** 检查传入 IP,并预先封禁已知的攻击者
- 在你依赖配置之前**验证你的配置** (`doctor`) 🆕
一切都是模块化的 —— 只需启用你需要的功能,所有配置均可通过单个 YAML 文件完成。
## 功能
### 🔒 SSH 加固
- 将 `/etc/ssh/sshd_config` 重写为 CIS Benchmark Level 2 + NSA SSH 安全指南标准
- 使用 `sshd -t` 进行验证,失败时自动回滚 —— 零停机风险
- 移除弱主机密钥(DSA、ECDSA),并重新生成 Ed25519 + RSA-4096
- 清除小于 3072 位的 DH moduli
- 仅使用强加密策略:仅限 ChaCha20、AES-256-GCM、ETM MACs
- 使用 `pam_faillock` 账户锁定配置 PAM
- 每次更改前进行完整备份
### 🚫 暴力破解防护
- **每个事件 O(1) 决策** —— 进程内 hash map,在热路径上完全不触及磁盘
- 渐进式封禁:每次重复违规封禁时间加倍(1h → 2h → 4h → ... → 最长 24h)
- 将封禁同步到 **nftables kernel set**,实现零开销的 packet 丢弃
- 可选的 **fail2ban** 集成,提供额外的冗余
- 通过 IP 或 CIDR 设置白名单
- 通过 CLI 手动执行 `ban` / `unban`
### 🧠 行为威胁评分(自适应封禁) 🆕
暴力破解防护仅提出一个简单的是/否问题(“此 IP 是否超过了 N 次失败?”),而威胁评分器会为每个源 IP 建立**行为画像**,并将加权信号融合为一个 **0–100 的风险分数**:
| 信号 | 捕获内容 | 最大权重 |
|---|---|---|
| 失败速度 | 快速且反复的失败 | 40 |
| 用户名扫射 | 同一 IP 尝试大量*不同*的用户名 | 30 |
| 无效用户探测 | 针对不存在用户的攻击 | 24 |
| 针对 root | 任何针对 `root` 的尝试 | 30 |
| 信誉度 | 被 AbuseIPDB 标记 | 50 |
| 非工作时间活动 | 工作时间之外的连接 | 6 |
| 已知良好信用折扣 | 该 IP 之前已成功通过身份验证 | −40 |
- **自适应封禁:** 一种缓慢、分布式的扫射,即使从未触发原始失败计数器,一旦其行为越过阈值(默认为 70),也会被封禁。
- 每个权重都可在 `settings.yaml` 中配置;分数会在滚动时间窗口内衰减。
- 判定级别:`LOW → SUSPICIOUS → HIGH → CRITICAL`。
### 🔥 速率限制
- **nftables**(首选)或 **iptables** 后端
- 带有突发缓冲的基于 IP 的新连接速率上限
- SYN flood 防护 + SYN cookies
- 内核级丢弃 —— 没有针对每个 packet 的用户空间开销
### 🌍 地理位置封锁
- 集成 MaxMind GeoLite2-Country
- 允许列表模式(仅列出的国家可以连接)或阻止列表模式
- 私有 IP 始终绕过地理检查
### 🚪 端口敲门
- 可选的 TCP/UDP 敲门序列 —— 完全隐藏 SSH 端口
- 仅针对完成序列的特定 IP 开放 SSH
- 在可配置的超时时间后自动关闭
### 📡 SIEM 集成(5 种后端)
| 后端 | 协议 | 格式 |
|---|---|---|
| Elasticsearch | HTTPS bulk API | ECS JSON |
| Splunk | HEC (HTTP Event Collector) | JSON |
| Syslog | UDP / TCP / TLS | CEF · RFC5424 · JSON |
| Apache Kafka | SASL / SSL | JSON |
| Webhook | HTTP POST | JSON |
### 🔔 警报通道
| 通道 | 触发条件 |
|---|---|
| **Telegram** | 登录成功、暴力破解封禁、root 尝试、异常、登录失败 |
| **Email** | 登录成功、暴力破解封禁、root 尝试、异常、每日摘要 |
| **Discord** | 登录成功、暴力破解封禁、root 尝试、异常 |
| **ntfy** 🆕 | 任何事件 —— 即时推送到 ntfy 应用,无需机器人/账户 |
| **Slack** | 所有安全事件 |
| **PagerDuty** | 严重事件 |
| **Webhook** | 所有事件 |
特性:
- 每个通道独立的冷却时间(不会在凌晨 3 点轰炸你的手机)
- 可配置的静音时间 (Telegram)
- 精美的 **HTML 电子邮件模板**,带有彩色标题
- Discord **rich embeds**,带有彩色侧边栏
- **每日摘要电子邮件**(在你选定的时间定时发送)
### 📊 异常检测
| 异常 | 触发条件 |
|---|---|
| IP 扫射 | 60 秒内出现 > 20 个唯一 IP |
| 异常时间 | 在 08:00–18:00 之外登录 |
| 不可能完成的旅行 | 同一用户在 1 小时内从 2 个或更多国家登录 |
| 身份验证失败激增 | 每分钟失败 > 10 次 |
| Root 尝试 | 任何 `root` 登录尝试 |
### 🔑 SSH 密钥审计
- 扫描所有系统用户的所有 `authorized_keys` 文件
- 标记:DSA 密钥(已损坏)、RSA < 4096 位、ECDSA < 521 位
- 检测在多个账户中重复使用的密钥
- 可选的自动吊销不合规的密钥
- 通过 systemd timer 进行每日审计
### 🌐 IP 信誉 (AbuseIPDB)
- 在进行任何身份验证尝试之前,根据 AbuseIPDB 检查连接的 IP
- 预先封禁置信度分数高于阈值的 IP(默认值:80)
- 24 小时内存缓存 —— 不会对同一 IP 重复调用 API
- 在 [abuseipdb.com](https://www.abuseipdb.com) 获取免费 API key
### 📈 统计追踪器
- 计数:总尝试次数、成功、失败、封禁、root 尝试、异常
- 每个 IP 的详细信息:失败次数、封禁次数、首次/最后一次出现的时间
- Top 攻击者列表
- Session 峰值追踪
- 每 30 秒持久化一次到 JSON
### 📟 Prometheus 指标 🆕
- 零依赖的 `/metrics` endpoint(仅使用标准库 —— 无需 push gateway)
- Counters + gauges:尝试、成功、失败、封禁、root 尝试、异常、活跃/峰值 sessions
- 基于 IP 标记的序列:`ssh_fortress_attacker_failures{ip=…}` 和 `ssh_fortress_threat_score{ip=…}`
- 可直接接入 Grafana / Alertmanager:`sudo python main.py metrics`
### 📄 安全报告 🆕
- `sudo python main.py report` —— 在终端中显示摘要表
- `--html` —— 设计精美、独立的 HTML 报告(可打开/发送邮件/提交)
- `--json` —— 适用于 pipeline 的机器可读报告
- 基于持久化的统计数据构建:Top 攻击者、封禁次数、失败率、异常
### 🩺 配置检查 (Doctor) 🆕
- `sudo python main.py doctor` 在你依赖它之前验证 `settings.yaml`
- 捕获:启用但无凭证的通道、无 endpoint 的 SIEM 后端、超出范围的阈值、不是有效端口的绑定端口
- 遇到任何阻塞性错误时以非零状态退出 —— 可安全接入 CI / 部署前检查
## 快速开始
### 要求
- Python 3.10+
- Linux (Ubuntu 22.04+, Debian 12+, RHEL 8/9, Rocky 8/9, AlmaLinux 8/9)
- Root 权限
- nftables 或 iptables
- 可选:fail2ban, MaxMind GeoLite2 DB
### 安装
```
git clone https://github.com/mobinert/ssh-fortress.git
cd ssh-fortress
sudo bash scripts/install.sh
```
安装程序将会:
1. 安装系统依赖(Python、nftables、fail2ban、rsyslog)
2. 创建一个包含所有必需包的 Python virtualenv
3. 将配置复制到 `/etc/ssh-fortress/settings.yaml`
4. 安装并启动 systemd 服务
5. 应用初始加固
### 配置
```
sudo nano /etc/ssh-fortress/settings.yaml
```
需要配置的关键设置:
```
# Telegram 警报
alerting:
telegram:
enabled: true
bot_token: "1234567890:ABCdef..." # from @BotFather
chat_id: "123456789" # from @userinfobot
# 电子邮件警报
email:
enabled: true
smtp_host: smtp.gmail.com
smtp_port: 587
username: "you@gmail.com"
password: "your-app-password" # Gmail: use App Password
from_addr: "you@gmail.com"
to_addrs:
- "you@gmail.com"
# AbuseIPDB 信誉检查
ip_reputation:
enabled: true
abuseipdb_api_key: "your-key-here"
# SIEM — Elasticsearch
siem:
backends:
elasticsearch:
enabled: true
hosts:
- "https://your-elastic:9200"
api_key: "your-api-key"
```
### 启动
```
sudo systemctl restart ssh-fortress
sudo systemctl status ssh-fortress
```
## CLI 参考
```
# 应用加固(首先使用 --dry-run 预览)
sudo python main.py harden --dry-run
sudo python main.py harden
# 启动 daemon(监控 + 暴力破解 + SIEM + 警报)
sudo python main.py run
# 当前 sshd_config 的 CIS 合规审计
sudo python main.py audit
# 验证 settings.yaml(配置错误的频道、SIEM、阈值)
sudo python main.py doctor
# 实时状态(健康状态 + 活动会话)
sudo python main.py status
# 事件统计 + 头部攻击者
sudo python main.py stats
# 安全报告 — 终端,或导出
sudo python main.py report
sudo python main.py report --html -o report.html
sudo python main.py report --json -o report.json
# Prometheus 指标 exporter(抓取 /metrics)
sudo python main.py metrics
# 手动 IP 管理
sudo python main.py ban 1.2.3.4 --duration 86400
sudo python main.py unban 1.2.3.4
# SSH 密钥审计
sudo python main.py keys audit
# 测试您的通知频道
sudo python main.py test telegram
sudo python main.py test email
sudo python main.py test ntfy
# 版本
python main.py --version
```
## 项目结构
```
ssh-fortress/
├── main.py # CLI + daemon wiring
├── requirements.txt
├── setup.py
│
├── config/
│ ├── settings.yaml # Central config — all modules read this
│ ├── sshd_config.hardened # Hardened sshd_config reference
│ ├── fail2ban/
│ │ ├── jail.local # fail2ban jail with progressive banning
│ │ └── sshd-fortress.conf # Custom filter (covers all fail patterns)
│ └── siem/
│ ├── filebeat.yml # Filebeat config for Elastic stack
│ ├── logstash-ssh.conf # Logstash pipeline (parse + enrich + route)
│ └── rsyslog-siem.conf # rsyslog: JSON local log + CEF remote forward
│
├── modules/
│ ├── core/
│ │ ├── config_manager.py # YAML loader, dotted-key access, template vars
│ │ ├── logger.py # Structured JSON logger, coloured console
│ │ └── config_validator.py # settings.yaml pre-flight checks (doctor) 🆕
│ │
│ ├── hardening/
│ │ ├── ssh_config.py # sshd_config writer + CIS auditor
│ │ ├── crypto_policy.py # Host key management + moduli cleanup
│ │ └── pam_config.py # PAM faillock + optional 2FA
│ │
│ ├── protection/
│ │ ├── brute_force.py # In-process tracker, progressive banning
│ │ ├── rate_limiter.py # nftables/iptables rate limit + SYN flood
│ │ ├── geo_blocker.py # MaxMind country allow/block list
│ │ ├── port_knocker.py # TCP/UDP knock sequence daemon
│ │ ├── ip_reputation.py # AbuseIPDB pre-ban check
│ │ └── threat_scorer.py # behavioural 0-100 risk score (adaptive ban) 🆕
│ │
│ ├── logging/
│ │ ├── log_parser.py # Pure-regex auth.log parser → SSHEvent
│ │ ├── log_aggregator.py # inotify/poll log tail, handler fan-out
│ │ └── siem_forwarder.py # 5 SIEM backends (ES/Splunk/Syslog/Kafka/Webhook)
│ │
│ ├── monitoring/
│ │ ├── session_monitor.py # Live session tracking → sessions.json
│ │ ├── anomaly_detector.py # IP spray, travel, hours, spikes, root
│ │ ├── health_checker.py # sshd / nftables / fail2ban / disk / SIEM health
│ │ └── metrics_exporter.py # Prometheus /metrics endpoint 🆕
│ │
│ ├── alerting/
│ │ ├── alert_manager.py # Rate-limited Slack/PagerDuty/Webhook routing
│ │ ├── telegram_notifier.py # Telegram Bot API (async queue, silent hours)
│ │ ├── email_notifier.py # HTML email (login/ban/anomaly/daily digest)
│ │ ├── discord_notifier.py # Discord webhook with rich embeds
│ │ └── ntfy_notifier.py # ntfy.sh push notifications 🆕
│ │
│ ├── key_management/
│ │ └── key_auditor.py # authorized_keys scanner (weak/old/dup keys)
│ │
│ ├── stats/
│ │ └── stats_tracker.py # Event counters, top attackers, daily reset
│ │
│ └── reporting/ # 🆕
│ └── html_report.py # HTML + JSON security report builders
│
├── tests/ # unit tests (pytest — 37 tests) 🆕
├── conftest.py
├── pytest.ini
│
├── scripts/
│ ├── install.sh # Full install (Ubuntu/Debian/RHEL/Rocky)
│ ├── setup_2fa.sh # Google Authenticator TOTP per-user setup
│ └── rotate_keys.sh # Ed25519 key rotation helper
│
└── systemd/
├── ssh-fortress.service # Systemd service (hardened, resource-limited)
└── ssh-fortress-monitor.timer # Daily key audit timer
```
## 架构
```
/var/log/auth.log
│
▼
┌──────────────────────────────────────┐
│ LogAggregator (inotify/poll) │
│ LogParser → SSHEvent (typed) │
└──────────────┬───────────────────────┘
│ SSHEvent
▼
┌──────────────────────────────────────────────────────────────┐
│ Handler Fan-out │
│ │
│ BruteForceProtector ──→ nftables banned_ips set │
│ │ fail2ban (optional) │
│ ▼ │
│ AlertRouter │
│ ├── TelegramNotifier ──→ Telegram Bot │
│ ├── EmailNotifier ──→ SMTP (HTML emails) │
│ ├── DiscordNotifier ──→ Discord Webhook │
│ ├── AlertManager ──→ Slack / PagerDuty / Webhook │
│ └── StatsTracker ──→ stats.json │
│ │
│ SIEMForwarder │
│ ├── Elasticsearch (bulk API, batched) │
│ ├── Splunk HEC (batched) │
│ ├── Syslog (CEF / RFC5424 / JSON) │
│ ├── Kafka (batched, async) │
│ └── Webhook (JSON POST) │
│ │
│ SessionMonitor ──→ sessions.json │
│ AnomalyDetector ──→ AlertRouter │
│ IPReputationChecker ──→ AbuseIPDB API (cached 24h) │
└──────────────────────────────────────────────────────────────┘
```
## Telegram 设置(分步指南)
1. 打开 Telegram,搜索 **@BotFather**
2. 发送 `/newbot` 并按照说明操作
3. 复制 **bot token**(类似于 `1234567890:ABCdefGHI...`)
4. 搜索 **@userinfobot**,发送 `/start` —— 它会显示你的 **chat_id**
5. 编辑 `settings.yaml`:
```
alerting:
telegram:
enabled: true
bot_token: "YOUR_BOT_TOKEN_HERE"
chat_id: "YOUR_CHAT_ID_HERE"
```
6. 测试一下:
```
sudo python main.py test telegram
```
你会立即在 Telegram 中收到一条消息。
## Email 设置(以 Gmail 为例)
1. 在你的 Google 账户上启用 2FA
2. 转到 **Google Account → Security → App passwords**
3. 为“Mail”生成一个 App Password
4. 编辑 `settings.yaml`:
```
alerting:
email:
enabled: true
smtp_host: smtp.gmail.com
smtp_port: 587
use_tls: true
username: "you@gmail.com"
password: "xxxx xxxx xxxx xxxx" # App Password (spaces OK)
from_addr: "you@gmail.com"
to_addrs:
- "you@gmail.com"
daily_report: true
daily_report_hour: 8
```
5. 测试:
```
sudo python main.py test email
```
## 加固的 sshd_config(自动应用)
| 设置 | 值 | 原因 |
|---|---|---|
| `PermitRootLogin` | `no` | 禁止直接使用 root SSH |
| `PasswordAuthentication` | `no` | 仅允许密钥 |
| `MaxAuthTries` | `3` | 限制每次连接的尝试次数 |
| `LoginGraceTime` | `30` | 30秒内完成身份验证 |
| `X11Forwarding` | `no` | 减少攻击面 |
| `AllowTcpForwarding` | `no` | 防止隧道穿透 |
| `Compression` | `no` | CVE 历史漏洞 (CRIME-like) |
| `LogLevel` | `VERBOSE` | 完整的密钥指纹记录 |
| `Ciphers` | 仅限 ChaCha20, AES-GCM | 无 CBC,无 RC4 |
| `MACs` | 仅限 ETM | 无 encrypt-and-MAC |
| `KexAlgorithms` | 仅限 Curve25519, DH-SHA512 | 无 RSA KEX |
## 常见问题
**问:SSH Fortress 会把我锁在外面吗?**
答:不会。它在应用任何配置更改之前都会使用 `sshd -t` 进行验证,并在失败时自动回滚。在关闭现有 session 之前,请务必在新的终端中进行测试。
**问:我需要 Elasticsearch/Splunk 吗?**
答:不需要。所有的 SIEM 后端都是可选的。Syslog 后端作为兜底方案始终处于开启状态。Telegram 和 Email 完全独立运行。
**问:它可以在容器/虚拟机上运行吗?**
答:可以,但在容器中,nftables 可能需要 `NET_ADMIN` capability。暴力破解防护模块可在任何地方运行。
**问:性能影响如何?**
答:几乎为零。基于 inotify 的日志追踪在空闲时占用 0% CPU。暴力破解决策复杂度为 O(1)。EM 转发是带有 backpressure queues 的异步操作。该服务在 systemd unit 中被限制为最高 20% CPU / 256 MB RAM。
## 作者的更多工具
| 工具 | 平台 | 功能 |
|------|----------|--------------|
| [**HORUS**](https://github.com/mobinert/HORUS) | Windows | 一个零依赖的执行文件内集成 IOC 富化 + PE 静态分析 |
| [**machunt**](https://github.com/mobinert/machunt) | macOS | 只读的威胁狩猎与 compromises 评估 —— 包含 20 个模块 |
## 许可证
MIT License —— 详情请参阅 [LICENSE](LICENSE)。
标签:osquery, Python, SIEM集成, SSH加固, 威胁情报, 开发者工具, 无后门, 暴力破解防护, 自定义请求头, 运维安全