理解Linux下的SELinux

长久以来,每当遇到授权问题或者新安装的主机,我的第一反应是通过setenforce 0命令禁用SElinux,来减少产生的权限问题,但是这并不是一个良好的习惯 。这篇文章尝试对SELinux的基本概念和用法进行简单介绍,并且提供一些更深入的资料 。
Linux下默认的接入控制是DAC,其特点是资源的拥有者可以对它进行任何操作(读、写、执行) 。当一个进程准备操作资源时,Linux内核会比较进程和资源的UID和GID,如果权限允许,就可以进行相应的操作 。此种方式往往会带来一些问题,如果一个进程是以root的身份运行,也就意味着他能够对系统的任何资源进行操作,而且不被限制 。假如我们的软件存在漏洞呢?这个往往是一个灾难性的问题 。因此,就引出了另外的一种安全接入控制机制mac,Linux下的一种现实是SELinux,也就是我们将要讨论的内容 。
基本概念Mandatory Access Control (MAC)SELinux 属于MAC的具体实现,增强了Linux系统的安全性 。MAC机制的特点在于,资源的拥有者,并不能决定谁可以接入到资源 。具体决定是否可以接入到资源,是基于安全策略 。而安全策略则是有一系列的接入规则组成,并仅有特定权限的用户有权限操作安全策略 。
一个简单的例子,则是一个程序如果要写入某个目录下的文件,在写入之前,一个特定的系统代码,将会依据进程的Context和资源的Context查询安全策略,并且根据安全策略决定是否允许写入文件 。
Flask Security ArchitectureSELinux的软件设计架构是参照Flask,Flask是一种灵活的操作系统安全架构,并且在Fluke research operating system中得到了实现 。Flask的主要特点是把安全策略执行代码和安全策略决策代码,划分成了两个组件 。安全策略决策代码在Flask架构中称作Security Server 。除了这两个组件以外,另外一个组件Vector Cache(AVC), 主要提供策略决策结果的缓存,以此提高Security Server的性能 。其具体执行流程为,安全策略执行代码通过AVC查询Security Server的安全策略决策结果,并将其缓存以备下次使用 。

理解Linux下的SELinux

文章插图
 
The Flask Security Architecture: System Support for Diverse Security Policies
Linux Security Module前面两部分介绍了MAC机制和Flask架构,最终SELinux的实现是依赖于Linux提供的Linux Security Module框架简称为LSM 。其实LSM的名字并不是特别准确,因为他并不是Linux模块,而是一些列的hook,同样也不提供任何的安全机制 。LSM的的重要目标是提供对linux接入控制模块的支持 。
理解Linux下的SELinux

文章插图
 
Linux Security Module Framework
 
LSM 在内核数据结构中增加了安全字段,并且在重要的内核代码(系统调用)中增加了hook 。可以在hook中注册回调函数对安全字段进行管理,以及执行接入控制 。
SELinuxSecurity Enhanced Linux(SELinux) 为Linux 提供了一种增强的安全机制,其本质就是回答了一个“Subject是否可以对Object做Action?”的问题,例如 Web服务可以写入到用户目录下面的文件吗?其中Web服务就是Subject而文件就是Object,写入对应的就是Action 。
依照上面的例子,我们引入了几个概念,分别是Subject、Object、Action、以及例子没有体现出来的Context:
  • Subject: 在SELinux里指的就是进程,也就是操作的主体 。
  • Object: 操作的目标对象,例如 文件
  • Action: 对Object做的动作,例如 读取、写入或者执行等等
  • Context: Subject和Object都有属于自己的Context,也可以称作为Label 。Context有几个部分组成,分别是SELinux User、SELinux Role、SELinux Type、SELinux Level,每个部分的具体含义,将在下一章介绍 。
用户程序执行的系统调用(例如读取文件),都要被SELinux依据安全策略进行检查 。如果安全策略允许操作,则继续,否则将会抛出错误信息给应用程序 。SELinux决策的同时还需要Subject和Object的Context信息,确定所属的User、Role和Type等信息,以此查询对应的安全策略进行决策 。SELinux同样也使用了AVC机制用于缓存决策结果,以此来提高性能 。
SELinux Context进程和文件都有属于自己的Context信息,Context分为几个部分,分别是 SELinux User、Role、Type 和一个可选的Level信息 。SELinux在运行过程中将使用这些信息查询安全策略进行决策 。