安全访问 - 第2章 MAC模型
Mandatory Access Control( 强制访问控制 ),简称MAC, 是在计算机安全领域中的一种访问控制类型,其原始定义来自可信计算机系统评估标准( TCSEC) :"是一种根据敏感度(由标签表示)限制对对象的访问的方法"。
操作系统通过这种访问控制来限制主体对对象执行操作的能力,主体通常是进程;对象是诸如文件、目录、网络端口、IO 设备等。主体和对象各有一组安全标签。每当主体尝试访问对象时,操作系统内核强制执行的授权策略会检查这些安全标签并决定是否可以进行访问。任何主体对任何对象的任何操作都会根据一组授权策略进行简称,以确定该操作是否被允许。
MAC的成熟实践主要有Linux的SELinux和Windows的MIC,以下我们以SELinux为参考,讲解MAC模型。
2.1 SELinux
2.1.1 什么是SELinux
安全增强型 Linux(SELinux)是一种采用安全架构的Linux 系统,它能够让管理员更好地管控哪些人可以访问系统。它最初是作为 Linux 内核的一系列补丁,由美国国家安全局(NSA)利用 Linux 安全模块(LSM)开发而成。
SELinux 于 2000 年发布到开源社区,并于 2003 年集成到上游 Linux 内核中。
2.1.2 为什么需要SELinux
回顾第1章我们介绍的权限三要素为:主体对哪个对象拥有什么访问策略。
在DAC模型中,对资源访问的主体是用户,没有对进程的行为做任何限制,假如当前用户是root组,该用户启动了Apache+MySQL的服务端程序对外提供WEB服务,如果黑客可以通过漏洞成功劫持该进程,则黑客可以对计算机中所有资源做任意操作,比如直接修改MySQL服务中的各种业务数据,这是非常严重的后果。
在SELinux中,对资源访问的主体为进程,在上面的例子中,我们可以将Apache进程的访问资源限定在指定的数据目录如 /data/apache中,这样即使黑客劫持Apache进程,即使root用户,也只能访问 /data/apache这个目录,没有权限访问MySQL的数据,无法破坏业务数据,因此提高了系统的整体安全性。
2.2.3 SELinux 如何工作
SELinux 为系统上的应用程序、进程和文件定义了访问控制。它使用安全策略(一组策略告诉 SELinux 什么可以访问或不可以访问)来强制执行策略允许的访问。
当称为主体的应用程序或进程请求访问对象(如文件)时,SELinux 会检查访问向量缓存,简称AVC(Access Vector Cache),其中缓存了主体和对象的权限决策。如果 SELinux 无法根据缓存的权限做出访问决策,它会将请求发送到安全服务器。安全服务器检查应用程序或进程和文件的安全上下文,从 SELinux 策略数据库应用安全上下文,然后授予或拒绝许可,决策作出后,会加入到AVC中。
SELinux 是一个标签系统,每个进程、文件/目录对象都有一个标签,甚至网络端口、设备和可能的主机名也有分配标签。我们编写策略来控制进程标签对对象标签(如文件)的访问,称之为策略(policy)。内核(kernel)负责执行策略,而这种强制执行就称为强制访问控制,简称MAC(Mandatory Access Control)。
2.2 概念
SeLinux的MAC实施由三个相对独立的子模型组成:分别为TE、MLS、MCS,我将详细介绍这三种模型。在学习下面三种模型之前,我们需要明确两个基本语言概念:类型(Type)和类别(Category )的区别?
汉语词典的解释:
类型 是由各种具有共同特征的事物或现象所形成的种类。
类别 是按种类的不同而做出的区别。
类型可以通过共同特征来准确识别对象,是客观存在的事实,是严谨的。而类别是一组主观认为的相似属性的对象,并不一定是客观事实,不严谨。
举个例子
-
路边有3只动物,我将它们的类型定义为猫,则它们必须是猫,是严谨的客观事实,所有人都能根据类型识别出它们到底是不是猫。还是这3只动物,我将它的类别划分为“活泼的”和“安静的”,但这个类别只是我主观观察的结果,是随意的,不一定是事实。
-
文件夹下有10个文件,我将它们的类型定义为图片,并将它们的类别划分为“自然风光”和“海洋世界”。这里的
图片类型
是客观事实,划分的图片类别
是主观定义。
因此当你需要对一些对象进行分类时,可以优先使用类型划分,这样比较准确,然后再考虑使用类别划分。
2.3 TE 模型
SELinux 主要模型称为类型强制,简称TE (Type enforcement) 。基本上,这意味着我们根据进程的类型定义进程的标签,并根据其类型定义文件系统对象的标签。
举个例子
以下充满活力和趣味的CAT/DOG系列示例来自RedHat工程师Daniel J Walsh和交互设计师Máirín Duffy,本文作者进行了一些中国化处理,感谢原文作者的优秀创作。
注:狗粮盘子上的字母Fido[fai.dow]是一只意大利流浪狗的名字,于1941年被一位名叫索里亚尼的砖窑工人收留,后来的两年间,Fido每个工作日都在公交站接送索里亚尼上下班。1943年第二次世界大战间,有一天意大利遭到盟军轰炸,索里亚尼阵亡,那天晚上,Fido 像往常一样出现在公交车站,但没有看到索里亚尼下车,Fido 后来回家了。但此后的十四年直到它去世的那一天,它每天都去车站,等着索里亚尼下车。
有一个叫做"宠物餐厅"的SELinux操作系统,有CAT和DOG两种动物,我们将CAT和DOG定义为进程类型,这是主体类型。
我们有它们想要与之交互的对象,称之为食物。为食物添加类型,CAT_CHOWN和DOG_CHOW,这是对象类型。
作为一名策略制定者,我会说猫有权限吃CAT_CHOWN食物,狗有权限吃DOG_CHOW食物。
在 SELinux 中,我们会在策略中编写此策略:
allow CAT CAT_CHOWN eat;
allow DOG DOG_CHOW eat;
使用这些策略,Linux内核将允许CAT进程吃标记类型为CAT_CHOWN的食物,而狗吃标记类型为DOG_CHOW的食物。
但是在 SELinux 系统中,默认情况下没有设定权限的所有访问对象的行为都会被拒绝。这意味着如果 DOG进程试图吃掉CAT_CHOWN ,内核会阻止它。
同样,CAT也不允许吃DOG_CHOW。
同理,在人类的网上银行生产环境中的例子:
我们将 Apache 进程标记为httpd_t类型 ,并将 Apache 的访问数据内容标记为httpd_sys_content_rw_t类型。假设我们将储蓄卡数据存储在标记为msyqld_data_t的 MySQL 数据库中。如果 Apache 进程被黑客入侵,黑客可以控制httpd_t 进程并被允许读写内容httpd_sys_content_rw_t。但是即使进程以 root 身份运行,黑客也不会被允许读取信用卡数据 ( mysqld_data_t )。
在这种情况下,SELinux 已经减轻了入侵带来的后果,提高了安全性。
2.4 MCS 模型
多类别模型,简称MCS (Multi-Category Security) ,是一种访问控制机制,是对TE的增强。用户使用类别分别标记进程和文件后,进程只能访问与其类别相同的的文件。
MCS用于进一步限制自由访问控制( DAC ) 和类型强制( TE ) 逻辑,假设现有的DAC和TE策略已允许访问 ,则只有有权访问此类别的用户才能访问标有该类别的文件。MCS 的目的是维护系统上的数据机密性。
举个例子
在TE模型的例子中,我们将CAT和DOG定义为主体类型,并且只能访问指定资源类型的CAT_CHOWN 和DOG_CHOW。
现在,如果有多个 DOGS(如Fido和Spot),但Fido比较调皮,偷吃了Spot的DOG_CHOW,因此我们要阻止Fido吃Spot的DOG_CHOW:
如果使用TE模型,我们需要分别为Fido这个主体和属于它的资源DOG_CHOW创建新类型,如果要阻止其他DOG的类似行为则需要为每个DOG和他们的DOG_CHOW创建新类型。但是随着后续DOGS数量的增加,这样的方式很快将变的混乱,因为一般情况所有的狗都拥有吃DOG_CHOW的权限,但却需要为它们中每一个调皮者定义不同的新类型,显然调皮者是独立权限不能继承DOG类型的通用权限了。理想情况下,我们是希望每一只DOG都只能吃属于自己的DOG_CHOW。
为了解决这个问题,我们开发了一种新的执法形式,我们称之为多类别安全 (MCS),这是基于TE的一种执法延伸。在 MCS 中,我们在TE基础上添加了标签的另一部分,将其附加应用于 DOG 主体和 DOG_CHOW 资源。现在我们将 DOG 进程标记为DOG:random1 (Fido) 和DOG:random2 (Spot)。
我们将狗食物标记为DOG_CHOW:random1 (Fido)和DOG_CHOW:random2 (Spot):
MCS 策略为:如果类型强制策略正常且随机 MCS 标签完全匹配,则允许访问,否则拒绝访问,于是:
Fido (DOG:random1) 试图吃CAT_CHOW:food被TE拒绝。
Fido (DOG:random1) 被允许吃DOG_CHOW:random1。
Fido (DOG:random1) 被拒绝吃 spot ( DOG_CHOW:random2 ) 的食物。
同理,在人类的虚拟机生产环境中的例子:
如果我们有一台运行大量虚拟机的服务器,其中一个被黑客入侵,我想防止它攻 击其他虚拟机和虚拟机镜像。
在TE中,KVM虚拟机被标记为svirt_t并且镜像被标记为svirt_image_t。我们有策略说svirt_t可以读取/写入/删除标记为svirt_image_t 的内容。
libvirt(虚拟机管理工具)不仅实现了TE分离,还实现了 MCS 分离,当 libvirt 即将启动虚拟机时,它会选择一个随机的 MCS 标签,如s0:c1,c2,然后将svirt_image_t:s0:c1,c2标签分配给虚拟机需要管理的所有数据内容。 最后,它以svirt_t:s0:c1,c2的形式启动虚拟机,SELinux 内核控制svirt_t:s0:c1,c2只能写入匹配的svirt_image_t:s0:c1,c2标签,不能写入其他任意标签如svirt_image_t:s0:c3,c4,即使虚拟机被黑客以root身份劫持。
2.5 MLS 模型
多层级模型,简称MLS(Multi-Level Security) ,是指强制实施Bell-LaPadula模型的安全方案,主要思想是根据数据层级的差别来控制流程。
Bell-LaPadula模型 (BLP) 是一种状态机模型,用于在政府和军事应用中实施访问控制,它由 David Elliott Bell和 Leonard J. LaPadula 在Roger R. Schell的指导下开发,以正式确定美国国防部的MLS策略,最终研究论文发表于 1976 年。
在MLS下,用户和进程称为Subject(主体),文件、设备和系统的其他组件称为Object(对 象)。主体和对象都标有安全层级,每个安全层级都由一个敏感度(s0~s15)和一个类别组成。获得机密许可的用户读写机密类别中的文档,但不能查看绝密的文件,而允许写入绝密的文档(在被许可的情况下),允许读取受限的和未分类的文档。
下图是美国国防部最初设计的许可层级,分为绝密(Top Secret)、机密(Secret)、受限的(Confidential )、未分类(Unclassified)。
下图显示了在“秘密”安全层级下运行的主体与具有不同安全层级的各种对象之间所有允许的数据流。
举个例子
我们现在不讨论不同的狗,而是讨论不同的品种。有一只灰狗和一只吉娃娃。
我们想让灰狗吃任何狗粮,但如果吉娃娃试图吃灰狗狗粮,它可能会窒息。
我们要将 Greyhound 标记为DOG:Greyhound并将其狗粮标记为DOG_CHOW:Greyhound, 并将 Chihuahua 标记为DOG:Chihuahua并将其食物标记为DOG_CHOW:Chihuahua。
使用 MLS 策略,我们让 MLS Greyhound 标签层级大于 Chihuahua 标签,这意味着DOG:Greyhound可以吃DOG_CHOW:Greyhound 和DOG_CHOW:Chihuahua。
但是DOG:Chihuahua不允许吃DOG_CHOW:Greyhound。
当然,DOG:Greyhound和DOG:Chihuahua通过TE仍然被阻止吃CAT_CHOW。
真实世界
有两台 Apache 服务器:一台作为httpd_t:TopSecret运行,另一台作为httpd_t:Secret运行。如果 Apache 进程httpd_t:Secret被黑客入侵,黑客可以读取httpd_sys_content_t:Secret 但无法读取httpd_sys_content_t:TopSecret。
如果运行httpd_t:TopSecret的 Apache 服务器被黑客入侵,它可以读取httpd_sys_content_t:Secret数据以及httpd_sys_content_t:TopSecret。
在军事环境中使用 MLS,可以允许用户查看机密数据,但同一系统上的另一个用户可以读取绝密数据。