# ADR-0008: Linux 主机加固 Check 架构

**状态**: 已采纳
**日期**: 2026-05-08
**参与者**: roger

## 背景

`agentsec server-audit` 现有 10 类 Check 全部聚焦 OpenClaw 应用层
（`native_audit` / `config_audit` / `version_patch` / `active_test` /
`exposure_scan` / `filesystem` / `process_forensics` /
`credential_audit` / `plugin_static` / `log_review`）。但「目标机器
是否安全」远不止 OpenClaw 进程本身 —— OS 层面是否打了补丁、
sysctl 是否合规、sshd 是否禁了 root 登录、sudoers 是否过宽、SUID
binary 是否被植入了非白名单条目，这些 CIS-级别的主机加固问题对
真实部署的安全姿态同样关键。

Phase 7e 把 server-audit 的 Check 生态从「应用层」扩到「主机
层」，覆盖 4 类 Linux 主机加固检查。

## 决策

新增 4 个 Check 类，全部遵循现有 `Check` ABC 模式：

1. **`SysctlAuditCheck` (`sysctl_audit`)** —
   `sysctl -n <key1> <key2> ...` 单次拉取多个 key，按
   baseline 期望值比对。每条违规一个 Finding。
2. **`SshdConfigAuditCheck` (`sshd_config_audit`)** —
   `sshd -T` 拿到有效配置（含默认值），按 baseline 比对。
3. **`SudoersAuditCheck` (`sudoers_audit`)** —
   `cat /etc/sudoers` + 列出 `/etc/sudoers.d/` 下每个文件并
   `cat`，按 baseline 的禁止 regex 模式扫描。
4. **`SuidAuditCheck` (`suid_audit`)** —
   `find /usr/bin -maxdepth 1 -type f -perm /4000` 与 `/usr/sbin`
   同款，比对 baseline 白名单（不在白名单的视为异常）。

四个 Check 共享一个 baseline 文件
`src/agentsec/audit/checks/linux_hardening_baseline.yaml`，按 section
切片（每个 Check 只读自己那一段，等同于
`config_audit.py:config_baseline.yaml` 的关系）。

**平台门槛**：每个 Check 在 `run()` 顶部检查
`ctx.profile.name in ("linux", "linux_user_mode")`；macOS / 未来其它
平台直接 `ctx.status.not_applicable(...)`。host hardening 是 Linux
独有概念，强行在 macOS 上跑只会出现 N/A 噪音。

## 理由

- **粒度选择**：每个违规一个 Finding，与 `config_audit` 一致，让
  报告 §3 详细发现按严重度分组时颗粒度可控。如果做成「整体一个
  finding 列出全部违规」会丢掉 per-key 的 fingerprint 稳定性。
- **baseline 静态化**：第一版用静态 YAML（CIS-aligned 默认值），
  不引入运维侧 override。后续 7e.1 可加 `linux_hardening.yaml`
  式的 ServerAuditConfig 字段，但当前不需要。
- **SSH policy 严格化**：每个新命令都补完整 argv schema 而非
  `allowed_argv` 通配，避免「allowed_argv 给了 sysctl 一个万用
  口子」。
- **Out of scope**：world-writable 扫描、auditd、firewall、
  systemd 服务枚举留作 7e.1 跟进；这一波先稳稳出 4 个高价值
  CIS 项。

## 备选方案

1. **复用 `config_audit` 写一个超大 baseline 把 sysctl/sshd/...
   全塞进去**：*放弃*：4 个 Check 的命令面、错误处理、参数构造
   差异大，硬合在一起会让 `config_audit` 变成 2000 行的怪物。
2. **跑 `lynis` / `oscap` 等现成工具，再 parse 输出**：*放弃*：
   外部工具版本差异大、SSH policy 难收敛（很多 lynis 子命令
   会 fork 子进程做事），跨真机部署成本反而更高；自写 4 个
   Check 反倒可控。
3. **每个 Check 一个独立 baseline 文件**：*放弃*：
   `linux_hardening_baseline.yaml` 单文件好检索，CIS 项之间
   的关联关系（比如「sysctl + sshd + sudoers 的 root 加固
   一致」）也方便 reviewer 一眼看穿。

## 后果

- 真机 server-audit 的 finding 总数会显著上升 —— Lightsail prod
  实跑预计 +20–40 finding（取决于 sysctl 默认配置）。这是预期
  的「Check 生态扩展」效应，不是回归。
- `ssh_policy.yaml` 新增 4 类命令（`sysctl` / `sshd` / `find` 在
  /usr/bin、/usr/sbin / `cat` 在 /etc/sudoers + /etc/sudoers.d）。
  每条都按 v1 严格 argv schema 落地，不放 `allowed_argv` 通配。
- macOS profile 的 server-audit 会看到 4 条新的
  `not_applicable`，sample drift guard 会随之刷新。
- 后续 7e.1 / 7f / 7g 的 Check 可以直接借这条 baseline-YAML +
  CLI-register-list 模式扩展，结构成熟。
