Omarchy 安全设计解析与实践指南:从全盘加密、默认防火墙到整机安全基线
本文基于 manual/48-security.md 编写。Omarchy 是一套以"在现实世界中完成真正工作"为目标的 Linux 发行版,其安全模型强调:即使设备丢失也不引发安全危机。本文从该文档的安全基线出发,结合仓库中的安装脚本、CLI 工具与验收测试源码,逐层讲解 Omarchy 的威胁模型、默认安全策略,以及修改密码、无密码 sudo、整机重置、签名密钥校验等日常安全运维操作,帮助读者既会"用"也会"验"。
Omarchy 的安全理念与五项默认基线
Omarchy 的安全出发点非常直白:这是一台用来干活的机器,笔记本可能被偷、可能遗失,因此默认防线必须让"丢设备"不变成"数据泄露"。围绕这一目标,系统在出厂(安装即生效)层面确立了五项基线策略。
1. 强制全盘加密(LUKS)
设备丢失或被盗时,物理介质落入他人之手是最大的数据泄露路径,因此全盘加密被列为最重要的一步。Omarchy 在安装阶段默认启用基于 LUKS(Linux Unified Key Setup)的整盘加密——即便硬盘被拆走、被挂载到其他机器,在没有口令的情况下数据仍然不可读。
这一点在源码中得到了充分印证。磁盘口令的日常维护封装在 bin/omarchy-drive-password,它通过 blkid -t TYPE=crypto_LUKS 枚举机器上的加密盘,然后调用 cryptsetup luksChangeKey --pbkdf argon2id --iter-time 2000 完成改密(见下方"修改密码"一节)。在 bin/omarchy-system-factory-reset 中,面向加密安装的整机重置还会做一次"临时口令 + 自动解锁 keyfile"的 LUKS 重设流程,并如实标注其边界:LUKS 重设只换口令(passphrase)而不换卷密钥(volume key),对于被释放的存储区间,拥有合法口令且能访问原始设备的人仍可读取,需要彻底确定性擦除时应使用 cryptsetup reencrypt 或重装系统。
2. 默认开启防火墙,默认拒绝入站
安装即生效的第二道防线是防火墙:默认拒绝所有入站流量,放行出站流量,仅对 LocalSend 使用的 53317 端口放行 TCP/UDP。SSH 服务默认不安装、不启动,需要时通过 Setup > Security > SSHD 手动开启,开启时会以**限速规则(rate limited)**打开 22 端口以对抗暴力破解。
仓库中的真实规则定义在 install/config/firewall.sh:
# Allow nothing in, everything out.
ufw default deny incoming
ufw default allow outgoing
# Allow ports for LocalSend.
ufw allow 53317/udp
ufw allow 53317/tcp
# Allow Docker containers to use DNS on host.
ufw allow in proto udp from 172.16.0.0/12 to 172.17.0.1 port 53 comment 'allow-docker-dns'
ufw allow in proto udp from 192.168.0.0/16 to 172.17.0.1 port 53 comment 'allow-docker-dns'
从该脚本可以看到几个细节:
- LocalSend 是唯一的默认入站白名单,且明确区分 TCP 与 UDP(文件/文本互传依赖这两类通道),其余一律
deny incoming; - 额外允许 Docker 容器访问宿主机的 DNS(
172.17.0.1:53),这是为了让容器网络可用,又不至于对整机开放入站; - 脚本末尾还会把 UFW 配置为开机自启(
ENABLED=yes+systemctl enable ufw),同时说明了一个安装期技巧:安装器所在 chroot 共享 live 环境的防火墙,因此安装期间只写配置文件、不激活 UFW,真正的启用发生在重启之后。
针对 Docker 的暴露风险,Omarchy 引入了 ufw-docker 的规则体系,防止容器端口意外暴露到公网。由于 ufw-docker 只有在 UFW 处于 active 状态时才肯写入 after.rules,install/config/firewall.sh 用一个"状态垫片(shim)"让 ufw status 返回 active、从而在不真正激活防火墙的前提下完成规则安装;这一行为被 test/shell.d/firewall-config-test.sh 精确验证——测试断言日志中出现了 ufw-docker install 与 systemctl enable ufw,却没有激活 live UFW。
3. 滚动更新保证补丁及时到位
Omarchy 建立在 Arch Linux 之上。Arch 是滚动发行版,任何软件包中暴露并被修复的漏洞都会很快进入仓库,用户通过 omarchy-update 即可安装,从而始终运行各组件的最新(通常是修复了已知 CVE 的)版本。
这条策略在仓库中对应着一整套更新链路:bin/omarchy-update 是入口,其中会先调用 bin/omarchy-update-keyring 刷新密钥环——该脚本检查 Omarchy 签名公钥 40DFB630FF42BCFFB047046CF0134EE680CAC571 是否已存在并本地签署,必要时从 keys.openpgp.org 拉取并 --lsign-key,随后安装 omarchy-keyring 包并强制刷新 archlinux-keyring。可见"更新即补丁"不是一句口号,而是把包签名信任链的刷新作为更新前置步骤固化进了工具链。
4. 自有软件仓库与镜像,最小化外部依赖
Omarchy 默认只依赖两组来源:Arch 官方 core/extra/multilib 仓库与 Omarchy 自有的软件包仓库(OPS);基础安装不引入 AUR。用户随时可以手动从 AUR 装软件,但默认镜像面被刻意收紧——只有少数可选安装(如第三方浏览器)会从 AUR 拉取。这缩小了软件供应链的攻击面,也让系统更新路径更可预期、可审计。
5. Cloudflare 保障分发基础设施可用性
Omarchy 的全部分发基础设施——ISO 镜像、自有软件包、Arch 镜像——都部署在 Cloudflare 的 DDoS 防护与 CDN 之后,以保障下载与升级的高可用。这一条属于基础设施层面的抗 DDoS 设计,主要面向分发链路本身的可用性(防止因下载源被打瘫而无法安装/升级,从而间接影响用户及时获得安全更新)。
开启 SSH:从"默认关闭"到"仅密钥认证"
文档强调 SSH 默认关闭,需要时通过 Omarchy 菜单 Setup > Security > SSHD 开启。仓库中对应的命令是 bin/omarchy-setup-security-sshd,它在一个命令里完成整套"打开却又加固"的流程:
- 安装并启动服务:
omarchy-pkg-add openssh后systemctl enable --now sshd.service; - 打开防火墙(限速):执行
sudo ufw limit 22/tcp comment "omarchy-sshd"并 reload——limit是 UFW 的暴力破解缓解规则,这就是文档所说"rate limited against brute force"的实现; - 授权密钥:支持三种来源,交互式菜单提供"从 GitHub 抓取"与"手动粘贴"两个选项,非交互场景则支持命令行参数
--key=<public-key>直接传入公钥,或用--gh-keys <github-username>从 GitHub 拉取该用户的全部公钥; - 关闭口令登录:一旦确认
~/.ssh/authorized_keys中存在有效密钥,就写入/etc/ssh/sshd_config.d/10-omarchy-hardening.conf,设置PasswordAuthentication no与KbdInteractiveAuthentication no。
这个脚本在安全细节上非常讲究,值得展开:
- 先授权密钥、后关闭口令(源码注释明确说明:在授权任何密钥之前禁用口令认证可能把所有者锁在机器外);
- 写配置前先
sshd -t校验语法,再用sshd -T读取生效配置逐一确认passwordauthentication no与kbdinteractiveauthentication no真正生效(因为 sshd 对这类配置采用"读到第一条即生效"的语义,管理员早前写入的规则可能覆盖它),校验失败则回滚删除配置、保留口令登录能力; - 用
reload而非restart,避免打断已连接的远端会话; --key与--gh-keys传入时跳过全部交互提示,可无人值守运行;二者不可同时给出。
对应的验收测试位于 test/acceptance.d/security-test.sh,它会真实生成一把 ed25519 测试密钥执行整套 setup,随后独立断言:sshd.service 处于运行态、公钥已进入 authorized_keys、sshd -T 的生效配置中口令认证与键盘交互认证均为 no,并且 ufw status 中存在 22/tcp LIMIT 限速规则。测试文件头部的注释同时说明了一个保守设计:这段测试会实际改动机器(开启 sshd、改防火墙),因此只有显式设置 OMARCHY_ACCEPTANCE_SUDO_PASSWORD 环境变量时才运行,避免在你不打算动的机器上误触发。
若要反向操作,仓库提供了对应的 bin/omarchy-remove-security-sshd(停止服务、撤掉防火墙规则),方便随时回到"SSH 默认关闭"的基线状态。
修改密码:两个口令各管一件事
在加密安装的机器上存在两个口令,职责完全不同:
- 磁盘解锁口令:开机时解锁加密卷;
- 用户登录/Sudo 口令:登录系统以及执行
sudo时使用。
两者都可以在 Omarchy 菜单的 Update > Password 下修改——Drive Encryption 改磁盘口令,User 改用户口令。仓库的菜单定义见 default/omarchy/omarchy-menu.jsonc,其中 update.password.drive 条目执行的正是 omarchy-drive-password,而 update.password.user 条目直接调用 passwd。
值得注意的是,改磁盘口令要求先提供当前口令(见文档提示"have it handy")。这并非只是流程繁琐:在 bin/omarchy-drive-password 的实现里,用户口令的交互是留给当前磁盘口令提示的——新口令通过 stdin 以进程替换 <(...) 的方式传给 cryptsetup luksChangeKey,从而把终端(/dev/tty)让给"当前口令"的输入。脚本还做了基本的输入校验:新口令不能为空、两次输入必须一致。如果你有多块加密盘,它会先让你选择要改哪一块。
Passwordless sudo:按需、限时、自动回收
AI Agent 需要长时间执行系统任务时,反复输入 sudo 口令很打断节奏。Omarchy 在 Setup > Security > Passwordless Sudo 提供的解决方案不是"永久放行",而是按需开启 + 定时自动关闭的临时窗口。
默认时长为 15 分钟,到点自动撤销;想要提前结束,在计时结束前再运行一次即可立刻关闭;15 分钟不够用,可以自定义时长:
omarchy-sudo-passwordless # 默认开启 15 分钟
omarchy-sudo-passwordless 30 # 开启 30 分钟
omarchy-sudo-passwordless # 再次运行(无参数)=立即提前关闭
其底层实现 bin/omarchy-sudo-passwordless 非常干净,值得逐条拆解:
- 授权文件按用户隔离:向
/etc/sudoers.d/99-omarchy-nopasswd-${USER}写入用户名 ALL=(ALL) NOPASSWD: ALL一行,文件权限收紧为440; - 过期靠 systemd transient timer 实现:
sudo systemd-run --on-active=${MINUTES}m --timer-property=AccuracySec=1s --unit=... rm -f -- <授权文件>——计时结束直接删除授权文件,不依赖任何后台常驻守护; - 先上保险、再报成功:如果 timer 没能成功创建(
arm_expiry失败),脚本会立即收回刚写入的授权并提示 "Revoking access now",绝不留一个没有倒计时的永久后门;若连回收都失败,会输出 CRITICAL 警告要求立即以 root 身份手动删除文件——fail-closed 而非 fail-open; - 重启兜底:transient timer 不跨重启存活,若重启后授权文件仍在而 timer 不存在,脚本会在下次运行时清理它。这还不算完——Omarchy 在 etc/tmpfiles.d/omarchy-nopasswd-sudo.conf 中额外定义了一条只在开机阶段执行的清理规则
r! /etc/sudoers.d/99-omarchy-nopasswd-*,确保任何重启后残留的授权文件都会被清除(这就是文档所说"A restart removes the passwordless sudo rule as well"的机制); - 由于脚本要求 sudo 提权,它会先向用户展示一条明确的警告信息,并用
gum confirm交互确认后才写入授权。
test/shell.d/nopasswd-sudo-expiry-test.sh 对这套逻辑做了细致的 mock 测试,覆盖了:成功开启后授权文件存在且属于当前用户、timer 被正确以 --on-active=15m 挂起、timer 创建失败时新授权被收回、更新时长失败时旧授权被收回、输出不会误导性地报告"已启用"等分支;它还验证了 tmpfiles 规则只在 --boot 模式下删除生成的授权文件、且不会误删 omarchy-dns 等其他 sudoers 规则。
文档对此功能的定位极其清醒,这里原文强调的核心风险值得复述:开启期间,任何以你的用户身份运行的程序都可以不经询问以 root 权限做任何事——这正是该功能的目的,也正是它的全部风险所在。 建议只在确实需要让可信的 AI Agent 连续执行系统操作时短时开启,并在用完立即关闭。
相邻功能:Sudoless Docker 与 sudoers 默认收紧
与 passwordless sudo 同属"安全 > 可选放权"的是 Sudoless Docker(菜单 Setup > Security > Sudoless Docker)。仓库中 bin/omarchy-setup-security-sudoless-docker 的实现非常直白:把你的用户加入 docker 组。脚本的警告信息会毫不含糊地告诉你——Docker 守护进程以 root 运行,加入 docker 组等价于无口令 root,例如 docker run -v /:/host alpine 就能以 root 完整读写宿主机,因此一个失控脚本、依赖或插件就能接管整机。这也是为什么 Omarchy 默认不这么做:默认情况下 Docker 访问要经过 polkit/sudo 提示,配合 install/config/firewall.sh 中的 ufw-docker 规则避免容器意外暴露到公网。若确实需要,开启后需重启生效(usermod -aG docker 只对全新会话生效),反向命令是 omarchy-remove-security-sudoless-docker。
在"减少无谓放权"这一面,仓库还固化了一些 sudoers 默认值,例如 etc/sudoers.d/omarchy-passwd-tries 设置 Defaults passwd_tries=10 限制 sudo 口令尝试次数;test/acceptance.d/security-test.sh 还验证了一个回归点:旧版本曾随系统发放 asdcontrol 的无口令 sudoers 授权,现已收回该授权、只由对应软件包自身管理——这是"最小权限"原则持续演进的一个佐证。
Reset Computer:把用过的机器安全交出去
把机器转交给别人时,不需要重装系统。在 Omarchy 菜单中运行 Setup > Reset Computer,输入 reset 确认后重启即可。重置会完成:
- 抹掉所有用户账户与
/home下的全部内容; - 丢弃安装后新增的所有软件包与系统改动;
- 清除机器的身份信息——网络连接、SSH host keys、machine-id 等;
- 重启后回到首次开机的设置向导,新主人自行设定用户名、口令与加密口令。
背后的实现是 bin/omarchy-system-factory-reset,它比文档描述更精细,值得展开:
- 原理是快照回滚:Omarchy 安装器(Quattro)在安装完成后拍摄了一个
@factory基线快照(Btrfs)。重置时脚本把当前运行根@换成@factory的一个可写新克隆,因此连你安装的软件包和/etc漂移也会一并消失。正因如此,它只对从 Omarchy ISO 安装的机器可用——从旧版本升级上来的机器没有@factory基线,脚本会明确拒绝并建议重装; - 加密盘的处置:如果检测到 LUKS 加密安装(通过解析
cryptdevice=内核参数或遍历设备树定位crypto_LUKS分区),脚本会先要求你输入当前磁盘口令以授权 re-key,然后luksAddKey写入一个随机临时口令,并把自动解锁 keyfile 与内核参数预置进新系统,使得"未配置新主人的交接窗口期"能够开机;首次开机向导完成后会再把卷口令 re-key 成新主人的口令并删除 keyfile; - 基线本身会被消毒(sanitize):
@factory快照在普通安装场景下仍含有卖家账户与/etc/shadow等敏感信息,重置会就地删除其中 uid≥1000 的账户、锁定 root、移除 SSH host keys、网络连接记录与 autologin 状态、清空 machine-id,防止旧账户被新主人挂载读取或在下次重置时"复活"; - 引导链同步重建:脚本会重置 ESP 上的
limine.conf、在目标根内重建 UKI 并校验limine.conf中每个条目的 blake2b 哈希,确保交接出去的机器不会在开机时卡在 Limine 的哈希不匹配警告上;若系统配置了休眠,还会在新根内重建 swapfile 与 resume 偏移量; - 诚实的能力边界(脚本注释与界面提示都明确说明):在未加密磁盘上,重置只是删除而非安全擦除——SSD 上
fstrim有帮助,但如果数据敏感应改用全新安装;LUKS re-key 也不改变卷密钥,对原始设备有访问权且持有合法口令的人仍可读取已释放的数据区间,需要确定性擦除时应使用cryptsetup reencrypt或重装。
菜单中的对应条目见 default/omarchy/omarchy-menu.jsonc 的 setup.reset,它带有一个 when 条件:仅在根文件系统是 btrfs 时显示。快照与恢复的日常用法可进一步参考 manual/47-system-snapshots.md。
签名密钥与验证
为抵御供应链投毒,Omarchy 对分发的每个环节都做了签名:所有 ISO 签名与 Omarchy 软件包仓库使用的公钥均为 40DFB630FF42BCFFB047046CF0134EE680CAC571(发布方为 Omarchy 的软件包维护邮箱),可在公钥服务器上校验该指纹;omarchy/omarchy-keyring 软件包内置此公钥,并负责未来任何密钥轮换的无缝推进。
仓库侧的对应实现见 bin/omarchy-update-keyring:它会检查本地 pacman-key 是否已持有该指纹,缺失时从 keys.openpgp.org 拉取并做 pacman-key --lsign-key(本地签署信任),再确保 omarchy-keyring 与最新的 archlinux-keyring 就位——这保证了 omarchy-update 每次安装的包都处于可验证的信任链之下。
ISO 方面,文档给出了一个通用验证方式:任意 ISO 版本的签名文件,只需在镜像地址后追加 .sig 即可得到(形如发布站点上 omarchy-x.x.x.iso 对应的 .sig 文件),配合上述公钥即可用标准 PGP 流程校验下载文件的完整性与真实性。
延伸阅读
- 系统级验收测试:test/acceptance.d/security-test.sh——输入组审计、asdcontrol sudoers 回归、SSH 加固全流程;
- 防火墙安装与 Docker 规则:install/config/firewall.sh、install/config/docker.sh 及测试 test/shell.d/firewall-config-test.sh;
- 无口令 sudo 的实现与测试:bin/omarchy-sudo-passwordless、etc/tmpfiles.d/omarchy-nopasswd-sudo.conf、test/shell.d/nopasswd-sudo-expiry-test.sh;
- 整机重置:bin/omarchy-system-factory-reset 与快照机制 manual/47-system-snapshots.md;
- 菜单入口:default/omarchy/omarchy-menu.jsonc(
setup.security.*、update.password.*、setup.reset等条目); - 密钥环与更新:bin/omarchy-update、bin/omarchy-update-keyring;
- sudoers 默认收紧:etc/sudoers.d/omarchy-passwd-tries 等文件。
总结而言,Omarchy 的安全设计遵循一条清晰的主线:加密兜底物理丢失风险,防火墙与最小默认面收窄网络攻击面,滚动更新与签名信任链保证补丁既快又可验证,而对任何"临时放权"(passwordless sudo、sudoless docker、SSH 端口)都附加了显式警告、默认关闭或自动回收机制。理解这一模型后,你既能高效地完成日常安全运维,也能在把机器交给下一位使用者时确保基线干净如初。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.2 K634
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown300
jforgamejforgame是一个一站式游戏服务器开发框架。包含游戏服务器开发所需要的各种组件,比如网关,socket服务端与客户端,自定义高效消息编解码,游戏热更新,游戏通用工具等等。包含游戏服,跨服,匹配服,后台管理系统等实现,同时提供大量业务案例以供学习。亦可用于其他socket应用,例如及时聊天等。Java101
fizz-gateway-nodeAn Aggregation API Gateway in Java . FizzGate 是一个基于 Java开发的微服务聚合网关,是拥有自主知识产权的应用网关国产化替代方案,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层胶水代码以及降低编码投入、提高 API 服务的稳定性和安全性。Java60
certd开源SSL证书管理工具;全自动证书申请、更新、续期;通配符证书,泛域名证书申请;证书自动化部署到阿里云、腾讯云、主机、群晖、宝塔;https证书,pfx证书,der证书,TLS证书,nginx证书自动续签自动部署JavaScript60
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python280