NoWayOS
ZH
GitHub
菜单关闭

少,是刻意为之

Single Purpose OS

一台心无旁骛的计算机。

没有浏览器。没有桌面。没有 Shell。没有登录。只有一项任务:仅由它所需的代码构建,在 seL4 微内核上密封于各个隔离舱中,以 Rust 编写。

今天已在 QEMU 和 Raspberry Pi 5 上运行 · 已在 GitHub 上开源

01 / 单一任务原则

一项任务。其余一概省去。
这一原则的示意图。

我们如何走到今天

一切始于那些 一天也出不得差错的地方。

我们起初并没打算写一个操作系统。我们只想保护几台非常重要的设备,却一再在它们底层发现同一个问题。

委托
保护一个国家赖以运转的系统:让电力源源不断、让水质洁净的控制系统,医院所依赖的网络,把它们的数据送出去的网关,控制室里的终端,以及它们周围的每一台设备,小到公共场所里陌生人走上前去使用的那块屏幕。它们每一台都只有一项任务,却每一台都运行着为成千上万种任务而打造的操作系统。
症结
通用系统一到手就带着它可能用到的一切:浏览器、桌面、Shell、登录、后台服务。把它锁定到一个应用上,这些东西依然藏在底下,等着有人找到回去的路。每多一行代码,就多一处要打的补丁,也多一处可供攻击的地方。
转折
于是我们反过来问:如果设备只装着它的那一项任务,会怎样?我们从 seL4 出发,在它之上的自有代码全部用 Rust 编写,把每个部分密封在各自的隔离舱中,其余一概省去。然后,我们把证据写了下来,谁都不必只听我们一面之词。
意外发现
接着我们环顾四周。变电站里的网关、控制室里的终端、水泵侧面的面板、两个网络之间的那台设备、车站墙上的显示屏:几乎每一台专用设备都只有一项任务。原本为关键基础设施打造的护甲,结果成了构建所有这些设备的更好方式。我们称之为 Single Purpose OS。

可攻击的更少。要修补的少得多。别无他事。

我们的定义

用途,内置其中。 其余,一概省去。

Single Purpose OS 为一台设备的唯一任务而构建,而不是先构建成什么都能运行、再锁定为只做一件事。它由三点界定。

  1. 专为一项任务而建

    设备镜像只包含其应用、该应用使用的驱动程序和内核。其他任务可能需要的东西一概没有:没有浏览器、桌面、Shell、包管理器或用户账户。

  2. 内部密封

    每个部分(屏幕、输入、网络、应用)都运行在自己的隔离舱中,只能触及被授予的资源。按照设计,一个部分中的故障会留在该部分之内。

  3. 有据可查

    它附带证据,说明内部有什么、每个部分可以做什么:每项授权都有记录,每个组件都有清单,还有任何人都能运行的检查。

它不是 Kiosk 模式——那只是把通用系统锁定在一个应用上,其余一切原封不动。它也不是单用户操作系统——那限制的是谁使用计算机,而不是计算机里有什么。

没有什么

软件更少。 刻意为之。

大多数专用设备运行的是通用系统,上面跑着一个应用,其余一切仍在底下。NoWayOS 从任务出发,只添加任务所需,其余一概省去。区别如下。

从未内置的东西,就无从被利用。
典型的锁定设备NoWayOS 设备
网页浏览器和 JavaScript 引擎包含未内置
桌面和窗口系统包含未内置
Shell 和命令行包含未内置
包管理器包含未内置
用户账户和登录包含未内置
后台服务包含未内置
用来锁定这一切的设置包含未内置
内核通用内核:数千万行seL4:约 10,000 行
驱动程序面向它可能遇到的硬件只面向它使用的硬件
您的应用包含包含
从未内置的东西,就无从被利用。

Screen Compiler

您爱 React。 我们也是。

想要丰富、现代的界面,又想沿用您熟悉的工作流程?那就用 React 编写屏幕。Screen Compiler 会把它们转换为直接在 NoWayOS 上运行的原生 Rust 组件:没有浏览器,没有 JavaScript,也没有可供攻击的网页。

  • 保留您的工具:组件、props、设计令牌,以及您已在使用的编辑器。
  • 真正的构建模块:布局、文本、按钮、文本输入框、复选框、单选组、卡片、提示、进度条和图标。
  • 要么精确,要么不做。它精确转换其子集,拒绝其他一切,并指出文件、行号和列号。它从不猜测。
  • 逐像素检查。每个转换后的屏幕都由 NoWayOS 绘制,并与其核准图像比对。

把您的第一个屏幕转换为 Rust

React 输入
<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>
Rust 输出
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
    GitHub 上的 NoWayOS
  • Screen Compiler

    用 React 设计,交付原生 Rust。设备上没有浏览器。

    将以 TSX 按声明的子集编写的 React 屏幕,转换为面向 NoWayOS 用户界面的 Rust 代码。它在构建时运行于您的机器或 CI 中,从不随设备交付。

    状态
    开发中:子集 v0 以及 v1 的首批部分
    许可证
    MIT
    GitHub 上的 Screen Compiler
  • Showcase

    可以在 Raspberry Pi 上运行的安全应用。

    一套用于安全自助服务屏幕的工具包、一个可在其上构建的参考应用,以及一个启动器,汇集了以虚构品牌呈现的示例,Raspberry Pi 5 开机即进入。

    状态
    早期阶段,尚不可部署
    许可证
    MIT OR Apache-2.0
    GitHub 上的 Showcase
  • Defence Agent

    每项贡献都必须通过的关卡,拉取请求无从染指。

    向 NoWayOS 各开放项目提交的每项变更都必须通过的全部安全关卡,逐一写明各自应对的威胁以及谁有权修改它,外加运行这些关卡的代理。拉取请求永远无法修改或提供评判它的东西。

    状态
    已公开:关卡已成文;代理及其工具是下一步
    许可证
    MIT OR Apache-2.0
    GitHub 上的 Defence Agent

进一步了解这些项目

商业合作伙伴

基于 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 已完成证明所覆盖的配置。每个镜像都会记录它所使用的配置。

关注进展

用途唯一,值得探索的却很多。

从设计入手,查验证据,或者跟随开发者指南构建您的第一个系统。顺便一提,本站也遵循同样的规则:没有脚本,没有 Cookie,心无旁骛。