15 · 安全边界与恢复¶
Omarchy 有意给予脚本很大能力:安装包、修改 /etc、控制会话、执行插件。安全性不来自“没有危险能力”,而来自把授权、信任和可恢复性放在明确边界上。
权限边界¶
flowchart TD
Action[用户动作] --> Need{需要 root?}
Need -->|否| User[普通用户命令]
Need -->|是/有终端| Sudo[sudo + 可见认证]
Need -->|是/GUI| Polkit[pkexec / Shell polkit agent]
Sudo --> Root[root entrypoint 再检查 EUID]
Polkit --> Root
Root --> System[/etc · pacman · systemd system]
CLI 的 requires-sudo 元数据只是帮助提示;真正边界由 sudo/pkexec 和目标脚本 EUID 检查共同执行。反方向同样重要:用户 provisioning 明确拒绝 root,防止 home 文件归属污染。
信任边界一览¶
| 输入 | 默认信任 | 防线 |
|---|---|---|
| package 中的脚本/default | 发行方代码 | pacman/keyring、固定所有权 |
| 用户 hook/Lua | 用户主动授权代码 | 只在用户配置路径、明确执行点 |
| 第三方 Shell 插件 | 未信任直到 enable | 保留 ID、路径校验、禁 symlink、确认/diff |
| 远程主题 | 只当数据 | staging allow/deny、禁代码文件、不跟 symlink |
| menu action | 配置即代码 | shipped/user 路径分离,guard 不作为权限 |
| migration | 发行方增量代码 | 顺序、严格 Bash、成功 marker |
主题与插件采用不同策略是合理的:插件的目的就是执行 QML 代码,所以需要显式 enable;主题的目的只是视觉数据,因此不应获得代码执行能力。
更新前快照¶
omarchy-snapshot create 枚举所有 Snapper config,为每个创建带当前 Omarchy 版本描述的 number snapshot,再执行 cleanup。若 Snapper 安装却没有任何 config,它明确失败,而不是安静返回成功制造“已经可恢复”的假象。
restore 交给 limine-snapper-restore,把恢复入口连接到 boot 环境。快照是更新前的重要恢复点,但不是数据库式原子事务:home、外部磁盘、固件和运行中云服务仍可能在覆盖范围外。
Factory reset:两阶段破坏性流程¶
Factory reset 只支持由 Quattro installer 创建了 @factory Btrfs 基线的机器;从旧版升级到 Quattro 的机器没有可信 factory snapshot,当前实现会拒绝。
阶段一:运行系统中 staging¶
- 强确认,要求输入
reset; - 验证 Btrfs
@与@factory; - 克隆 fresh writable root 为 next;
- 准备 provisioning units/markers;
- 加密安装临时 re-key 并嵌入一次性自动解锁 key;
- 重建 UKI/boot entry;
- 验证 Limine 中每个 UKI 的 BLAKE2 hash;
- 只在所有 staging 完成后安排下次启动切换。
阶段二:下次 boot 早期清理¶
finish service 在 home.mount / var-log.mount 之前运行:删除旧 root,重建空 @home 与 @log,修复 /.snapshots 子卷,trim,最后清 pending marker 并进入新 owner provisioning。
stateDiagram-v2
[*] --> Confirmed
Confirmed --> FactoryClone
FactoryClone --> BootVerified
BootVerified --> WipePending
WipePending --> Reboot
Reboot --> EarlyFinish
EarlyFinish --> HomeLogRecreated
HomeLogRecreated --> Provisioning
Provisioning --> [*]
EarlyFinish --> RetryNextBoot: 失败保留 wipe-pending
失败时保留 wipe-pending,阻止 provisioning 在半清理机器上创建新用户。这里 marker 是安全闸门,不只是进度记录。
Factory reset 不等于取证级擦除
未加密磁盘上的删除与 fstrim 不能保证不可恢复;LUKS 改 passphrase 也不更换 volume key。源码明确建议高保证场景使用 blkdiscard + 重装或 cryptsetup reencrypt。
机器身份也属于敏感状态¶
reset 不只删 home,还处理:
/etc/ssh/ssh_host_*;- NetworkManager connections、iwd、Tailscale;
- fingerprint enrolments;
- SDDM autologin/state;
- machine-id;
- 旧 boot identity 与 UKI hash。
卖出机器时只删账号会留下网络凭据、host keys 和设备身份,这就是系统级 reset 必须比 rm -rf /home 更广的原因。
锁屏与 polkit 为什么在 Shell¶
Lock view 与 polkit agent 是 first-party service plugins,启动即加载。它们提供 UI,但认证事实仍交给 PAM/polkit。Shell 不应自行实现密码验证或把认证 token 持久化。
睡眠锁由 user systemd 服务配合会话状态,解决“合盖/睡眠竞态中 UI 尚未锁定”的时序,而不是仅依靠按键调用锁屏。
故障隔离的共同手法¶
- update/theme/shell restart 使用互斥锁;
- staging 完整后再原子切换;
- marker 只在成功后写;
- 第三方 namespace 不能覆盖 first-party;
- package update 前创建快照;
- reboot/cutover 前验证启动参数和 UKI hash;
- 破坏性跨 boot 流程失败时保持 pending,以便重试而非继续。
关键源码索引¶
bin/omarchy-snapshot— Snapper create/restore 与空配置失败bin/omarchy-system-factory-reset— staging、re-key、boot verificationbin/omarchy-system-factory-reset-finish— early-boot wipe 与重试闸门shell/plugins/lock/Service.qml— 锁屏服务入口shell/plugins/polkit/PolkitAgent.qml— 图形授权代理bin/omarchy-theme-set— 主题 trust/staging 边界bin/omarchy-plugin-validate— 插件安装边界
下一章分析风险最高也最完整的一次状态转换:16 · Quattro 一次性升级器。