16.5.1 什么是 SELinux
SELinux是“ Security Enhanced Linux ”的缩写,字面上的意义就是安全强化的 Linux。
当初设计的目标:避免资源的误用
SELinux 是由美国国家安全局 (NSA) 开发的,当初开发这玩意儿的目的是因为很多企业界发现, 通常系统出现问题的原因大部分都在于“内部员工的资源误用”所导致的,实际由外部发动的攻击反而没有这么严重。 那么什么是“员工资源误用”呢?举例来说,如果有个不是很懂系统的系统管理员为了自己设置的方便,将网页所在目录 /var/www/html/ 的权限设置为drwxrwxrwx 时,你觉得会有什么事情发生?
传统的文件权限与帐号关系:自主式存取控制, DAC
系统的帐号主要分为系统管理员 (root) 与一般用户,而这两种身份能否使用系统上面的文件资源则与 rwx 的权限设置有关。 不过你要注意的是,各种权限设置对 root 是无效的。因此,当某个程序想要对文件进行存取时, 系统就会根据该程序的拥有者/群组,并比对文件的权限,若通过权限检查,就可以存取该文件了。
这种存取文件系统的方式被称为“自主式存取控制 (Discretionary Access Control, DAC)”,基本上,就是依据程序的拥有者与文件资源的 rwx 权限来决定有无存取的能力。 不过这种DAC 的存取控制有几个困扰,那就是:
root 具有最高的权限:如果不小心某支程序被有心人士取得, 且该程序属于 root 的权限,那么这支程序就可以在系统上进行任何资源的存取。
使用者可以取得程序来变更文件资源的存取权限:如果你不小心将某个目录的权限设置为 777 ,由于对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取。
以政策规则订定特定程序读取特定文件:委任式存取控制, MAC
我们知道 DAC 的困扰就是当使用者取得程序后,他可以借由这支程序与自己默认的权限来处理他自己的文件资源。 万一这个使用者对 Linux 系统不熟,那就很可能会有资源误用的问题产生。为了避免 DAC 容易发生的问题,因此 SELinux 导入了委任式存取控制(Mandatory Access Control, MAC) 的方法。
左图是没有 SELinux 的 DAC 存取结果,apache 这只 root 所主导的程序,可以在这三个目录内作任何文件的新建与修改,右边则是加上 SELinux 的 MAC 管理的结果,SELinux 仅会针对 Apache 这个“ process ”放行部份的目录, 其他的非正规目录就不会放行给 Apache 使用。
16.5.2 SELinux 的运行模式
SELinux 是通过 MAC 的方式来控管程序,他控制的主体是程序, 而目标则是该程序能否读取的“文件资源”!
主体 (Subject): SELinux 主要想要管理的就是程序,因此你可以将“主体”跟本章谈到的 process 划上等号;
目标 (Object): 主体程序能否存取的“目标资源”一般就是文件系统。因此这个目标项目可以等文件系统划上等号;
政策 (Policy): 由于程序与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的规则 (rule) 来指定不同的服务开放某些资源的存取与否。在目前的 CentOS 7.x 里面仅有提供三个主要的政策,分别是:
targeted:针对网络服务限制较多,针对本机限制较少,是默认的政策;
minimum:由 target 修订而来,仅针对选择的程序来保护!
mls:完整的 SELinux 限制,限制方面较为严格。建议使用默认的 targeted 政策即可。
安全性本文 (security context): 我们刚刚谈到了主体、目标与政策面,但是主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。 这个安全性本文 (security context) 有点类似文件系统的 rwx。
由于 SELinux 重点在保护程序读取文件系统的权限,因此我们将上述的几个说明搭配起来,绘制成下面的流程图,比较好理解:
上图的重点在“主体”如何取得“目标”的资源存取权限! 由上图我们可以发现,(1)主体程序必须要通过 SELinux 政策内的规则放行后,就可以与目标资源进行安全性本文的比对,(2)若比对失败则无法存取目标,若比对成功则可以开始存取目标。问题是,最终能否存取目标还是与文件系统的 rwx 权限设置有关。如此一来,加入了 SELinux 之后,出现权限不符的情况时,你就得要一步一步的分析可能的问题了!
安全性本文 (Security Context)
CentOS 7.x 的 target 政策已经帮我们制订好非常多的规则了,因此你只要知道如何打开/关闭某项规则的放行与否即可。 那个安全性本文比较麻烦!因为你可能需要自行设置文件的安全性本文呢!为何需要自行设置啊? 举例来说,你不也常常进行文件的 rwx 的重新设置吗?这个安全性本文你就将他想成 SELinux 内必备的 rwx 就是了。
安全性本文存在于主体程序中与目标文件资源中。程序在内存内,所以安全性本文可以存入是没问题。 那文件的安全性本文是记录在哪里呢?事实上,安全性本文是放置到文件的inode 内的,因此主体程序想要读取目标文件资源时,同样需要读取 inode , 这 inode 内就可以比对安全性本文以及 rwx 等权限值是否正确,而给予适当的读取权限依据。
那么安全性本文到底是什么样的存在呢?我们先来看看 /root 下面的文件的安全性本文好了。观察安全性本文可使用“ ls -Z ”去观察如下:
如上所示,安全性本文主要用冒号分为三个字段,这三个字段的意义为:
身份识别 (Identify):
相当于帐号方面的身份识别!主要的身份识别常见有下面几种常见的类型:
unconfined_u:不受限的用户,也就是说,该文件来自于不受限的程序所产生的!一般来说,我们使用可登陆帐号来取得 bash 之后, 默认的 bash 环境是不受 SELinux 管制的,因为 bash 并不是什么特别的网络服务!因此,在这个不受 SELinux 所限制的 bash程序所产生的文件, 其身份识别大多就是 unconfined_u 这个“不受限”用户。
system_u:系统用户,大部分就是系统自己产生的文件。
基本上,如果是系统或软件本身所提供的文件,大多就是 system_u 这个身份名称,而如果是我们用户通过 bash 自己创建的文件,大多则是不受限的 unconfined_u 身份~如果是网络服务所产生的文件,或者是系统服务运行过程产生的文件,则大部分的识别就会是 system_u。
系统安装主动产生的 anaconda-ks.cfs 及 initial-setup-ks.cfg 就会是 system_u,而我们自己从网络上面抓下来的 regular_express.txt 就会是 unconfined_u 这个识别。
角色 (Role):
通过角色字段,我们可以知道这个数据是属于程序、文件资源还是代表使用者。一般的角色有:
object_r:代表的是文件或目录等文件资源,这应该是最常见的
system_r:代表的就是程序
类型 (Type)
在默认的 targeted 政策中, Identify 与 Role 字段基本上是不重要的!重要的在于这个类型(type) 字段! 基本上,一个主体程序能不能读取到这个文件资源,与类型字段有关!而类型字段在文件与程序的定义不太相同,分别是:
type:在文件资源 (Object) 上面称为类型 (Type);
domain:在主体程序 (Subject) 则称为领域 (domain) 了
domain 需要与 type 搭配,则该程序才能够顺利的读取文件资源。
程序与文件 SELinux type 字段的相关性
基本上,这些对应数据在 targeted 政策下的对应如下:
如上所述,在默认的 target 政策下,其实最重要的字段是类型字段 (type), 主体与目标之间是否具有可以读写的权限,与程序的 domain 及文件的 type 有关!这两者的关系我们可以使用 crond 以及他的配置文件来说明! 亦即是 /usr/sbin/crond, /etc/crontab, /etc/cron.d等文件来说明。
上图的意义我们可以这样看的:
1. 首先,我们触发一个可执行的目标文件,那就是具有 crond_exec_t 这个类型的/usr/sbin/crond 文件;
2. 该文件的类型会让这个文件所造成的主体程序 (Subject) 具有 crond 这个领域(domain), 我们的政策针对这个领域已经制定了许多规则,其中包括这个领域可以读取的目标资源类型;
3. 由于 crond domain 被设置为可以读取 system_cron_spool_t 这个类型的目标文件(Object), 因此你的配置文件放到 /etc/cron.d/ 目录下,就能够被 crond 那支程序所读取了;
4. 但最终能不能读到正确的数据,还得要看 rwx 是否符合 Linux 权限的规范!
上述的流程告诉我们几个重点,第一个是政策内需要制订详细的 domain/type 相关性;第二个是若文件的 type 设置错误, 那么即使权限设置为 rwx 全开的 777 ,该主体程序也无法读取目标文件资源。
从上面的测试案例来看,我们的配置文件确实没有办法被 crond 这个服务所读取喔!而原因在登录文件内就有说明, 主要就是来自 SELinux 安全本文 (context) type 的不同所致。