<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans">
  <title>NoWayOS 手记</title>
  <subtitle>NoWayOS 是如何构建的，以及为什么这样构建：来自 Single Purpose OS 开发过程的故事，篇篇属实，大多可以查证。</subtitle>
  <link href="https://www.nowayos.com/zh/journal/feed.xml" rel="self"/>
  <link href="https://www.nowayos.com/zh/journal"/>
  <id>https://www.nowayos.com/zh/journal</id>
  <updated>2026-11-13T00:00:00Z</updated>
  <author><name>NoWayOS</name><uri>https://www.nowayos.com/zh</uri></author>
  <entry>
    <title>写的是 React，出的是 Rust</title>
    <link href="https://www.nowayos.com/zh/journal/react-in-rust-out"/>
    <id>https://www.nowayos.com/zh/journal/react-in-rust-out</id>
    <published>2026-11-13T00:00:00Z</published>
    <updated>2026-11-13T00:00:00Z</updated>
    <summary>设计师继续用 React。设备得到的是原生 Rust。Screen Compiler 如何在构建时把屏幕变成代码，让设备上没有可供攻击的浏览器。</summary>
    <content type="html">&lt;p&gt;现代界面是用 React 设计的。于是，从控制面板到售票机，非常多的专用设备都带着一整个浏览器引擎，这是世上最庞大、受攻击最多的程序之一，只为了画出几个按钮和“Touch Start to begin”这几个词。&lt;/p&gt;
&lt;p&gt;我们想要现代的设计流程，但不要浏览器。于是我们构建了 &lt;strong&gt;Screen Compiler&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&quot;用-react-编写屏幕&quot;&gt;用 React 编写屏幕&lt;/h2&gt;
&lt;p&gt;您的设计师和前端开发者继续使用他们的工具：组件、props、设计令牌，还有他们的编辑器。他们用 TSX 编写屏幕（下面这个节选自 Screen Compiler 的一个测试屏幕）：&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&amp;lt;Column gap={SPACE_SM} padding={SPACE_LG}&amp;gt;
  &amp;lt;Text id=&amp;quot;title&amp;quot;&amp;gt;Welcome&amp;lt;/Text&amp;gt;
  &amp;lt;Text&amp;gt;Touch Start to begin.&amp;lt;/Text&amp;gt;
  &amp;lt;Spacer /&amp;gt;
  &amp;lt;Button id=&amp;quot;start&amp;quot; onPress={onStart}&amp;gt;Start&amp;lt;/Button&amp;gt;
&amp;lt;/Column&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;交付的是普通的-rust&quot;&gt;交付的是普通的 Rust&lt;/h2&gt;
&lt;p&gt;在构建时，在您的机器上或在 CI 中，Screen Compiler 把它转换成面向 NoWayOS 用户界面运行时的 Rust：&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;let n1 = b.text(&amp;quot;Welcome&amp;quot;)?; // welcome.tsx:17:9 &amp;lt;Text&amp;gt;
let n2 = b.text(&amp;quot;Touch Start to begin.&amp;quot;)?; // welcome.tsx:18:9 &amp;lt;Text&amp;gt;
let n4 = b.spacer(None)?; // welcome.tsx:20:9 &amp;lt;Spacer&amp;gt;
let n5 = b.button(&amp;quot;Start&amp;quot;, actions::START)?; // welcome.tsx:21:9 &amp;lt;Button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;每一行都指回它所来自的 TSX。设备得到的只有这些代码，别无其他：没有 JavaScript 引擎，没有浏览器，没有可供攻击的网页。Screen Compiler 本身从不随设备交付。&lt;/p&gt;
&lt;!-- slot --&gt;&lt;h2 id=&quot;要么精确-要么不做&quot;&gt;要么精确，要么不做&lt;/h2&gt;
&lt;p&gt;靠猜测的转换器，是您无法信任的转换器。Screen Compiler 精确地转换它所声明的 TSX 子集，其余的一律拒绝，并给出文件、行和列。它从不近似。它写出的 Rust 没有 &lt;code&gt;unsafe&lt;/code&gt;，没有 &lt;code&gt;unwrap&lt;/code&gt;，也没有 &lt;code&gt;panic&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后，每个转换后的屏幕都由 NoWayOS 的渲染器绘制，并与它的已批准图像逐像素比较。哪怕只有一个像素移动，构建也会指出来。&lt;/p&gt;
&lt;h2 id=&quot;目前的进展&quot;&gt;目前的进展&lt;/h2&gt;
&lt;p&gt;Screen Compiler 正在开发中：它的第一个子集已经构建完成，下一个正在进行。它以 MIT 许可证开源，在 GitHub 上与 NoWayOS 并列。如果您的团队用 React 设计，并且构建举足轻重的设备，&lt;a href=&quot;mailto:partners@nowayos.com&quot;&gt;我们很希望听到您的消息&lt;/a&gt;。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>那个不是复制品的备份</title>
    <link href="https://www.nowayos.com/zh/journal/the-backup-that-wasnt-a-copy"/>
    <id>https://www.nowayos.com/zh/journal/the-backup-that-wasnt-a-copy</id>
    <published>2026-11-13T00:00:00Z</published>
    <updated>2026-11-13T00:00:00Z</updated>
    <summary>阿波罗 11 号带着两套按不同原理构建的制导系统飞行，而且两套都用上了。阿丽亚娜 5 号带着两套完全相同的系统飞行，一个故障让两套都停了。这种差别有个名字，而 NoWayOS 的构建方式，就是为了站在正确的那一边。</summary>
    <content type="html">&lt;p&gt;人人都知道应该有备份。但很少有人接着问那个不太好回答的问题：到底是&lt;em&gt;什么&lt;/em&gt;的备份？&lt;/p&gt;
&lt;h2 id=&quot;五次警报&quot;&gt;五次警报&lt;/h2&gt;
&lt;p&gt;1969 年 7 月 20 日，阿波罗 11 号的登月舱距离月面只有几分钟时，它的制导计算机发出了一个警报，机组不得不向任务控制中心询问。接着又是一个。在下降的最后一段，一共五次。&lt;/p&gt;
&lt;p&gt;计算机过载了。它接下来所做的，是这个故事里最了不起的工程成就之一：每一次，它都重新启动，丢掉可以等的工作，立刻接回不能等的工作。着陆继续进行。&lt;/p&gt;
&lt;p&gt;这是人人都讲的部分。接下来值得讲的部分，发生在第二天。&lt;/p&gt;
&lt;h2 id=&quot;第二套系统&quot;&gt;第二套系统&lt;/h2&gt;
&lt;p&gt;登月舱带着第二套制导系统，而它并不是第一套的备用复制品。它由另一家公司按另一种原理建造。主系统靠一个在万向架上自由转动的平台保持方位。第二套根本没有万向架：它的传感器直接固定在航天器上，哪边是上，它靠计算得出。&lt;/p&gt;
&lt;p&gt;它的用处，是在主系统万一停止工作时把机组送回轨道。着陆期间没有用到它。&lt;/p&gt;
&lt;p&gt;后来，在上升返回、与指令舱对接的途中，一连串机动把主系统的平台带到了万向架平台唯一应付不了的那个位置，它失去了姿态基准。机组切换到第二套系统来稳住航天器，并完成了对接。&lt;/p&gt;
&lt;p&gt;第二套系统不可能以同样的方式失效。它没有那个部件。&lt;/p&gt;
&lt;h2 id=&quot;两个一样的&quot;&gt;两个一样的&lt;/h2&gt;
&lt;p&gt;现在讲另一个故事。1996 年，第一枚阿丽亚娜 5 号升空时带着两台惯性基准装置，告诉它自己指向哪里：一台工作，一台待命。它们完全相同，连软件也一样。&lt;/p&gt;
&lt;p&gt;三十七秒后，软件里的一个数变得太大，超出了为它留出的空间。待命的那台停了。工作的那台，在同一次飞行中运行着同样的代码，也停了。调查委员会的报告是公开的，说得很直白：没有可以切换过去的东西，因为备份已经走了同一条路。&lt;/p&gt;
&lt;p&gt;两个复制品。一个故障。什么都没剩下。&lt;/p&gt;
&lt;h2 id=&quot;工程师怎么称呼它&quot;&gt;工程师怎么称呼它&lt;/h2&gt;
&lt;p&gt;一个故障把系统和它的备件一起带走，这叫&lt;em&gt;共因故障&lt;/em&gt;。对付它的办法是&lt;em&gt;多样性冗余&lt;/em&gt;：第二套系统的构建方式要足够不同，使得让第一套停下的东西不在第二套里。&lt;/p&gt;
&lt;p&gt;航天飞机就是这样飞的。它的四台飞行计算机运行一家公司的软件；第五台运行的是另一家公司单独编写的软件。四个复制品能防住一台坏掉的计算机。它们防不住一个写错的程序，因为四台都在运行它。&lt;/p&gt;
&lt;p&gt;这不是没有代价的。航天飞机的首次发射被取消，就是因为第五台计算机和另外四台在时间上对不上。两种设计比一种更费工夫，而且必须让它们对得上。&lt;/p&gt;
&lt;h2 id=&quot;nowayos-的位置&quot;&gt;NoWayOS 的位置&lt;/h2&gt;
&lt;p&gt;如今大多数专用设备运行的，是为数极少的几种通用操作系统之一。它们的备份也是。当浏览器引擎、桌面或数千万行的内核里出现一个缺陷，或者一个有问题的更新被推送出去，它会在这种软件运行的每一个地方出现，就在同一天。&lt;/p&gt;
&lt;p&gt;NoWayOS 设备在内部是不同的。它的内核是 seL4，约 10,000 行。内核之上属于我们的一切都用 Rust 编写。它没有浏览器引擎，没有桌面，也没有 Shell，所以这些东西里的缺陷不在它里面。&lt;/p&gt;
&lt;p&gt;这意味着 NoWayOS 不必取代您正在运行的系统才有用。它可以站在旁边：完成一项关键任务的第二种方式，按另一种原理构建。&lt;/p&gt;
&lt;h2 id=&quot;它做不到什么&quot;&gt;它做不到什么&lt;/h2&gt;
&lt;p&gt;多样性有局限，我们宁愿由我们来告诉您。&lt;/p&gt;
&lt;p&gt;它给 NoWayOS 设备的是不同的故障，而不是没有故障。对两套系统共用的东西，它无能为力：电源、网络、它们背后的服务，或者对这项任务本该是什么的误解。而且 NoWayOS 的一些开源部件也用在别的软件里，所以每个镜像都会列出它包含的每一个组件，让您可以读到它与旁边的系统有哪些共同之处。&lt;/p&gt;
&lt;p&gt;NoWayOS 正在开发中，所以这是它为之设计的角色，而不是它已经担当过的角色。&lt;a href=&quot;/zh/security#diverse-redundancy&quot;&gt;安全页面说明了它的依据&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;阿波罗的工程师带上第二套系统，并不是因为他们预计第一套会失效。他们带上它，是因为他们无法证明它不会失效，而且他们确保，无论是什么让第一套停下，在第二套里都找不到任何熟悉的东西。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>每次变更，我们都攻击自己的构建</title>
    <link href="https://www.nowayos.com/zh/journal/we-attack-our-own-build"/>
    <id>https://www.nowayos.com/zh/journal/we-attack-our-own-build</id>
    <published>2026-11-13T00:00:00Z</published>
    <updated>2026-11-13T00:00:00Z</updated>
    <summary>不可能失败的安全测试说明不了任何问题。所以 NoWayOS 的测试都配有专门为失败而构建的版本，它的关卡则放在拉取请求够不到的地方。</summary>
    <content type="html">&lt;p&gt;对任何安全测试，都有一个让人不舒服的问题：它失败过吗？一个从未失败过的测试之所以通过，可能是因为系统健全，也可能是因为这个测试什么都看不见。从外面看，两者一模一样。&lt;/p&gt;
&lt;p&gt;所以 NoWayOS 不只是测试自己的安全性。每次变更，它都会攻击它，并检查这些攻击被拦了下来。&lt;/p&gt;
&lt;h2 id=&quot;伸手去拿不属于自己的东西&quot;&gt;伸手去拿不属于自己的东西&lt;/h2&gt;
&lt;p&gt;NoWayOS 系统的每个部分都运行在 seL4 上各自的隔离舱里，只持有被授予它的东西。隔离测试会故意让探针越过这些边界。一个探针去读从未给过它的地址。一个探针去写它只能读的页面。一个探针持有的东西与用户界面完全相同，它试图写入显示的控制页面，而界面对这个页面只能读。另一个探针持有的东西与网络客户端完全相同，它试图写入网络驱动的内存。&lt;/p&gt;
&lt;p&gt;seL4 必须把它们全部拦下，而一个旁观的部分必须继续运行，不受任何影响。&lt;/p&gt;
&lt;h2 id=&quot;一个为失败而构建的测试&quot;&gt;一个为失败而构建的测试&lt;/h2&gt;
&lt;p&gt;接下来是转折。在用户界面的隔离测试旁边，有一个故意放宽了一项授权的变体：界面的替身得到了显示的私有页面。这个变体的测试&lt;strong&gt;必须失败&lt;/strong&gt;。如果它哪天通过了，就说明隔离测试是瞎的，构建会指出这一点。&lt;/p&gt;
&lt;p&gt;同样的想法贯穿其余的检查。各部分之间消息的每个解码器，都有来自 Kani 模型检查器的有界证明，证明它绝不会 panic、溢出或越界读取。随后，变异检查会故意把解码器改坏，以表明这些证明能够察觉。每个处理外部输入的解析器，都用恶意数据做模糊测试。&lt;/p&gt;
&lt;p&gt;这一切都是 &lt;code&gt;make ci&lt;/code&gt; 的一部分，也就是每次变更都必须通过的关卡。隔离测试每次都运行；一项证明或一轮模糊测试，只要它覆盖的代码有变化，就会重新运行。&lt;/p&gt;
&lt;!-- slot --&gt;&lt;h2 id=&quot;够不到的关卡&quot;&gt;够不到的关卡&lt;/h2&gt;
&lt;p&gt;关卡的强度，取决于能改动它的那只手。因此，对 NoWayOS 的每一项贡献必须通过的检查，都定义在 &lt;strong&gt;Defence Agent&lt;/strong&gt; 里，这是一个独立的公开仓库。触及关卡的拉取请求会被标记出来，交给维护者。&lt;/p&gt;
&lt;p&gt;Defence Agent 也用同样的方式测试自己：二十个预先埋好的拉取请求，每一个都藏着审阅者可能漏掉的东西。有注释里隐藏的从右到左文本，有被换成相似的西里尔字母的一个字母，有直接从 git 仓库获取的依赖，有会运行不可信代码的工作流。每一个都必须被发现，而三个真实的历史变更必须通过。&lt;/p&gt;
&lt;h2 id=&quot;要证据-不要形容词&quot;&gt;要证据，不要形容词&lt;/h2&gt;
&lt;p&gt;这一切都不会让设备变得“无法被黑客攻破”。没有什么能做到这一点，我们也永远不会这样说。它给您的是证据：一份记录，写明尝试了什么、拦下了什么，以及能展示这一切的命令。请阅读&lt;a href=&quot;/zh/security#read-one-images-evidence&quot;&gt;一个真实镜像的证据&lt;/a&gt;，或者&lt;a href=&quot;https://github.com/NoWayOS/defence-agent&quot;&gt;这些关卡本身&lt;/a&gt;。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>证明能承诺什么</title>
    <link href="https://www.nowayos.com/zh/journal/what-a-proof-can-promise"/>
    <id>https://www.nowayos.com/zh/journal/what-a-proof-can-promise</id>
    <published>2026-11-13T00:00:00Z</published>
    <updated>2026-11-13T00:00:00Z</updated>
    <summary>测试尝试的是有人想到的情况。证明覆盖的是全部情况。seL4 的数学证明说了什么，假设了什么，NoWayOS 又站在哪里。</summary>
    <content type="html">&lt;p&gt;人们信任软件，通常是因为它经过了测试。有人想到它可能出错的方式，逐一尝试，看着它应付过去。这个办法很管用，直到遇上谁也没想到的那种情况。&lt;/p&gt;
&lt;p&gt;证明从另一头入手。它不去尝试各种情况。它用数学说明，一个命题在所有情况下都成立。&lt;/p&gt;
&lt;h2 id=&quot;所有情况-而不只是试过的情况&quot;&gt;所有情况，而不只是试过的情况&lt;/h2&gt;
&lt;p&gt;拿一个小小的承诺来说：这段代码绝不会读到缓冲区末尾之外。测试可以给它一千个输入，或者十亿个，然后报告说没有一个让它出错。证明说的是另一类话：不存在会让它出错的输入。不是没找到，而是没有。&lt;/p&gt;
&lt;p&gt;代价是严格。证明需要一份对代码应当做什么的精确陈述，也就是它的规约，还需要一个把代码每一行都与规约联系起来的论证。对真实的软件来说，这个论证长得没有人能凭肉眼检查。于是由计算机来检查。&lt;/p&gt;
&lt;!-- slot --&gt;&lt;h2 id=&quot;由机器检查&quot;&gt;由机器检查&lt;/h2&gt;
&lt;p&gt;这就是“经机器检查”的意思。证明被完整地写出来，使用一种名为证明助手的程序能够读懂的语言，由这个程序对照逻辑规则检查每一步。它不会在第九百页感到疲倦，也不会轻信任何人的话。&lt;/p&gt;
&lt;p&gt;seL4 的证明就是这样检查的，使用名为 Isabelle/HOL 的证明助手。这些证明是公开的，任何人都可以重新运行。&lt;/p&gt;
&lt;h2 id=&quot;sel4-的证明说了什么&quot;&gt;seL4 的证明说了什么&lt;/h2&gt;
&lt;p&gt;seL4 是每个 NoWayOS 系统运行其上的内核：约 10,000 行代码，也是唯一完全控制设备的代码。关键就在于它的规模。关于一万行代码的论证可以做完。关于数千万行代码的论证，目前还做不到。&lt;/p&gt;
&lt;p&gt;seL4 Foundation 分层&lt;a href=&quot;https://sel4.systems/Verification/proofs.html&quot;&gt;说明了这些证明&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码所做的就是规约所说的，仅此而已。&lt;/strong&gt; 由此可以得出一份内核做不到的事情的清单：缓冲区溢出、解引用空指针、内存泄漏、除以零。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实际运行的程序与被证明的代码一致。&lt;/strong&gt; 两者之间隔着编译器，所以另有一项证明检查编译器的输出。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内核能够把系统的各个部分隔开。&lt;/strong&gt; 一个部分不能修改另一个部分的数据，不能读取它，也不能夺走它所需的资源，除非被授予了这样的权利。&lt;/li&gt;
&lt;li&gt;**系统能够以设计时确定的状态启动，**所拥有的授权与其描述中列出的完全一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;并不是每一层都已针对每种处理器和每种配置完成。这一点很重要，后面还会谈到。&lt;/p&gt;
&lt;h2 id=&quot;证明视为理所当然的东西&quot;&gt;证明视为理所当然的东西&lt;/h2&gt;
&lt;p&gt;证明的范围与它的命题完全一样宽，并且建立在它的假设之上。seL4 把自己的假设写了下来：硬件的行为与其模型一致；最底层的几百行代码是正确的；内核启动之前运行的代码完成了它的工作。保密性的证明不涵盖时序。&lt;/p&gt;
&lt;p&gt;对于规约要求的是否是正确的东西，证明不置一词；对于内核之上的软件，也不置一词。经过证明的内核会忠实地隔离一个带有缺陷的程序。缺陷仍然在那里。它只是够不到别的任何东西。&lt;/p&gt;
&lt;p&gt;这不是证明的弱点。这正是它们的价值所在：它们精确地说明自己覆盖什么，于是您也就精确地知道还剩下什么。&lt;/p&gt;
&lt;h2 id=&quot;nowayos-的位置&quot;&gt;NoWayOS 的位置&lt;/h2&gt;
&lt;p&gt;直截了当地说：NoWayOS 运行在 seL4 之上，但目前没有任何 NoWayOS 镜像处于 seL4 已完成的证明范围之内。NoWayOS 使用 seL4 的混合关键性配置，针对我们所用处理器的证明仍在进行中。而 seL4 的证明从来就不覆盖 NoWayOS 自身的代码。所以我们不说 NoWayOS“经过形式化验证”，以后也不会这样说。&lt;/p&gt;
&lt;p&gt;每个镜像都会说明自己的位置。镜像旁边有一个文件，逐项列出其内核的配置，并与 seL4 已证明的配置对照。&lt;a href=&quot;/zh/security#what-sel4s-proofs-cover-and-what-they-dont&quot;&gt;安全&lt;/a&gt;页面展示了一个真实的例子。&lt;/p&gt;
&lt;h2 id=&quot;我们自己的-更小的证明&quot;&gt;我们自己的、更小的证明&lt;/h2&gt;
&lt;p&gt;NoWayOS 的代码通过另一条途径获得保障：Rust、隔离、评审、测试，以及一种更为朴素的证明。&lt;/p&gt;
&lt;p&gt;在系统各部分之间传递的消息，其每一个解码器都有&lt;strong&gt;有界证明&lt;/strong&gt;，由名为 Kani 的模型检查器完成。有界证明覆盖不超过规定大小的每一个输入，在这里是解码器所接受的最长记录。在这个界限之内，它是真正的证明：没有任何输入能让解码器发生 panic、溢出或越界读取。超出界限，它什么也不说，所以我们把界限定为可能出现的最长输入。&lt;/p&gt;
&lt;p&gt;然后我们故意把解码器改坏，以确认证明能够察觉。一个不可能失败的证明，并不比&lt;a href=&quot;/zh/journal/we-attack-our-own-build&quot;&gt;一个不可能失败的测试&lt;/a&gt;更有用。&lt;/p&gt;
&lt;h2 id=&quot;它实际的分量&quot;&gt;它实际的分量&lt;/h2&gt;
&lt;p&gt;证明不会让任何东西变得“无法被黑客攻破”。它让一个命题在所有情况下为真，而所依据的假设，您都可以读到。了解了命题和假设，您就知道自己手里有什么。&lt;/p&gt;
&lt;p&gt;正因如此，NoWayOS 构建在拥有这些证明的内核之上，并且逐个镜像地告诉您，这些证明覆盖到哪里。&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>为什么 NoWayOS 设备没有 Shell</title>
    <link href="https://www.nowayos.com/zh/journal/why-a-nowayos-device-has-no-shell"/>
    <id>https://www.nowayos.com/zh/journal/why-a-nowayos-device-has-no-shell</id>
    <published>2026-11-13T00:00:00Z</published>
    <updated>2026-11-13T00:00:00Z</updated>
    <summary>大多数专用设备都是一台通用计算机，上面放着一项任务，下面仍然留着其余的一切。我们走了另一条路：每台设备只用它的任务所需的东西来构建，其余的一概不放进去。</summary>
    <content type="html">&lt;p&gt;对专用设备的攻击，大多并不冲着它所做的那项工作。它们冲着的是设备所运行的那台计算机的其余部分：为维护而留下的 Shell，没人关掉的远程访问服务，应用背后的浏览器，一次崩溃之后就会露出来的桌面。&lt;/p&gt;
&lt;p&gt;这个“计算机的其余部分”无处不在。把读数从水厂送出去的网关，电网控制室里的终端，医院所依赖的设备，机器侧面的面板，车站大厅里的屏幕：其中许多运行的是通用操作系统，上面放着一项任务，下面的其余一切都还在，只是被设置关掉了。自助终端模式是其中最简单的一种。每一次失陷，都是有人找到了被漏掉的那一项设置。&lt;/p&gt;
&lt;h2 id=&quot;不如干脆不放进去&quot;&gt;不如干脆不放进去&lt;/h2&gt;
&lt;p&gt;NoWayOS 从另一头入手。一个 NoWayOS 镜像里有设备的应用、这个应用用到的驱动，以及 seL4 微内核。清单到此为止。&lt;/p&gt;
&lt;p&gt;没有可以落入的 Shell，因为从来没有构建进去。没有可以猜密码的远程登录。没有可以逃逸过去的桌面。没有等着恶意页面的浏览器引擎。对于根本不存在的软件，您不可能把它的设置配错。&lt;/p&gt;
&lt;p&gt;以上说的都是操作系统。运行在它之上的应用是另一回事：只要任务需要，应用可以让它的用户登录，也可以登录到其他系统。它只是没有坐落在一个任何人都能登录的操作系统之上。&lt;/p&gt;
&lt;p&gt;我们把这称为 &lt;strong&gt;Single Purpose OS&lt;/strong&gt;：一台心无旁骛的计算机。&lt;/p&gt;
&lt;h2 id=&quot;而留下的部分是密封的&quot;&gt;而留下的部分是密封的&lt;/h2&gt;
&lt;p&gt;不放进去，只是一半。留下的每个部分（网络、屏幕、输入、应用）都运行在各自的隔离舱里，用 seL4 的术语说就是&lt;em&gt;保护域&lt;/em&gt;，只能触及被授予它的东西。网络驱动搬运数据包。显示驱动负责绘制。应用通过固定大小的消息与它们各自通信。&lt;/p&gt;
&lt;p&gt;每项授权都写在一个文件里，每行一个事实；如果系统与文件不一致，构建就会失败。这样构建，是为了让一个部分的故障留在那个部分之内。&lt;/p&gt;
&lt;h2 id=&quot;可是没有-shell-怎么修呢&quot;&gt;“可是没有 Shell，怎么修呢？”&lt;/h2&gt;
&lt;p&gt;工程师最先问的就是这个，问得有道理。您不会登录到 NoWayOS 设备的操作系统上：它没有账户，也就没有可以用来登录的身份。您构建一个新镜像，替换旧的。目前这意味着构建它并加载到开发板上；由设备检查、并能安全回退的签名更新，已经完成设计，正在路上。&lt;/p&gt;
&lt;p&gt;换来的是一台直接启动进入其唯一任务的设备，需要打补丁的东西少得多，可供攻击的东西也少得多。对于一个国家赖以运转的系统来说，这笔交换正是全部意义所在。&lt;/p&gt;
&lt;h2 id=&quot;请亲自看看&quot;&gt;请亲自看看&lt;/h2&gt;
&lt;p&gt;一个真实 NoWayOS 镜像的证据，包括它的授权文件、物料清单和 seL4 配置记录，都在我们的&lt;a href=&quot;/zh/security#read-one-images-evidence&quot;&gt;安全页面&lt;/a&gt;上。无需注册，没有脚本。只有这些文件。&lt;/p&gt;
</content>
  </entry>
</feed>
