SELinux是Security Enhaanced Linux 的英文缩写,字面上的意思就是安全强化的Linux
其实SELinux是在进行进程、文件等详细权限配置时依据的一个内核模块。由于启动网络服务的也是进程,因此刚好也是能够控制网络服务能否读写系统资源的一道关卡
传统的文件权限与账号的关系:自主访问控制(DAC)
系统中的账号一般分为系统管理员(root)和一般用户,它们能否使用系统上面的文件资源是与rwx的权限设置有关(权限设置对于root是无效的)。因此当某个进程想要对文件进行读写时,系统会根据该进程的拥有者和用户组来对比文件的权限,只有通过了权限检查,才可以读写该文件
基本上,就是依据进程的拥有者与文件资源的rwx权限来决定有无读写的权限
DAC的访问控制的缺点:
- root具有最高权限:如果有个进程不小心被有心人士获取,且该进程属于root,那么这个进程就可以在系统上执行任何资源的读写
- 用户可以获取进程来修改文件资源的访问权限:如果将目录的权限设置为777,那么任何人都具有rwx权限,因此该目录可以被任何人读写
以策略规则指定特点进程读取特定文件:强制访问控制(MAC)
我们针对的主体从用户变成了进程。此外,这个主体进程也不能任意使用系统文件资源,因为每个文件资源也针对该主体进程设置了可使用的权限
强制访问控制(MAC)可以针对特定的进程与特定的文件资源来管理权限。也就是说,即使是root身份,在使用不同的进程时,获取的权限也并不一定是root,而是要根据当时该进程的设置而定
SELinux提供了一些默认的策略(Policy),并在该策略内提供了多个规则(rule)来让我们选择是否启用该控制规则
SELinux的运行模式
SELinux时通过MAC的方式来管理进程,它控制的主体是进程,而目标则是该进程能否读取的文件资源
主体(Subject):SELinux主要管理的就是进程,因此可以把主体与进程划伤等号
目标(Object):主体进程能否读写的目标资源一般就是文件系统
策略(Policy):由于进程与文件数量庞大,因此SELinux会依据某些服务来制订基本的读写安全性策略,这些策略内还会有详细的规则(rule)来指定不同的服务是否开发某些资源的读写
在CentOS 7.x中仅提供三个主要的策略,分别是:
- targeted:针对网络服务限制较多,针对本机限制较少,是默认的策略
- minimum:有target自定义而来,仅针对选择的进程来保护
- mls:完整的SELinux限制,限制方面较为严格
安全上下文(security context):主体与目标的安全上下文必须一致才能顺利读写。这个安全上下文有点类似于文件系统的rwx,它的内容与设置是非常重要的,如果设置错误,你的某些服务(主体进程)就无法读写文件系统(目标资源),就会一直出现权限不符的错误信息
- 主体进程必须要通过SELinux策略内的规则放行后,才能与目标资源进行安全上下文的比对
- 若比对失败则无法读写目标,若比对成功则可以开始读写目标
- 最终能否读写目标还是与文件系统的rwx权限设置有关
安全上下文(security context)
对于策略我们只需要知道开启/关闭策略规则的放行即可,因为系统提供的策略已经为了我们制订好了很多规则,但安全上下文比较麻烦,因为我们可能需要自行配置文件的安全上下文,我们可以把SELinux的安全上下文比作文件系统的rwx权限设置,我们经常需要去修改它
安全上下文存在于主体进程与目标文件资源中,由于进程在内存中,所以主体进程的安全上下文可以存入,而文件的安全上下文是放置到文件的inode内的,因此主体程序想要目标文件资源时,同样需要读取inode,这inode内就可以对比安全上下文以及rwx等权限值是否正确
我们来查看一下安全上下文到底是怎么样的
安全上下文主要用冒号分成了三个字段
Identify:role:type
身份识别:角色:类型
身份识别(Identify)
相当于账号方面的身份识别,主要的身份识别有下面几种常见的类型:
- unconfined_u:不受限的用户,也就是说,该文件来自于不受限的进程。一般来说,我们使用可登录账号获取bash之后,默认的bash环境是不受SELinux管制的,因为bash并不是什么特别的网络服务。因此这个不受SELinux限制的bash进程所产生的文件,其身份识别大多就是unconfined_u这个不受限用户
- system_u:系统用户,大部分就是系统自己产生的文件
基本上,如果是系统或软件本身所提供的文件,大多是system_u这个身份名称;而如果使我们用户通过bash自己建立的文件,大多是不受限的unconfined_u身份;如果是网络服务所产生的文件、或是系统服务运行过程产生的文件,则大部分的识别就会是system_u
角色(Role)
通过角色字段,我们可以知道这个数据是属于进程、文件资源还是代表用户,一般的角色有:
- object_r:代表的是文件或是目录等资源,这应该是最常见的
- system_r:代表的就是进程,不过一般用户被指定成为system_r
你会发现角色字段的最后都会用_r来结尾,这是因为是role的意思
类型(Type)(最重要)
在默认的targeted策略中,Identifity与Role字段基本上是不重要的,重要的是类型(type)字段,基本上,一个主题进程能不能读取到这个文件资源与类型字段有关,而类型字段在文件与进程方面的定义又不太相同,分别是:
- type:在文件资源(Object)上面称为类型(Type)
- domain:在主体进程(Subject)则称为域(Domain)
进程与文件SELinux类型字段的相关性
通过身份识别和角色字段的定义,我们可以大概知道某个进程代表的意义
基本上,这些数据在targeted策略下的对应如下:
身份识别 | 角色 | 该对应在targeted的意义 |
unconfined_u | unconfined_r | 一般可登录用户的进程,比较没有受限的进程之意。大多数都是用户已经顺利登陆系统(不论是网络还是本机登录来获取可用的shell)后,所用来操作系统的进程,如bash、X Window相关软件等 |
system_u | system_r | 由于是系统账号,因此是非交互式的系统运行程序,大多数的系统进程均是这种类型 |
在默认的target策略下,其实最重要的字段是类型字段(type),主体与目标之间是否具有可以读写的权限,与进程的domain及文件的type有关
这两者的关系,我们用下面的例子来说明:
1、先看看crond这个进程的安全上下文内容
可以看出crond进程的安全上下文的类型名称为crond_t
2、再看看执行文件、配置文件的安全上下文内容
当我们执行/usr/sbin/crond之后,这个程序变成的进程的domain类型会是crond_t,而这个crond_t能够读取的配置文件则是system_cron_spool_t这种类型。因此无论是/etc/crontab、/etc/cron.d还是/var/spool/cron(类型为user_con_spool_t)都会是相关的SELinux类型
上图的意义我们可以这样看:
- 首先,我们触发一个可执行的目标程序,既具有crond_exec_t这个类型的/usr/sbin/crond文件
- 该文件的类型会让这个文件所造成的主体进程(Subject)具有crond这个域(domain),我们的策略针对这个域已经制定了许多规则,其中包括这个域可读取的目标资源类型
- 由于crond domain被设置为可以读取system_cron_spool_t这个类型的目标文件(Object),因此你的配置文件放到/etc/cron.d目录下,就能够被crond这个进程所读取了
- 但最终能不能读取到正确的数据,还是要看rwx是否符合Linux权限的规范