我们如何走到今天
一切始于那些 一天也出不得差错的地方。
我们起初并没打算写一个操作系统。我们只想保护几台非常重要的设备,却一再在它们底层发现同一个问题。
- 委托
- 保护一个国家赖以运转的系统:让电力源源不断、让水质洁净的控制系统,医院所依赖的网络,把它们的数据送出去的网关,控制室里的终端,以及它们周围的每一台设备,小到公共场所里陌生人走上前去使用的那块屏幕。它们每一台都只有一项任务,却每一台都运行着为成千上万种任务而打造的操作系统。
- 症结
- 通用系统一到手就带着它可能用到的一切:浏览器、桌面、Shell、登录、后台服务。把它锁定到一个应用上,这些东西依然藏在底下,等着有人找到回去的路。每多一行代码,就多一处要打的补丁,也多一处可供攻击的地方。
- 转折
- 于是我们反过来问:如果设备只装着它的那一项任务,会怎样?我们从 seL4 出发,在它之上的自有代码全部用 Rust 编写,把每个部分密封在各自的隔离舱中,其余一概省去。然后,我们把证据写了下来,谁都不必只听我们一面之词。
- 意外发现
- 接着我们环顾四周。变电站里的网关、控制室里的终端、水泵侧面的面板、两个网络之间的那台设备、车站墙上的显示屏:几乎每一台专用设备都只有一项任务。原本为关键基础设施打造的护甲,结果成了构建所有这些设备的更好方式。我们称之为 Single Purpose OS。
可攻击的更少。要修补的少得多。别无他事。
我们的定义
用途,内置其中。 其余,一概省去。
Single Purpose OS 为一台设备的唯一任务而构建,而不是先构建成什么都能运行、再锁定为只做一件事。它由三点界定。
专为一项任务而建
设备镜像只包含其应用、该应用使用的驱动程序和内核。其他任务可能需要的东西一概没有:没有浏览器、桌面、Shell、包管理器或用户账户。
内部密封
每个部分(屏幕、输入、网络、应用)都运行在自己的隔离舱中,只能触及被授予的资源。按照设计,一个部分中的故障会留在该部分之内。
有据可查
它附带证据,说明内部有什么、每个部分可以做什么:每项授权都有记录,每个组件都有清单,还有任何人都能运行的检查。
它不是 Kiosk 模式——那只是把通用系统锁定在一个应用上,其余一切原封不动。它也不是单用户操作系统——那限制的是谁使用计算机,而不是计算机里有什么。
没有什么
软件更少。 刻意为之。
大多数专用设备运行的是通用系统,上面跑着一个应用,其余一切仍在底下。NoWayOS 从任务出发,只添加任务所需,其余一概省去。区别如下。
| 典型的锁定设备 | NoWayOS 设备 | |
|---|---|---|
| 网页浏览器和 JavaScript 引擎 | 包含 | 未内置 |
| 桌面和窗口系统 | 包含 | 未内置 |
| Shell 和命令行 | 包含 | 未内置 |
| 包管理器 | 包含 | 未内置 |
| 用户账户和登录 | 包含 | 未内置 |
| 后台服务 | 包含 | 未内置 |
| 用来锁定这一切的设置 | 包含 | 未内置 |
| 内核 | 通用内核:数千万行 | seL4:约 10,000 行 |
| 驱动程序 | 面向它可能遇到的硬件 | 只面向它使用的硬件 |
| 您的应用 | 包含 | 包含 |
Screen Compiler
您爱 React。 我们也是。
想要丰富、现代的界面,又想沿用您熟悉的工作流程?那就用 React 编写屏幕。Screen Compiler 会把它们转换为直接在 NoWayOS 上运行的原生 Rust 组件:没有浏览器,没有 JavaScript,也没有可供攻击的网页。
- 保留您的工具:组件、props、设计令牌,以及您已在使用的编辑器。
- 真正的构建模块:布局、文本、按钮、文本输入框、复选框、单选组、卡片、提示、进度条和图标。
- 要么精确,要么不做。它精确转换其子集,拒绝其他一切,并指出文件、行号和列号。它从不猜测。
- 逐像素检查。每个转换后的屏幕都由 NoWayOS 绘制,并与其核准图像比对。
<Column gap={SPACE_SM} padding={SPACE_LG}>
<Text id="title">Welcome</Text>
<Text>Touch Start to begin.</Text>
<Button id="start" onPress={onStart}>
Start
</Button>
</Column>let n1 = b.text("Welcome")?; // welcome.tsx:17:9
let n2 = b.text("Touch Start to begin.")?;
let n5 = b.button("Start", actions::START)?;
let n0 = b.column(
ui::Layout::new()
.gap(super::tokens::SPACE_SM)
.padding(super::tokens::SPACE_LG),
&[n1, n2, n5],
)?;节选自 Screen Compiler 的一个测试屏幕及其生成的 Rust 代码。
为何重要
一件事,足矣。
为一件事而造的计算机,可以造得截然不同。下面是它为您带来的好处。
更安全
从未内置的东西,就无从被利用。
- 没有浏览器引擎,没有窗口系统,没有 Shell,没有包管理器,没有用户账户。镜像里没有的东西,就无法被用来对付它。
- 屏幕、输入、网络和您的应用各自住在密封的隔离舱中,只能触及被授予的资源。它的构建方式,就是让一个部分中的故障留在该部分之内。
- 其核心是 seL4,seL4 基金会称之为“全球保障程度最高、速度最快的操作系统内核”。
- 全面采用 Rust。unsafe 代码只存在于少数几个经过审查的 crate 中,并由构建强制执行这份清单。
更高效
无一闲置,无一碍事。
- 没有后台服务,也没有为您从不使用的软件准备的更新程序。一开机,它就直奔那一项任务。
- 每个字节都在构建时确定:每个部分获得固定数量的内存,永远不能多占。大多数设备代码根本不分配内存,就连 TLS 客户端也只有固定的预算:一旦用完,它会干净利落地停止,而不是继续增长。
- 清晰的原生界面,只重绘发生变化的部分,在 Raspberry Pi 5 这样的低成本硬件上也游刃有余。
更易开发
一种语言。一个容器。模拟器优先。
- 从驱动程序到用户界面,全部用 Rust。
- 用 React 设计屏幕。Screen Compiler 在构建时把它们转换为原生 Rust:设备上拥有现代界面,却没有浏览器引擎,也没有 JavaScript。您也可以直接用 Rust 编写。
- 工具链、seL4 Microkit SDK 和 QEMU 都以固定版本装在同一个开发容器中。您的机器只需要 Podman 和 make,驱动 Raspberry Pi 时再加上 Python。
更易证明
每项授权都有记录。每个镜像都有清单。
- 系统授予的每项能力都列在一个文件中,两者一旦不符,构建就会失败。
- 每个镜像都附带一份软件物料清单,以及其 seL4 配置的记录。
- 有界证明表明每个消息解码器都不会 panic、溢出或越界读取,此外还有模糊测试以及许可证和安全公告检查:每一项都是您可以亲自运行的命令。
当一切都系于它,就只让它做一件事。
有些设备的工作太过重要,容不得任何分心:电网的控制系统、水厂对外的网关、控制室里的终端、两个网络之间的边界。NoWayOS 围绕每台设备需要承担的角色而设计,并提供证据,帮助您了解其中有什么。
要证据,不要形容词
它只做分内之事。您可以亲自查验。
安全主张的分量,取决于它背后的证据。NoWayOS 把证据写下来,而且每一份证据都来自您可以运行的命令。
每项授权都有记录
每个系统的授权文件列出它授予的每个优先级、内存区域、设备、中断和通道。系统与清单一旦不符,构建就会失败。
以越界检验隔离
隔离测试会去触碰未被授予的资源,而 seL4 必须阻止它们。一个故意放宽了授权的变体必须失败,这表明测试确实能够失败。
每个镜像都有清单
每个镜像都有一份 CycloneDX 软件物料清单:内核、加载器、每个保护域及其中的 crate,各自附带哈希值。
关卡不容染指
每项贡献都必须通过的检查存放在 Defence Agent 中,这是一个独立的公开代码仓库;任何触及关卡的拉取请求都会被标记出来,交由维护者处理。
公开开发
四个项目,各司一职。
四个项目全部开源,在 GitHub 上的 NoWayOS 组织下公开开发。您可以克隆、构建,并亲自检查每一行代码。
NoWayOS
Single Purpose OS。
基于 seL4 和 Microkit 的保护域模式、类型化消息、驱动程序、网络和原生用户界面,外加每个 NoWayOS 代码仓库构建时都要用到的开发容器和检查。
- 状态
- 开发中
- 许可证
- MIT OR Apache-2.0
Screen Compiler
用 React 设计,交付原生 Rust。设备上没有浏览器。
将以 TSX 按声明的子集编写的 React 屏幕,转换为面向 NoWayOS 用户界面的 Rust 代码。它在构建时运行于您的机器或 CI 中,从不随设备交付。
- 状态
- 开发中:子集 v0 以及 v1 的首批部分
- 许可证
- MIT
Showcase
可以在 Raspberry Pi 上运行的安全应用。
一套用于安全自助服务屏幕的工具包、一个可在其上构建的参考应用,以及一个启动器,汇集了以虚构品牌呈现的示例,Raspberry Pi 5 开机即进入。
- 状态
- 早期阶段,尚不可部署
- 许可证
- MIT OR Apache-2.0
Defence Agent
每项贡献都必须通过的关卡,拉取请求无从染指。
向 NoWayOS 各开放项目提交的每项变更都必须通过的全部安全关卡,逐一写明各自应对的威胁以及谁有权修改它,外加运行这些关卡的代理。拉取请求永远无法修改或提供评判它的东西。
- 状态
- 已公开:关卡已成文;代理及其工具是下一步
- 许可证
- MIT OR Apache-2.0
商业合作伙伴
基于 NoWayOS 的 商业产品。
NoWayOS 的赞助方 Adappt.ai 是它的首个商业合作伙伴。Adappt.ai 正在 NoWayOS 之上构建两款商业产品,两者都在开发中。
有意成为商业合作伙伴? 发邮件至 partners@nowayos.com
- Remote Desktop
- 一扇钢化的视窗。一台用于访问远程 Windows 桌面的安全工作站,按照设计,它把连接密封在独立的隔离舱中,并让凭据处于连接触及不到的地方。
- Data Diode
- 没有回头路。一道单向边界,用于把数据从受保护的网络中送出,围绕一条只朝一个方向传光的链路而设计。
进展如何
今天已在运行。 但尚未完工。
NoWayOS 正在开发中,尚不能用于生产环境,其 API 也会发生变化。以下是今天已经运行的部分,以及接下来的工作。
- 在 QEMU 中
- 五十多个系统能够启动并检查自身的输出,从第一个保护域,到获取 DHCP 租约的网络协议栈、监管器的故障安全状态,以及一个可点击的用户界面。
- 在 Raspberry Pi 5 上
- HDMI 屏幕上的用户界面、USB 键盘和鼠标、定时器、看门狗以及监管器的复位,都已在开发板上运行。板上更多硬件正在逐步启用。
- 尚待实现
- 安全启动、在设备上应用的签名更新,以及工业级硬件(NXP i.MX8)。
- seL4 的证明
- 每个系统都运行在 seL4 之上,但目前还没有任何 NoWayOS 镜像使用 seL4 已完成证明所覆盖的配置。每个镜像都会记录它所使用的配置。