web3-ai-game/oece-x-blue-sh

GitHub: web3-ai-game/oece-x-blue-sh

一款单文件 Bash 编写的 VPS 蓝队安全加固面板,提供从加固评分到蜜罐、监控和应急响应的完整防御闭环,所有变更均可回滚。

Stars: 0 | Forks: 0

MIT Bash ShellCheck Version 32 checks single file

Stars Forks Issues Last commit code size

Debian Ubuntu RHEL OpenSSH arch zh-TW bilingual

score rollback honeypot tarpit crowdsec docker ioc no telemetry

YouTube Telegram Website sister


**简体中文界面 · 单文件可审计 · 只读优先 · 全变更可逆 · 危险操作需完整输入 `yes`**
### 🔗 姊妹项目 / Sister Project | 项目 | 回答的问题 | 短命令 | |:-----|:-----------|:-------| | [**oece-x.sh**](https://github.com/web3-ai-game/oece-x-sh) | 这台机器**值不值**? | `bash <(curl -sL oece-x.com/x)` | | **oece-x-blue.sh** ← 你在这里 | 这台机器**守不守得住**? | `bash <(curl -sL oece-x.com/b)` |
## ⚡ 快速开始 / Quick Start
| 方式 / Method | 命令 / Command | |:----:|:-----| | 🌐 **官网一键** | `bash <(curl -sL oece-x.com/b)` | | 🐙 **GitHub raw** | `bash <(curl -sSL https://raw.githubusercontent.com/web3-ai-game/oece-x-blue-sh/main/oece-x-blue.sh)` | | 📊 **只跑评分** | `bash oece-x-blue.sh --audit` | | 📡 **直接进面板** | `bash oece-x-blue.sh --panel` | | 🔇 **跳过动画** | `OECE_NO_ANIM=1 bash <(curl -sL oece-x.com/b)` |
``` # 推薦 / Recommended bash <(curl -sL oece-x.com/b) ``` ## 💡 为什么需要这个 / Why This Exists
**大多数 VPS 教程停在“改个 SSH 端口、装个 fail2ban”就结束了。** *Most VPS tutorials stop at "change the SSH port, install fail2ban."*
真正的蓝队工作是一个闭环,而且有一个所有教程都轻描淡写的风险: ``` flowchart LR A["👁️ 看得見
Visibility"] --> B["🛡️ 守得住
Hardening"] B --> C["🪤 有陷阱
Deception"] C --> D["🔔 有告警
Alerting"] D --> E["🔍 查得清
Forensics"] E --> A style A fill:#0EA5E9,color:#fff,stroke:none style B fill:#8B5CF6,color:#fff,stroke:none style C fill:#F59E0B,color:#fff,stroke:none style D fill:#10B981,color:#fff,stroke:none style E fill:#EF4444,color:#fff,stroke:none ```
### ⚠️ 加固 SSH 最大的风险不是被入侵,是把自己关在门外 ### *SSH 加固的头号风险不是入侵——而是把自己锁定在外*
一个“一键加固”脚本如果没有逃生机制,就是一键自杀。所以本项目的**第一个**功能不是加固,而是防锁门: ``` flowchart TD S["開始加固
Start"] --> P{"preflight
留存帳戶真的有可用公鑰?
Valid pubkey exists?"} P -->|"❌ 沒有 / None"| R["拒絕執行
Refuse — no lockout possible"] P -->|"✅ 有 / Yes"| BK["備份設定
Backup to /var/backups/oece-x/"] BK --> T["⏱️ 排定 N 分鐘後自動還原
Arm auto-rollback timer"] T --> AP["套用變更 + sshd -t 驗證
Apply + validate"] AP --> U{"你另開終端登入
並執行 xb --confirm ?"} U -->|"✅ 有 / Confirmed"| OK["取消定時器 · 寫入 manifest
Timer cancelled"] U -->|"❌ 沒有 / Timeout"| RB["⏮️ 自動還原到加固前
Auto-restored"] style R fill:#EF4444,color:#fff,stroke:none style OK fill:#10B981,color:#fff,stroke:none style RB fill:#F59E0B,color:#fff,stroke:none style T fill:#0EA5E9,color:#fff,stroke:none ``` **没登上去 = 没确认 = 自动还原。** 这是整个脚本最重要的设计。 *Didn't get back in? Then you never confirmed, and it rolls itself back.* ## 📸 界面预览 / UI Preview ### 蓝队态势面板 · Live Threat Panel 实测输出,来自一台全新的 DigitalOcean Debian 13 机器: *Real output from a freshly provisioned DigitalOcean Debian 13 droplet:* ``` ╔══════════════════════════════════════════════════════════════╗ ║ OECE-X BLUE · 藍隊態勢面板 07-23 12:38 oece-blue-testbo ║ ╚══════════════════════════════════════════════════════════════╝ 加固評分 ▊▊▊▊▊▊▊▊▊▊▊░░░░░░░░░ 56/100 偏弱 ──────────────────────────────────────────────────────── 防火牆 iptables open 入侵防禦 未安裝 24h 失敗登入 34 蜜罐命中 39 root 30 / admin 9 Top 攻擊源 45.61.188.7 (24 次) 194.26.29.3 (9 次) 162.214.22.174 (1 次) ──────────────────────────────────────────────────────── 當前會話 root@27.34.111.135 監聽埠 5355(systemd-resolve) 22(sshd) 25(exim4) 53(systemd-resolve) 安全更新 4 個待裝 重啟需求 否 負載 / 磁碟 1.73, 0.60, 0.22 5% 已用 / 25G ──────────────────────────────────────────────────────── [r] 重新整理 [w] 每 10 秒自動刷新 [a] 完整評分明細 [Enter] 返回 ``` ### 加固评分体检 · Hardening Audit ``` ── 身份與存取 ── ✘ root SSH 登入 允許 root 直接登入 ↳ 修復:選單 10 · root 蜜罐 ✔ 密碼認證 已關閉,僅金鑰登入 ✔ 空密碼登入 已禁止 ✔ uid=0 帳戶 僅 root(正常) ✔ 空密碼帳戶 無 ▲ sudo 免密規則 1 條 NOPASSWD(雲鏡像常見預設,確認是你要的) ✔ 公鑰盤點 共 1 把:root:1 — 逐一確認都是你自己的 ▲ MaxAuthTries 6(建議 ≤3) ▲ LoginGraceTime 120s(建議 20-30s,降低半開連線耗用) ── 內核與掛載 ── ✘ 網路層 sysctl 4 項未達標:rp_filter accept_redirects send_redirects log_martians ✘ /dev/shm 掛載 缺 noexec/nosuid — 攻擊者常在此落地執行檔 ── 完整性 ── ✔ ld.so.preload 空或不存在(正常) ✔ 已刪除二進制進程 無 ▲ SUID 檔案 12 個,已建立首次基線(下次即可比對變化) ──────────────────────────────────────────────────────── 加固評分 ▊▊▊▊▊▊▊▊▊▊▊░░░░░░░░░ 57/100 · 偏弱 得分 110 / 滿分 191(不適用項目已排除在分母外) ──────────────────────────────────────────────────────── ```
**一台刚开机、你什么都还没做的 VPS —— 57 分。** *A brand-new VPS you haven't touched yet: 57/100.*
## 🧰 功能总览 / Feature Matrix | # | 模块 ZH | EN | 说明 | 状态 | |:-:|:--------|:---|:-----|:----:| | **1** | **蓝队面板** ★ | Live panel | 评分趋势 · 封禁 · Top 攻击源 · 蜜罐命中 · 10s 自动刷新 | ✅ | | **2** | **加固评分体检** ★ | Hardening score | 32 项只读检查 · 6 组 · 附修复指引 | ✅ | | 3 | Lynis 深度审计 | Third-party audit | 业界标准工具的独立第二意见 | ✅ | | **4** | **一键加固 · 基础** ★ | Harden: basic | 补丁 · sysctl · 挂载选项(**零锁门风险**) | 🚧 | | **5** | **一键加固 · 标准** ★★ | Harden: standard | SSH 收紧 · 防火墙 · 入侵防御(挂自动回滚) | 🚧 | | 6 | 一键加固 · 硬核 | Harden: hardcore | 管理员换人 · root 蜜罐 · 改端口 | 🚧 | | 7 | 逐项加固 | Cherry-pick | 手动挑选单项 | 🚧 | | **8** | **CrowdSec** ★ | Community IPS | 社群威胁情报(**共享预设关闭**) | 📋 | | 9 | fail2ban | Lightweight IPS | 轻量封禁,适合 <512MB | 📋 | | **10** | **root 蜜罐** ★ | Root honeypot | 诱饵帐户 · 诱饵用户名秒封 · 本地命中统计 | 📋 | | **11** | **endlessh 焦油坑** ★ | SSH tarpit | 22 埠每 10s 吐一字符,把扫描器挂住数小时 | 📋 | | **12** | **防火墙** ★ | Firewall | UFW + **Docker 绕过修复** + Cloudflare-only 入口 | 📋 | | 13 | 告警通道配置 | Alert channels | Telegram / 邮件(`/etc/oece-x/blue.env`) | 📋 | | **14** | **登入即时告警** ★ | Login alerts | PAM 钩子,登入成功 1 秒推送 | 📋 | | 15 | 每日巡检报告 | Daily report | cron 日报 + **配置漂移侦测** | 📋 | | **16** | **IOC 快检** ★ | IOC scan | 入侵指标扫描(只读) | 📋 | | 17 | 一键取证包 | Forensics bundle | 打包全部证据 + REPORT.md | 📋 | | 18 | 封禁 / 解封 / 踢人 | Ban & kick | IP 黑名单 + 强制下线 | 📋 | | **19** | **紧急锁定** ★ | Emergency lockdown | 只放行当前 IP,其余全封 | 📋 | | 20 | 回滚与还原 | Rollback | 逐项撤销 / 全部还原 | 🚧 | | 21 | 检查更新 | Self-update | 对比远程版本 | 📋 |
1-3 4-7 8-12 13-15 16-19
## 📊 评分规则 / Scoring Rubric 32 项检查分 6 组。`PASS` 得满分、`WARN` 得半分、`FAIL` 得 0 分, **`SKIP` 不计入分母** —— “本机没装 Docker”不该拉低你的分数。 *32 checks across 6 groups. `SKIP` items are excluded from the denominator — not running Docker shouldn't cost you points.* | 组 / Group | 检查项 / Checks | |:-----------|:----------------| | **身份与访问**
*Identity & Access* | root SSH 登入 · 密码认证 · 空密码登入 · uid=0 帐户 · 空密码帐户 · sudo 免密 · **全系统公钥盘点** · MaxAuthTries · LoginGraceTime | | **网络暴露**
*Network Exposure* | 防火墙状态 · 公网监听埠 · **Docker 绕过防火墙侦测** · IPv6 同步防护 | | **补丁**
*Patching* | 待装安全更新 · 自动安全更新 · 重启需求 | | **内核与挂载**
*Kernel & Mounts* | 13 项 sysctl · `/dev/shm` 与 `/tmp` 的 noexec/nosuid · core dump | | **侦测能力**
*Detection* | 入侵防御引擎 · auditd · AIDE 基线 · 登入告警 · 日志保留 | | **完整性**
*Integrity* | `ld.so.preload` · **执行档已被删除的进程** · SUID 基线比对 · **计划任务中的“下载即执行”** · 临时目录可执行档 · 全域可写目录 |
| 分数 | 评级 | Grade | |:----:|:----:|:------| | 90-100 | 优秀 | Excellent | | 75-89 | 良好 | Good | | 60-74 | 及格 | Passing | | 40-59 | 偏弱 | Weak | | 0-39 | 危险 | Critical |
## 🏗️ 架构:三条降级链 / Architecture: Three Degradation Chains **设计原则:任何资料源取不到就降级,绝不中断、绝不假装没问题。** *Design rule: every data source degrades gracefully — never crash, never silently under-report.* ``` flowchart TD subgraph SSHD["sshd 設定 / SSH config"] A1["sshd -T(權威)"] -->|失敗| A2["解析 sshd_config.d/*.conf
+ sshd_config"] A2 -->|沒寫該項| A3["OpenSSH 官方預設值
標註「推定」"] A1 -.->|無 SSH 服務| A4["整組 SKIP"] end subgraph LOG["auth 日誌 / Auth log"] B1["journalctl -t sshd -t sshd-session"] -->|濾掉 meta 行後為空| B2["/var/log/auth.log
或 /var/log/secure"] end subgraph FW["防火牆 · IPS"] C1["ufw"] --> C2["nftables"] --> C3["iptables"] D1["CrowdSec"] --> D2["fail2ban"] end style A1 fill:#0EA5E9,color:#fff,stroke:none style B1 fill:#0EA5E9,color:#fff,stroke:none style A3 fill:#F59E0B,color:#fff,stroke:none ```
🐛 为什么这三条链是必要的 —— 三个真实踩过的坑 / Three real bugs that shaped this design
**1. 配置档没写,不代表没开** `sshd -T` 会因为配置有误、缺 privsep 目录、或旧版不支持而失败。早期版本遇到这种情况只显示“无法读取”—— 但配置档里没有 `PasswordAuthentication` 这一行,**不代表密码登入是关的,OpenSSH 预设就是 `yes`**。 不套用官方预设值会严重**低报**真实风险。现在会降级推导并明确标注“推定”。 *A missing `PasswordAuthentication` line doesn't mean password auth is off — OpenSSH defaults it to `yes`. Reporting "unknown" here would materially under-report risk.* **2. `journalctl` 的空输出不是空字符串** 无资料时 `journalctl` 会印 `-- No entries --`(16 字符,**非空**)。 早期版本用“输出非空”判断有资料,于是永远不降级到 `/var/log/auth.log`, 导致**所有统计恒为 0** —— 面板上的数字全是假的。纯看代码看不出来,是容器测试才暴露的。 *`journalctl` prints `-- No entries --` when empty. Treating that as "has data" meant the log-file fallback never fired and every stat silently read zero.* **3. OpenSSH 10 改了 syslog 识别码** OpenSSH 9.8+ 把工作进程拆成 `sshd-session`。在 Debian 13(OpenSSH 10.0)上, 只查 `journalctl -t sshd` 会**一条日志都找不到**。本项目两个识别码都带。 *OpenSSH 9.8+ split the worker into `sshd-session`. On Debian 13 a `-t sshd`-only query returns nothing at all.*
## 🚨 锁门风险与救援 / Lockout Risk & Recovery
**开始加固前,请先确认你知道自己云商的控制台在哪里。** *Before hardening: know where your provider's console is.*
三道防线 / *Three layers of protection*: | # | 机制 / Mechanism | 做什么 / What it does | |:-:|:-----------------|:----------------------| | **1** | **preflight 守门员** | 逐行跑 `ssh-keygen -l` 验证留存帐户**真的有可用公钥**(不是看档案存不存在);印出完整配置 diff;问你有没有 VNC / 救援模式。**没有任何有效公钥时直接拒绝执行禁用密码登入。** | | **2** | **arm_rollback 定时器** | 备份原配置 → 排定 N 分钟后自动还原 → 要求你**另开终端**登入并执行 `xb --confirm`。逾时未确认即自动还原。 | | **3** | **manifest 变更清单** | 每个动作把“做了什么 / 怎么撤销”写进 `/var/lib/oece-x/manifest.tsv`,可逐项或全部撤销。 | ### 真的被锁在外面了怎么办 / If you do get locked out ``` # 1. 用雲商的 VNC / 序列埠控制台登入 # DigitalOcean · Vultr · Linode · Hetzner · 阿里雲 都有 # 2. 還原備份 cp /var/backups/oece-x/<最新時間戳>/* /etc/ssh/sshd_config.d/ # 3. 重啟 sshd systemctl restart sshd ``` ## 🪤 主动防御设计 / Active Defense Design ### root 蜜罐 / Root Honeyp 机器人 99% 的暴破都打 `root`、`admin`、`ubuntu`、`test` 这几个名字。 把它们全部变成**诱饵**:真管理员换一个名字,诱饵帐户锁死并在**第一次尝试就封禁**。 *Bots overwhelmingly target `root`, `admin`, `ubuntu`, `test`. Turn all of them into tripwires: move the real admin elsewhere, lock the decoys, and ban on the **first** attempt.* ``` flowchart LR BOT["🤖 掃描器
Scanner"] -->|"ssh root@..."| SSHD["sshd"] SSHD -->|"DenyUsers root"| DENY["❌ 立即拒絕"] DENY --> BAN["🚫 maxretry=1 秒封
Instant ban"] DENY --> ALERT["🔔 告警 + 本地統計
Alert + local stats"] YOU["👤 你
You"] -->|"ssh <真管理員>@... :2222"| SSHD SSHD -->|"AllowUsers + 公鑰"| OK["✅ 放行"] style DENY fill:#EF4444,color:#fff,stroke:none style BAN fill:#F59E0B,color:#fff,stroke:none style OK fill:#10B981,color:#fff,stroke:none ``` ### endlessh 焦油坑 / SSH Tarpit 真 SSH 搬走后,让 22 埠**每 10 秒吐一个字符**的假 banner。扫描器会傻等好几个小时。 *Once real SSH has moved, serve an endless banner on port 22 — one character every 10 seconds. Scanners hang for hours.* ``` endlessh 已困住 41 個掃描器 · 累計浪費 63.2 小時 ``` ## 🔒 合规与隐私 / Compliance & Privacy
no telemetry no warp secrets sha256
- **零遥测**。脚本不上报任何资料 · *No telemetry, ever* - **蜜罐采集的攻击者用户名 / IP / 密码仅存本地**,不外传 · *Honeypot data stays on your box* - **CrowdSec 的社群情报共享预设关闭** —— 它预设会上报讯号,与本项目的零遥测原则冲突, 必须你明确同意才启用 · *CrowdSec's community signal sharing is opt-in here, not opt-out* - 不含任何代理 / 绕过网络封锁功能 · *No proxy or censorship-circumvention features* - 不硬编码任何 key。告警凭证存 `/etc/oece-x/blue.env`(`chmod 600`) - 第三方二进制一律 **HTTPS + 钉版本 + 内嵌 SHA256 校验** - 不 DD 重装、不覆盖生产配置 ## 🗺️ 路线图 / Roadmap | 版本 | 内容 | 状态 | |:-----|:-----|:----:| | **v1.0.0** | 骨架 · 32 项评分体检 · 蓝队面板 · Lynis(**全部只读**) | ✅ | | v1.1.0 | 防锁门机制(preflight + rollback + manifest)· 基础/标准加固 | 🚧 | | v1.2.0 | CrowdSec · fail2ban · root 蜜罐 · endlessh · 防火墙 | 📋 | | v1.3.0 | Telegram/邮件告警 · PAM 登入推送 · 日报 · IOC · 取证包 | 📋 | 当前版本选单 4-21 会提示“后续版本开放”。 *Menu items 4–21 currently print a "coming soon" notice.* ## 🧪 开发与测试 / Development ``` bash -n oece-x-blue.sh docker run --rm -v "$PWD":/mnt koalaman/shellcheck:stable /mnt/oece-x-blue.sh # 須 0 告警 ``` 测试矩阵 / *Test matrix*: | 环境 | 验证什么 | |:-----|:---------| | `debian:12` / `ubuntu:24.04` / `rockylinux:9` | apt 与 dnf 两条分支 · 全降级路径 | | 拟真映像(sshd + ufw + fail2ban + 植入的坏味道) | 真实 PASS/FAIL 分支 · IOC 侦测 | | DigitalOcean Debian 13(OpenSSH 10.0) | 真机 · `sshd-session` 识别码 · 真实云镜像预设值 | 详见 [docs/DEV-HANDOFF.md](docs/DEV-HANDOFF.md)。
PRs maintained issues
🌍 English Summary — click to expand
### 这是什么? `oece-x-blue.sh` is a single-file Bash blue-team panel for VPS hardening. It closes the loop that most tutorials leave open: **see → harden → deceive → alert → investigate**. ### 为什么还要另一个加固脚本? Because "one-click hardening" without an escape hatch is one-click suicide. The single most important feature here is not any hardening step — it's the **auto-rollback timer**: 1. Preflight verifies the account you're keeping has a **genuinely valid public key** (parsed with `ssh-keygen -l`, not just "the file exists"). No valid key → the script refuses. 2. Config is backed up and a timed restore job is armed. 3. Changes are applied and validated with `sshd -t`. 4. You must open a **second terminal**, log in with the new config, and confirm. 5. No confirmation within the window → everything is automatically restored. ### 亮点 - **32-point hardening score** across identity, exposure, patching, kernel, detection, and integrity. `SKIP` items are excluded from the denominator, so absent subsystems don't distort your score. - **Live threat panel** — bans, 24h failed logins, top attacking IPs, honeypot hits, tarpit stats. - **Root honeypot** — the usernames bots actually target (`root`, `admin`, `ubuntu`, `test`) become tripwires that ban on the *first* attempt. All captured data stays local. - **endlessh tarpit** — one banner character every 10 seconds on port 22; scanners hang for hours. - **Docker/UFW bypass fix** — Docker writes FORWARD-chain rules that `ufw deny` never sees. The audit cross-references published container ports against actual firewall rules. - **Graceful degradation everywhere** — three fallback chains (sshd config, auth logs, firewall/IPS) so the tool produces correct output on stock images, minimal containers, and OpenSSH 8 through 10. ### 隐私 Zero telemetry. Honeypot captures never leave the machine. CrowdSec's community signal sharing — which is normally on by default — is **opt-in** in this script. No proxy or circumvention features. Third-party binaries are pinned and SHA256-verified over HTTPS. ### 要求 Root. Debian 11+ / Ubuntu 20.04+ / RHEL-family 8+, amd64 or arm64. Menu items 1–3 are strictly read-only — safe to run before committing to anything. ``` bash <(curl -sL oece-x.com/b) ```
footer **MIT License** · Built for [YouTube @oece-x](https://www.youtube.com/@oece-x) · [oece-x.com](https://oece-x.com) *守好你的机器。 / Guard your box.*
标签:Cutter, PE 加载器, Shell脚本, 库, 应急响应, 应用安全, 系统加固, 蜜罐, 证书利用, 运维面板