## 一、产品定位
面向 Linux 运维人员的**智能感知交互式安全加固 CLI 工具**。专为 Debian/Ubuntu 服务器设计(兼容 RHEL 系),首次运行时会自动审计系统当前安全状态,对已加固的项目标记“安全可靠”,仍允许用户按需重新配置。通过向导式问答,一站式完成从系统更新、用户创建、SSH 深度加固、防火墙、入侵防御、审计到自动更新的完整安全基线建设。
## 二、目标用户
- 刚接手一台云服务器的开发者或运维,服务器可能是全新的,也可能已有部分配置。
- 需要标准化、可重复的安全基线,且不想因重复设置导致冲突或破坏现有环境。
- 希望工具辅助发现已有防护措施,避免浪费精力或错误覆盖。
## 三、功能需求(核心步骤)
### 步骤 0:环境审计与兼容性检测(新增,强制执行)
在用户进行任何选择前,工具以只读方式扫描系统,输出“当前安全状态报告”,并作为后续步骤交互的依据。
**检测项目清单:**
| 当前用户权限 | 检查 UID | 非 root 禁止执行 |
| 包管理器类型 | `which apt` / `yum` / `dnf` | 确定后续安装命令 |
| SSH 端口 | 解析 `/etc/ssh/sshd_config` 中的 `Port` 指令 | 若端口非22,标记“SSH端口已自定义” |
| 是否禁止密码登录 | 检查 `PasswordAuthentication` 和 `ChallengeResponseAuthentication` | 若均为 no,标记“密码登录已禁用” |
| 是否禁止 root 登录 | 检查 `PermitRootLogin` | 若为 no 或 prohibit-password,标记“root登录已禁止” |
| 是否存在非 root 的 sudo 用户 | 解析 `/etc/group` 中 `sudo` 组成员,过滤 UID≥1000 | 标记已有管理用户列表 |
| 是否已安装 fail2ban | `which fail2ban-server` 或检查服务状态 | 标记“fail2ban已安装”,并获取版本 |
| 是否已有替代入侵防御软件 | 检查 `crowdsec`、`denyhosts` 等进程 | 提示用户已有同类工具,询问是否切换 |
| UFW 状态 | `ufw status` | 若启用,列出当前规则摘要 |
| 是否已启用自动安全更新 | 检查 `unattended-upgrades` 配置或 systemd timer | 标记“自动安全更新已启用” |
| 是否存在 SSH 密钥(针对现有用户) | 检查 `~/.ssh/authorized_keys` | 提示已有密钥,避免覆盖 |
| 系统更新状态 | 检查上次 `apt update` 时间戳(基于缓存文件) | 提示是否需要更新 |
**审计报告输出示例:**
```
🔍 环境审计完成:
✅ 当前已以 root 运行
⚠️ SSH 端口已修改为 2222(安全)
✅ 密码登录已禁用
⚠️ 已存在 sudo 用户: alice, bob
✅ fail2ban 已安装并运行
❌ UFW 未启用
❌ 未检测到自动安全更新配置
...
```
### 步骤 1:系统更新
- **状态感知**:若检测到系统包列表已过期(超过 7 天),主动建议更新;若已是最新则提示“系统已处于最新状态,可跳过”。
- **执行**:`apt update && apt upgrade -y`
### 步骤 2:非 root 用户创建
- **状态感知**:列出已存在的 sudo 用户,询问“是否需要新建另一个管理用户?”,可跳过直接使用现有用户。
- **创建**:新建用户、加入 sudo 组、锁定密码(强制密钥),或为用户设置密码(可选,但引导使用密钥)。
### 步骤 3:禁止 root SSH 登录
- **状态感知**:若已禁止,提示“root 登录已禁止,无需修改”;但允许用户强制重新设置(如曾经手误改回)。
- **约束**:需确保存在至少一个 sudo 用户,否则拦截。
### 步骤 4:SSH 端口修改
- **状态感知**:若端口非22,提示当前端口并询问“保持当前端口 2222,还是修改为其他?”。允许输入新端口覆盖。
- **默认值**:随机生成一个 1024-65535 未占用端口作为建议。
### 步骤 5:禁止密码登录
- **状态感知**:若已禁止,提示“密码登录已处于禁用状态”,允许重新执行确保配置未被篡改。
### 步骤 6:ED25519 密钥设置
- **状态感知**:检查目标用户 `.ssh/authorized_keys` 是否存在,若存在则显示已有公钥指纹,询问“追加新密钥、覆盖或保留现有”。
- **选项**:生成新密钥对(私钥路径提醒)或粘贴用户提供的公钥。
### 步骤 7:UFW 防火墙配置
- **状态感知**:`ufw status` 输出展示,若已启用则列出规则,询问“添加新 SSH 端口规则还是保持现状?”。若检测到 firewalld(非 Debian 系)则提示适配方案。
### 步骤 8:Fail2ban 安装配置
- **状态感知**:若已安装,显示版本和运行状态,询问“重新配置监狱规则还是保留现有?”。
- **冲突处理**:若发现 `crowdsec` 等同类软件,警告并让用户选择保留哪个。
### 步骤 9:自动安全更新
- **状态感知**:检查 `unattended-upgrades` 是否启用,若已启用则提示“已开启无人值守安全更新”,可重新配置源或跳过。
### 步骤 10:安全扫描
- 执行轻量自检脚本或安装 `lynis` 运行审计。若之前已安装 lynis,可直接运行并显示报告摘要。
### 步骤 11:日志与审计增强
- 配置 `logwatch`、`aide`,同样先检测是否已存在配置。
### 步骤 12:SSH 服务重启与验证
- 汇总所有 SSH 相关修改,重启前强制警告,提供测试指引和 30 秒自动回退提示(若用户手动选择回退)。
## 四、交互流程(增强状态感知)
1. 启动 → 权限检查 → **执行环境审计并展示报告**(3 秒内完成)。
2. 展示所有步骤列表,**在每个步骤旁标注状态图标**:
- ✅ 已安全配置
- ⚠️ 部分配置或存在同类工具
- ❌ 未配置
- 🔄 需要更新
3. 用户通过多选(`dialoguer::MultiSelect`)勾选要执行的步骤,已安全配置的步骤默认不勾选,但可主动选择覆盖。
4. 按选中步骤依次交互,每个步骤内部开头再次确认当前状态:
- “检测到 SSH 端口已设置为 2222,您可保持或修改。”
5. 操作后实时更新状态图标,最终生成“本次加固总结报告”。
## 五、非功能性需求
- **安全与审计**:审计阶段只读,不修改系统。所有操作日志记录至 `/var/log/secure-init.log`,日志脱敏(如隐藏公钥内容仅记录指纹)。
- **幂等与抗冲突**:环境感知机制确保不会重复配置,允许用户显式覆盖。
- **可恢复性**:任何修改前自动备份(时间戳文件名),提供回滚命令提示。
- **跨平台适配**:审计阶段识别发行版,后续步骤自动调整包名与工具(如 firewalld 替代 ufw 建议)。
- **无交互模式**:通过配置文件(TOML)加载参数,结合环境审计结果,自动跳过已配置项,实现静默部署。
## 六、技术实现要点(融入架构)
- 在领域层新增 `SecurityAudit` 领域服务,聚合所有检测逻辑,返回 `AuditReport` 实体。
- UI 层通过报告渲染步骤列表。
- 应用层编排时,先调用审计服务,再根据用户选择和每个步骤的当前状态决定是否执行。