mobinert/ssh-fortress

GitHub: mobinert/ssh-fortress

一个模块化的 SSH 安全加固框架,集成暴力破解防护、行为威胁评分、SIEM 集成与多通道告警,用于全面保护 Linux 服务器的 SSH 访问安全。

Stars: 0 | Forks: 0

🛡️ SSH Fortress

高级模块化 SSH 加固、暴力破解防护及 SIEM 集成

## 什么是 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)。
Mobin Erteghaie 构建
标签:osquery, Python, SIEM集成, SSH加固, 威胁情报, 开发者工具, 无后门, 暴力破解防护, 自定义请求头, 运维安全