操作系统设计/安全演变:能力
参与者是指可能执行操作的实体。这通常是用户、进程、线程或类似的实体。
被执行者或对象是指可能被参与者操作的实体。它可能是文件、注册表项、关系数据库条目、硬件设备或类似的实体。通常,它是数据。参与者通常也可以作为对象;一个进程(作为参与者)可以杀死另一个进程(作为对象)。
操作或权限是指参与者可以对对象执行的操作。示例操作包括读取和写入。
安全系统通常实现一个有用的三维矩阵子集,矩阵的维度是参与者、对象和操作。出于性能和可用性的原因,永远不会实现完整的矩阵。
主流操作系统安全主要基于访问控制列表。对于每个对象,我们可以维护一个参与者列表,这些参与者可以操作它。
基于能力的系统(不要与将特殊管理能力称为能力的系统混淆)以另一种方式反转了这些东西。对于每个参与者,他们维护一个对象列表,参与者可以对其进行操作。
主流操作系统安全是可选择的。也就是说,对象所有者可以决定谁可以访问该对象。
强制访问控制是非可选择的。一组规则用于执行安全,设置用户无法覆盖的权限。这可以阻止内部人员成为有效的间谍,将设计出售给竞争对手,与媒体分享医疗记录,运行间谍软件,以及防止许多类型的用户错误。
上述方法中没有一个方法排除任何其他方法。DG/UX 具有能力、可选 ACL 和强制访问控制。Linux 提供可选 ACL 和几种强制访问控制选择。所有类 Unix 系统上都可用的文件描述符可以用作能力。
第一次安全尝试是保护方案,它控制程序访问敏感区域,例如第 0 页(通常存储操作系统调用的软件中断以进行高效调用)或操作系统区域(操作系统代码在运行时保留的地方)。这种能力是分时必不可少的,因为新手程序员有时会覆盖操作系统,导致整个计算机关闭,因为他们不理解寻址系统。像 Z80 这样的 CPU 开始被设计为设置 aside "系统" 区域,以便它们不会被错误地覆盖。
一种方法是为系统创建单独的命名空间并控制对它的访问。通常,访问受保护模式的文档很少,或者在流行的书籍中缺失,试图通过模糊性来保护它。事实证明,这相对毫无用处,因为它意味着为信息创建了地下市场,只有破解者才能确定他们是如何入侵操作系统的。
一些 CPU 将复杂的软件中断设置为受保护模式内存和用户区域之间的网关。每个用户区域都有自己的软件中断区域,该区域对受保护的系统区域执行系统调用,因为中断区域位于用户空间,因此中断向量可以随意覆盖,而不会影响任何其他程序对操作系统的使用。这是一个有用的机制,因为外围驱动程序倾向于为特定外围设备提供自己的中断服务例程。
像 Windows 这样的应用程序可以创建其自身的虚拟化版本,并修改该单个虚拟版本中的中断,而不会影响操作系统的其余部分。这通常是 286 和 386 受保护模式之间的区别,Windows 的虚拟副本具有修改其自身中断向量而不影响机器其余部分的能力。在 386 受保护模式之前,所有程序共享相同的中断向量,一个程序的错误处理或恶意软件对中断的破坏可能会导致整个系统崩溃。
传统的 Unix 访问控制是一种可选 ACL。许多可能的动作被归类为四类:读取、写入、执行和特殊操作,这些操作通常保留给对象所有者。与每个对象相关联的参与者列表相当受限,简化了实现和用户体验。列出了三个参与者:所有者、组和其他。参与者获得其符合条件的第一个参与者的权限。所有者始终获得其他人没有的特殊操作。组是对其他地方指定的参与者列表的间接引用,因此是一种压缩形式。“其他”就是这样,所有其他参与者。通过创建组,传统的 Unix 访问控制可以提供很大的力量。但是,创建组通常有限制,通常需要人类批准的管理操作。
动作类别可能或多或少细粒度。Netware 使用读取、写入、创建、擦除、修改、文件扫描、访问控制和管理员。系统可以将正常的“写入”类别分成覆盖和追加。系统可能缺乏“执行”类别,而是简单地要求读取访问权限来执行文件。
许多系统允许将相当任意的参与者列表与每个对象相关联。这包括 Windows、现代类 Unix 系统(包括 Linux)和 Netware。列表可能支持十几个条目或数百个条目,具体取决于性能和控制之间的良好折衷方案。
ACL 中的一个有趣创新是层次参与者。例如,VSTa OS 使用十进制、点分隔的参与者标识符。在这个方案中,用户 ID 是由点分隔的一系列十进制数字(例如,1.85.23.323.888),如果用户拥有一个用户 ID,该用户 ID 与对象的 user ID 一致,直到其结尾,那么用户拥有该对象。因此,例如,拥有 user ID 1.85.23 的用户将拥有分配给 1.85.23.323.888 的任何对象,而该对象本身(无论是其他用户还是程序)将无法访问 1.85.23 拥有的其他对象。此方案允许动态创建用户和子用户的层次结构。可以通过提供一种机制让类 Unix 系统的用户创建和控制组来实现与大量 POSIX 软件兼容的这种较弱的形式。
能力是不可伪造的对象引用,允许其持有者访问在该对象上定义的一组定义明确的操作。
有许多不同的东西可以作为能力。有被称为“密码”的人类可读能力,人们使用它。有实验性操作系统内核实现的扁平、低级、集中式能力。有 Kerberos 服务器授予的票证。有 Unix 风格的文件描述符,它们可以从一个进程传递到另一个进程以提供访问权限。
KeyKOS 和 EROS 等操作系统使用扁平、低级和高度集中式的能力,将人类有用的能力的实现留给更高级的层。
这种方案中的能力是**扁平的**,因为它们无法被查询。你无法向这样的能力询问诸如它何时被创建或被访问了多少次之类的信息。这些能力也不具备可以被修改的内部状态。通常,你可以从你拥有的能力中创建一个新的降级能力,但你不能降级或以任何方式改变原始能力本身。这些能力不是对象,而是原始数据类型。
这种方案中的能力是**低级的**,因为它们不提供高级的安全抽象。在 KeyKOS 中,能力只有两种类型:读和读写,尽管 KeyKOS 能力可以包含其他信息来实现服务级别和其他类似的功能。这种方案中的能力不会自然地聚合其他能力(一种非常简单且非常有用的安全抽象),必须人为地在它们之间创建一个唯一职责是聚合它们的中间对象。请注意,某些安全抽象(例如动态权限继承)在低级系统之上几乎无法实现。
这种方案中的能力是**集中化的**,因为内核,且仅内核,管理所有能力。而不是每个模块都导出自己的能力,内核中只有唯一的可用能力。这实际上是使用低级能力的结果。如果能力足够高级以提供消息传递服务,那么强迫每个模块使用所有通过单个受保护内核能力路由的二级能力是可行的。相反,KeyKOS 中的每个模块(称为域)最多只能访问 16 个在内核保护的特殊槽中且只能通过特殊调用访问的特殊能力。
传统的强制访问控制或**MAC**以美国政府处理机密信息的方式为模型。更具体地说,这是**强制敏感性控制**或**MSEN**。存在安全级别,如最高机密、机密、机密和非机密。存在基于知情权或特殊程序访问的类别。拥有机密访问权限的参与者禁止读取最高机密数据,但可能被允许写入它。(尽管可能存在额外的可选 ACL 来阻止这种情况)。你可能能够从较低的安全级别读取,并写入较高安全级别。可能存在污染的概念,允许拥有机密访问权限的参与者写入非机密数据,只要没有读取机密或机密数据。
强制完整性控制(**MINT**)则反过来,防止原始对象被垃圾污染。在这种情况下,所有参与者都允许读取最受信任的数据。尝试执行从不受信任的来源下载的内容的参与者将被阻止,或者将失去写入更受信任对象的权限。
更现代的系统将 MSEN 和 MINT 的功能结合到具有角色的状态转换模型中。当参与者执行操作时,它们的状态可能会改变。在具有基于角色的访问控制的类 Unix 系统中,执行新的可执行文件是状态转换发生的一个特别重要的点。基于角色的安全对于执行隐私法规(例如 HIPPA(美国医疗信息法)和欧盟隐私法)特别有用。这两种流行的实现是 SE Linux 和 RSBAC,两者都可用于 Linux。
国际网络的出现将安全问题扩展到操作系统的通常领域之外,扩展到通过网络进出系统的移动数据。模仿有效数据包的能力意味着数据可以在途中通过简单地重新路由有效数据包并用无效数据包替换它来更改。因此,安全不仅必须扩展到本地系统,还必须扩展到系统之间所有关键的通信。最初,通过将原始数据的摘要作为数据流的一部分发送来实现这些机制,假设更改后的数据包将不适合原始摘要。但是,发现摘要在密码学上不安全,可以被欺骗成认为数据是有效的,而实际上并非如此。此外,以明文发送数据意味着介入系统中的某人可以使用数据包嗅探器读取数据包,并了解信息是什么。
当确定了这一点时,想法变成了对数据进行加密保护,这至少可以希望减缓邮件的读取速度,并对摘要进行加密保护,以便它不会那么容易被欺骗。