访问控制是操作系统安全的基石,当前的操作系统已部署了很多访问控制的模型:Unix和windows NT多用户安全;SElinux中的类型执行;反恶意软件产品;Apple OS X,Apple IOS和google Android中的应用沙盒;以及面向应用程序的系统如FreeBSD中的Capsicum等。这种多样性是一种惊人的结果。
本质是本地化安全,将操作系统安全模型适应于本地或产品特定要求。这一转变是由三个变化所驱动的:无处不在的互联网连接;从专用嵌入式操作系统向通用操作系统的迁移,以寻求更复杂的软件堆栈;以及从多用户计算向单用户设备与复杂应用模型的普遍使用。这种转变得到了可扩展的访问控制框架的支持,这些框架允许操作系统内核更容易地适应新的安全要求。
其中一种可扩展内核访问控制框架是 TRustedBSD 的强制访问控制 (mac) 框架,它始于 2000 年,于 2003 年在开源的 FreeBSD 操作系统中发布。
嵌入式和移动操作系统在过去的20多年中发生了巨大变化:设备已经拥有运行通用操作系统的CPU能力,并被放置在网络环境中,持成熟的软件栈以及第三方应用程序,也暴露在恶意活动之下。供应商在现有开源操作系统的基础上构建,而不是从头开始。这提供了成熟的应用程序框架和复杂的网络堆栈,这两个领域都是“嵌入式操作系统”的弱点。
这种趋势在2007年得以实现,当时基于Linux的谷歌Android和部分基于Mach和FreeBSD的苹果iOS面世,从而改变了智能手机市场。
所有这些环境都注重安全性和可靠性,由于第三方应用程序在各种系统中部署,沙盒变得至关重要,首先是为了防止“变砖”,其次是为了限制恶意软件。因此,操作系统安全性的作用已经从保护多个用户之间转向保护单个用户或用户免受不可信应用的影响。嵌入式设备、移动电话和平板电脑现在成为交汇点:许多不同的利益相关者如消费者、电话供应商、应用程序作者和在线服务都必须借助于另一个空间和时间的操作系统来协调。
操作系统开发人员必须满足设备供应商的需求,这些需求包括路由器和防火墙的加固以及移动应用程序的沙箱化。操作系统供应商已经观察到历史上“可信任操作系统”的困境,其强制访问控制方案在可用性、性能、可维护性和最为重要的是最终用户需求方面都存在问题。同样,许多有前途的新安全模型,其可行性都不确定,这表明没有单一的访问控制模型能够满足所有需求。
这种本地化安全的实际现实直接推动了可扩展访问控制。在过去的20年中,已经明确了需要一个自包含、不可绕过、可验证的访问控制中心。在20世纪90年代初,这个概念已经与“封装”的概念结合起来,出现在“通用访问控制框架”中,并出现了“基于规则集的访问控制”以及“Flask安全架构”等。直到21世纪初,主流操作系统供应商才采用这些方法,例如FreeBSD的MAC框架以及Linux安全模块(LSM)。在这些情况下,一个关键问题是支持第三方安全模型,而不像早期的可信系统一样承诺固定的策略。
MAC框架于1999年提出,在2003年出现在FreeBSD 5.0中,作为一项“实验性功能”,默认情况下被编译排除,但可供早期采用者使用。2009年的FreeBSD 8.0将该框架作为“生产功能”编译到默认内核中。
MAC框架提供了一种逻辑解决方案,用于增强内核的访问控制。扩展基础设施能够代表许多不同的策略,提供了更好的可维护性,并得到操作系统厂商的支持。类似于设备驱动程序和虚拟文件系统(VFS)模块,策略被编译到内核或可加载模块中,并实现了定义良好的内核编程接口。策略可以增强访问控制决策,并利用常见的基础设施,例如对象标记,以避免直接内核修改和代码重复。它们能够在广泛的对象类型上执行访问控制,从文件到网络接口,并与内核的并发模型集成。
MAC是一种安全模型,其中强制策略限制所有系统用户的互动。与自主访问控制方案不同,如文件系统访问控制列表(ACL),允许对象所有者自行保护(或共享)对象,MAC则强制实施系统范围的安全不变量,而不考虑用户偏好。
早期的强制性政策侧重于信息流,要求在内核中实施。多级安全通过标记用户和数据机密性来保护安全性,限制流动。Biba完整性策略是MLS的逻辑对偶,保护其完整性。这些模型维护主题和对象的安全标签,持有机密性或完整性信息,并控制可能导致信息升级或降级的操作。SRI的可证明安全操作系统设计包括强制执行对象类型,补充能力保护。这演变成了类型强制执行以及域和类型强制执行,这些模型很有影响力,类型强制执行已部署在SELinux和McAfee的防火墙中。这两个模型都是灵活且细粒度的,用象征性的域和类型标记主题和对象。管理员控制规则授权并在域之间交互和转换。另外,还有一类特定于产品的加固策略,这些策略采用较少的原则性方法,直接控制服务而不是抽象模型。
在可扩展的访问控制之前有如下技术:
MAC框架的可扩展性访问控制和鼓励上下游供应商参与的双重目标,激发了几项设计原则:
不要承诺特定的访问控制策略。 没有针对单一策略甚至策略语言的共识;相反,用C代码捕获策略模型。
避免特定于策略的内核入侵。 将内部封装在策略无关的接口后面。这自然地导致了基于对象的设计,尤其是关于主体、对象和方法的访问控制检查。
提供策略无关的基础设施。 这满足了超越访问控制的常见要求,例如标记和跟踪。
支持多个同时加载的策略。 以此方式可以独立地表达策略的不同方面,可能来自不同的供应商。组合必须是可预测的、确定性的,理想情况下是合理的。
强制实施有助于保证论证的结构。 这可以通过引用监视器分离策略和机制以及通过明确定义的KPI语义(例如,锁定)来实现。
设计一个并发的内核。 策略不仅必须正确地行为,而且还必须与它们保护的功能相匹配。
如下图所示,MAC框架是一个薄层,将内核服务、策略和安全感知应用程序链接起来。控制从内核消费者通过大约250个入口点(对象类型x方法)传递到框架和策略:
图片
总体而言,这些接口允许策略以可维护的方式增强内核访问控制。
为了理解这些层如何相互作用,可以通过内核跟踪单个文件写入检查。
下面的代码展示了vnwrite,一个实现write和writev系统调用的VFS函数。macvnodecheckwrite内核服务入口点通过两个主体凭证(fp->fcred和启动写操作的activecred)授权对vnode(vp)进行写入。
static int
vn_write(struct file *fp, struct uio *uio,
struct ucred *active_cred, int flags,
struct thread *td)
{
...
vn_lock(vp, lock_flags | LK_RETRY);
...
#ifdef MAC
error = mac_vnode_check_write(active_cred,
fp->f_cred, vp);
if (error == 0)
#endif
error = VOP_WRITE(vp, uio, ioflag,
fp->f_cred);
...
VOP_UNLOCK(vp, 0);
...
return (error);
}
策略可以实现 能力语义或撤销语义。
vnode锁(vp->v_lock)在检查和使用期间保持,保护标签状态,并防止从检查到使用的时间竞争条件。
从入口点中排除的参数与包含的参数一样重要。例如,vn_write的数据指针(uio)被省略,因为这些数据位于用户内存中,不能在与写入相关的竞争条件下无风险地访问。框架中的类似设计选择阻止了不安全的行为,这些行为不能通过内核同步模型安全地表示。
在可能的情况下,最好从内核子系统实现标记对象的角度出发,并且可以通过对方法调用进行控制来执行策略。这种方法与内核的面向对象结构自然契合,一旦确定了对象,放置入口点就需要小心:KPI粒度越细,策略就可以越容易表达,这是以策略复杂度为代价。调用入口点越少,验证就越容易;然而,太少会导致保护不足。入口点设计还必须平衡将检查放置得足够深,以允许了解对象类型,同时最小化特定抽象级别的执行点。
许多访问控制策略为了支持访问控制决策(例如完整性或保密级别)而标记主体和对象。MAC框架为内核对象提供了与策略无关的标记工具、标记管理系统调用以及文件标记的持久化存储。策略控制标记语义,不仅存储字节,还包括内存模型。例如,策略可能存储每个实例、引用计数或全局数据。
图片
该框架使用 struct label 来表示标记存储,对于内核服务和策略来说是不透明的。在这个例子中,Biba将 低 完整性赋予新创建的套接字,从一个 低
下表描述了FreeBSD衍生的商业或开源产品中的策略。有许多因素促成了这一转变的成功:
该框架自2003年以来得到了多个公司的贡献,得到了长足的发展。
FreeBSD是一个开源操作系统,用于构建在线服务、设备和嵌入式设备。FreeBSD或其组件可在数据中心、集成产品和嵌入式/移动设备(Juniper交换机和Apple iphone)中找到。其起源可以追溯到20世纪70年代和80年代开发的伯克利软件发行版(BSD)。BSD起源于许多中心化的Unix技术,包括快速文件系统(FFS)和伯克利TCP/IP堆栈和套接字API。BSD许可证及其变体(MIT、CMU、ISC、Apache)通过允许无限制的商业使用来鼓励技术转换。FreeBSD的多样化消费者是本地化安全的完美目标。
MAC框架是一个复杂的软件,虽然框架本身只有8500行代码,参考策略也只有15000行,但它与一个几百万行的内核集成在一起。投入生产依赖于多个因素,包括对协调的信任增强以及针对设计、兼容性和性能的社区反馈。该框架作为FreeBSD 5.0中首次发布,被标记为“实验性”,具有几个含义:
合并该框架对于获得能够帮助验证和改进方法的用户至关重要,同时保留了进行更改的灵活性。在框架在生产就绪之前,需要解决两个问题:
FreeBSD规定,针对某个版本编译的某些内核模块必须与同一系列后续的次要版本一起工作。目标是避免破坏消费者子系统的内核二进制接口,并为策略模块提供类似的二进制兼容性。子系统和策略的标签存储不透明性是改进的主要领域,这避免了将内核数据结构中的细节编码到策略中,如果它们仅需要标签访问,则提供了灵活性来更改标签。
许多FreeBSD部署非常敏感于性能,需要最小的开销,特别是如果禁用了该框架的话。由于站点根据本地安全性能权衡选择策略,因此,希望策略只产生他们实际使用功能的性能惩罚。然而,在FreeBSD 5.0中,衡量结果是可测量的,这是默认启用框架的障碍。
即使从框架中编译出来,添加标签到内核数据结构(特别是数据包mbufs)的膨胀也会导致显著的分配时间成本。在FreeBSD 5.1中,内联的mbuf标签被替换为指针,这减少了非MAC内核的成本,但增加了MAC启用内核的分配和间接成本。
标签分配在启用框架时更加可测,并且对于未标记的策略是不必要的。这种影响在网络数据包中最为明显,并在FreeBSD 5.1中引入了每个策略标志来请求数据包标签。在8.0中,这种方法被一般化,以便仅为至少一个加载的策略定义了初始化入口点的对象类型分配标签。这有效地消除了不需要策略时的标记成本,恢复了性能比例,并满足了一般情况。然而,使用数据包标记的一个商业产品McAfee Sidewinder Firewall看到足够的开销来绕过标记抽象,而采用了直接结构修改的方法。
已编译的框架中,入口点调用时受锁保护的引用计数操作对于频繁操作(如每个数据包的交付检查)非常容易测量。随着多核硬件变得越来越普遍,锁争用也变得显著起来。
从FreeBSD 5.2开始,策略被分为静态和动态集,以帮助固定配置的嵌入式系统。前者在编译或引导时被编译或加载,并在此后可卸载,因此不需要同步。动态策略在引导后加载或卸载仍然需要多个锁操作。
在FreeBSD 8.0中,同步进一步进行了优化,以便MAC框架可以在默认内核中运行。这项工作受益于内核可扩展性的持续改进,特别是“读多写少锁”,它不会在只读获取期间触发缓存行迁移,代价是更昂贵的独占获取,但非常适合不经常更改的策略列表。
苹果在2007年相继发布了桌面版的Leopard版本,以及在2008年为iPhone和iPod Touch发布的iPhone OS 2版本,该版本将MAC框架作为参考监控框架。OS X Snow Leopard带有三种MAC策略:
在OS X MountAIn Lion中,通过Apple的应用商店分发的应用程序必须进行强制沙箱化。苹果的iOS 2.0带有两个策略:沙箱和一个额外的策略。Apple移动文件完整性(AMFI)。与代码签名工具一起使用,终止数字签名在运行时被取消验证的应用程序;在应用程序开发期间免除调试。
这些策略共同支持系统完整性,并在应用程序之间提供强大的隔离,以保护数据的隐私性。OS X和iOS都与MAC框架的设计期望有很大差异,进行了重大的适应性修改。
苹果公司在2000年开始测试OS X的beta版,一个具有开源内核的商用桌面操作系统的承诺难以忽视。XNU内核是卡内基梅隆大学的Mach微内核、FreeBSD 5.0、一些较新的FreeBSD元素以及苹果公司开发的众多特性的复杂融合。有了这些基础,MAC框架方法和甚至代码是可重用的。
虽然不是微内核,XNU采用了许多Mach的元素,包括其调度程序、进程间通信模型和VM系统。FreeBSD的进程模型、IPC、网络堆栈和VFS被嫁接到Mach上,提供了丰富的Posix编程模型。OS X第一个版本中苹果公司开发的内核组件包括了I/O Kit设备驱动程序框架、网络内核扩展和HFS+文件系统;这个列表随着时间的推移一直在增长。从2003年到2007年,日益成熟的MAC框架被移植到了OS X上。
MAC框架需要对FreeBSD内核进行详细分析,并与低级内存管理和同步以及更高级的服务(如文件系统、IPC和网络堆栈)紧密集成。虽然适应OS X可以大量依赖苹果公司使用的FreeBSD组件,但需要进行根本性的变革以反映FreeBSD和XNU之间的差异。
第一步是将MAC框架与紧密对齐的BSD进程模型、文件系统和网络堆栈集成。高层次的架构对齐使得一些适配变得容易,但也遇到了一些差异。例如,FreeBSD的Unix文件系统认为目录是专门的文件对象,而HFS+则认为目录和对象属性结构或磁盘目录是一级对象。这要求对框架和XNU进行更改。
接下来,覆盖范围扩展到包括Mach任务和IPC。每个XNU进程将Mach任务(调度、VM)与FreeBSD进程链接在一起,提出了一个问题:MAC框架是Mach还是BSD的一部分?虽然在架构上有用,但XNU中的Mach-BSD边界是人为的,引用经常跨层,要求MAC框架同时服务于两者。在BSD进程标签上的标签修改被映射到相应的Mach任务标签上。
Mach端口是另一种微内核与MAC框架的单内核前提相冲突的情况。与由内核管理名称空间的BSD IPC对象不同,Mach端口依赖于由launchd(例如,用于桌面IPC)管理的用户空间名称空间。类似于内核标签结构的用户空间标签句柄抽象用于此目的。
苹果是世界上最大的桌面系统供应商之一,也是最早在智能手机中部署类Unix系统的公司之一。由于普遍的网络化和恶意攻击者的存在,同样遇到了爆炸性的用例和新的安全要求。然而,苹果对MAC框架的采用并不确定,因为竞争技术也被考虑在内,这些技术受到类似的观察、未来产品方向、性能问题。替代方案包括基于系统调用插入的技术,以及苹果的Kauth3(内核授权),这是一个针对杀毒软件供应商的授权框架。苹果发现了关于系统调用插入的不可靠性的争论,并最终采用了两种技术:Kauth用于第三方杀毒软件供应商,以及更具表现力和能力的MAC框架,用于其自己的沙箱技术。
沙盒策略 由于苹果的OS X和iOS策略模块不是开源的,因此无法考量它们的实现,但是针对Mac OS 组件和第三方应用程序(例如Google的Chrome Web浏览器)使用的Sandbox策略存在着参考文档。Sandbox允许应用程序自愿限制其对资源的访问(例如文件系统、IPC名称空间和网络)。进程沙箱配置文件存储在进程标签中。
通过公共API或sandbox-exec助手程序可以设置字节码编译的策略。应用程序可以从几个苹果定义的策略(如下表)中选择,或定义自定义策略。几个应用程序使用默认策略,例如视频编解码器,它使用配置文件限制与主机进程的IPC。
图片
Chrome使用的common.sb配置文件说明了关键的Sandbox构造:sysctl内核管理接口和共享内存的粗略控制,以及文件路径的精细正则表达式匹配。基于文件路径的控制是Sandbox策略的亮点,比Biba、MLS和TE中的文件标签更好地解决了程序模型。
基于路径的方案在VFS模型上很难实现,虽然FreeBSD允许文件具有一个或多个名称(硬链接),但HFS+为文件实现了父指针,并确保名称缓存始终包含正在使用文件的明确路径所需的信息。
虽然Sandbox与许多Mac OS服务一起使用,但许多第三方应用程序包含环境权限的强烈假设,即能够访问系统中的任何对象。通过iPhone,苹果打破了这种假设:应用程序在与系统服务和彼此隔离的情况下执行。这种模型现在出现在OS X中,同样可以帮助保护设备完整性,防止应用程序的恶意行为和日益增多的最终用户数据。
性能优化
在FreeBSD 8.0的性能优化之前,OS X和iOS使用的是MAC Framework,需要苹果基于产品特定的限制进行自己的优化。
与FreeBSD优化类似,这些优化通常关注框架入口和标签的开销。默认情况下,对于某些对象类型,标签会在内核中被编译掉;对于其他类型,如vnodes,策略可能会有选择地请求标签分配,以适应MacOS策略中标签的稀疏使用。
在FreeBSD中,框架和同步优化依赖于愿意支付额外访问控制扩展。在Mac OS中,假设大多数机器都使用沙箱技术,但仅对高风险进程进行选择性应用。为此,每个进程都携带着由策略设置的掩码,指示哪些对象类型需要执行。随着沙箱技术普及,如在iOS中的情况,将应用进行了更全局的优化。
MAC框架已成为许多本地化安全实例的基础,允许本地访问控制策略与仍然流行的自主访问控制模型进行组合。开源部署是一种成功的策略,提供了协作改进的论坛,早期采用者的访问以及通往众多产品的途径。
行业对于用于设备和嵌入式设备的开源基础采用已得到很好的满足:
然而,MAC框架还需要改进和扩展以解决几个未预料到的问题:
考虑到与MAC框架的广泛实践,有如下几个新的设计原则:
为什么在操作系统策略的表达方面没有达成共识呢?显然,策略模型的支持者认为捕捉了系统设计的关键问题。首先,策略模型旨在以根据最小特权原则的不同形式(例如信息流与系统特权)捕捉其关键问题,使它们的方法互补;其次,不同的模型在多维权衡中解决了不同的领域问题,包括表达类型,保障,性能,管理复杂性,实现复杂性,兼容性和可维护性。这反映了对于领域特定的策略模型的共识。
需要进行重要的设计增强吗?这是否证实或拒绝了访问控制可扩展性的假设?进一步与类似的框架(如VFS和设备驱动程序)进行比较似乎是合适的,两者都经常扩展以适应新的要求,例如分布式文件系统的变化或电源管理的改进。管理重要的源代码库的上游-下游关系是一个强有力的动机因素。MAC框架的部署似乎证实了更普遍的论点,即访问控制可扩展性是当代操作系统设计的关键方面。
通过了解访问控制可扩展性和框架设计的背景和挑战,进而观察了几个产品在部署安全策略中的实践,包括 FreeBSD、Juniper 的 Junos 和 Apple 的 OS X 和 iOS。虽然访问控制的可扩展性是这些项目的关键所在,但它们对框架本身也带来了相当大的改变,最后尝试讨论了框架如何满足每个产品的要求,以及操作系统安全的持续演进。