什么是 SELinux
SELinux 是【Security Enhanced Linux】的缩写,字面上的意义就是安全强化的 Linux。
SELinux 是由美国国家安全局(NSA)开发的,开发原因:因为很多企业界发现,通常系统出现问题的原因大部分都在于【内部员工的资源误用】所导致的,实际由外部发动的攻击反而没有这么严重。
为了控管这方面的权限与进程的问题,所以美国国家安全局就着手处理操作系统这方面的控管。由于 Linux 是自由软件,程序代码都是公开的,因此她们便使用Linux来作为研究的目标,最后更将研究的结果整合到 Linux 核心里面去,那就是SELinux。
所以说,SELinux 是整合到核心的一个模块。
这也就是说:其实SELinux是在进行进程、文件等细部权限设定依据的一个核心模块。
传统的文件权限与账号关系:自主式访问控制, DAC
系统的账号主要分为系统管理员(root)与一般用户,而这两种身份能否使用系统上面的文件资源则与 rwx 的权限设定有关。不过要注意的是,各种权限设定对 root 是无效的。
因此,当某个进程想要对文件进行存取时,系统就会根据该进程的拥有者/群组,并比对文件的权限,若通过权限检查,就可以存取该文件了。这种存取文件系统的方式被称为【自主式访问控制(Discretionary Access Control, DAC)】,基本上,就是依据进程的拥有者与文件资源的 rwx 权限来决定有无存取的能力。
这种 DAC的访问控制有几个困扰,那就是:
1.root 具有最高的权限:如果不小心某支进程被有心人士取得,且该进程属于root 的权限,那么这支进程就可以在系统上进行任何资源的存取;
2.使用者可以取得进程来变更文件资源的访问权限:如果不小心将某个目录的权限设定为777,由于对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取;
因此 SELinux 导入了委任式访问控制(Mandatory Access Control, MAC)。
委任式访问控制(MAC) 可以针对特定的进程与特定的文件资源来进行权限的控管。也就是说,即使是root ,那么在使用不同的进程时,所能取得的权限并不一定是 root,而得要看当时该进程的设定而定。
如此一来,针对控制的【主体】变成了【进程】而不是使用者。此外,这个主体进程也不能任意使用系统文件资源,因为每个文件资源也有针对该主体进程设定可取用的权限。
如此一来,控件目就细的多了,但整个系统进程那么多、文件那么多,一项一项控制可就没完没了,所以SELinux也提供一些预设的政策(Policy),并在该政策内提供多个规则(rule),可以选择是否启用该控制规则。
简单的来说,针对 Apache 这个 WWW 网络服务使用DAC或 MAC 的结果来说,两者间的关系:
左图是没有 SELinux 的 DAC 存取结果,apache 这只 root 所主导的进程,可以在这三个目录内作任何文件的新建与修改;右边则是加上 SELinux 的 MAC管理的结果,SELinux 仅会针对 Apache 这个【process】放行部份的目录,其他的非正规目录就不会放行给 Apache 使用。因此不管是谁,都不能穿透MAC的框框。
SELinux 的运作模式
SELinux 是透过 MAC 的方式来控管进程,控制的主体是进程,而目标则是该进程能否读取的【文件资源】。
主体(Subject):
SELinux 主要想要管理的就是进程,因此可以将【主体】跟谈到的 process 划上等号;
目标(Object):
主体进程能否存取的【目标资源】一般就是文件系统。因此这个目标项目可以等文件系统划上等号;
政策(Policy):
由于进程与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的规则(rule)来指定不同的服务开放某些资源的存取与否。
在 CentOS 7.x 里面仅有提供三个主要的政策,分别是:
targeted:针对网络服务限制较多,针对本机限制较少,是预设的政策;
minimum:由 target 修订而来,仅针对选择的进程来保护;
mls:完整的 SELinux 限制,限制方面较为严格。
建议使用预设的 targeted 政策即可。
安全性本文(security context):
主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。这个安全性本文(security context)有点类似文件系统的 rwx,安全性本文的内容与设定是非常重要的,如果设定错误,某些服务(主体进程)就无法存取文件系统(目标资源),就会一直出现【权限不符】的错误讯息。
上图的重点在【主体】如何取得【目标】的资源访问权限。
(1)主体进程必须要通过 SELinux 政策内的规则放行后,就可以与目标资源进行安全性本文的比对;
(2)若比对失败则无法存取目标,若比对成功则可以开始存取目标。
最终能否存取目标还是与文件系统的 rwx 权限设定有关了。
安全性文本
CentOS 7.x 的 target 政策已经制订好非常多的规则了,因此只要知道如何开启/关闭某项规则的放行与否即可。这个安全性本文比较麻烦,因为可能需要自行配置文件案的安全性本文。
安全性本文存在于主体进程中与目标文件资源中。进程在内存内,所以安全性本文可以存入是没问题。
安全性本文是放置到文件的 inode 内的,因此主体进程想要读取目标文件资源时,同样需要读取 inode,这 inode 内就可以比对安全性本文以及rwx等权限值是否正确,而给予适当的读取权限依据。
安全性本文可使用【ls -Z】去观察(开启了 SELinux 才可以)
安全性本文主要用冒号分为三个字段,这三个字段的意义为:Identify:role:type (身份识别:角色:类型)
身份识别(ldentify):
相当于账号方面的身份识别,主要的身份识别常见有底下几种常见的类型:
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 政策中,Identify 与 Role 字段基本上是不重要的。重要的在于这个类型(type)字段,基本上,一个主体进程能不能读取到这个文件资源,与类型字段有关。而类型字段在文件与进程的定义不太相同,分别是:
type
:在文件资源(Object)上面称为类型(Type);
domain
:在主体进程(Subject)则称为领域(domain);
domain 需要与 type 搭配,则该进程才能够顺利的读取文件资源。
进程与文件 SELinux type 字段的相关性
目前系统中的进程在 SELinux 底下的安全本文:
基本上,这些对应资料在 targeted 政策下的对应如下:
在预设的 target 政策下,其实最重要的字段是类型字段(type),主体与目标之间是否具有可以读写的权限,与进程的domain及文件的 type有关。
这两者的关系可以使用crond以及他的配置文件来说明:亦即是/usr/sbin/crond, /etc/crontab, /etc/cron.d 等文件来说明。
当执行 /usr/sbin/crond 之后,这个程序变成的进程的 domain 类型会是 crond_t 这一个~而这个crond_t 能够读取的配置文件则为 system_cron_spool_t 这种的类型。因此不论 /etc/crontab, /etc/cron.d 以及 /var/spool/cron 都会是相关的SELinux类型(/var/spool/cron 为 user_cron_spool_t)。
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 权限的规范。
SELinux 三种模式的启动、关闭与关闭
并非所有的 Linux distributions 都支持 SELinux 的。
CentOS 7.x 本身就支持 SELinux。目前 SELinux 依据启动与否,共有三种模式,分别如下:
enforcing:强制模式,代表SELinux运作中,且已经正确的开始限制domain/type了;
permissive:宽容模式:代表SELinux运作中,不过仅会有警告讯息并不会实际限制domain/type的存取。这种模式可以运来作为SELinux 的debug 之用;
disabled:关闭,SELinux并没有实际运作。
并不是所有的进程都会被 SELinux 所管制,因此最左边会出现一个所谓的【有受限的进程主体】。
ps -eZ
可以去【观察有没有受限】
三种模式的运作:首先,如果是 Disabled 的模式,那么 SELinux 将不会运作,当然受限的进程也不会经过SELinux,也是直接去判断 rwx 而已;如果是宽容(permissive)模式是不会将主体进程抵挡(所以箭头是可以直接穿透的喔! ),不过万一没有通过政策规则,或者是安全本文的比对时,那么该读写动作将会被纪录起来(log),可作为未来检查问题的判断依据。
getenforce 可以知道目前的 SELinux 模式:
可以使用 sestatus 来观察 SELinux 的政策:
sestatus [-vb]
SELinux 的配置文件:
vim /etc/selinux/config
SELinux 的启动关闭
如果改变了政策则需要重新启动;如果由 enforcing 或 permissive 改成 disabled,或由 disabled 改成其他两个,也必须要重新启动。
因为 SELinux 是整合到核心里面去的,只可以在 SELinux 运作下切换成为强制(enforcing)或宽容(permissive)模式,不能够直接关闭 SELinux。如果刚刚发现 getenforce 出现 disabled 时,到 /etc/selinux/config
修改成为 enforcing 然后重新启动。
如果从 disable 转到启动 SELinux 的模式时,由于系统必须要针对文件写入安全性本文的信息,因此开机过程会花费不少时间在等待重新写入SELinux安全性本文(有时也称为SELinux Label),而且在写完之后还得要再次的重新启动一次。
如果已经在 Enforcing 的模式,但是可能由于一些设定的问题导致 SELinux 让某些服务无法正常的运作,此时可以将 Enforcing 的模式改为宽容(permissive)的模式,让 SELinux 只会警告无法顺利联机的讯息,而不是直接抵挡主体进程的读取权限。
让 SELinux 模式在 enforcing 与 permissive 之间切换的方法为:
setenforce [0|1]
# 0: 转成 permissive 宽容模式;
# 1:转成 enforcing 强制模式;
在某些特殊的情况底下,从 Disabled 切换成 Enforcing 之后,有一堆服务无法顺利启动,都会说在 /lib/xxx 里面的数据没有权限读取,所以启动失败。这大多是由于在重新写入 SELinux type(Relabel) 出错之故,使用 Permissive 就没有这个错误。
最简单的方法就是在 Permissive 的状态下,使用【restorecon -Rv/】重新还原所有 SELinux 的类型,就能够处理这个错误。
SELinux 政策内的规则管理
SELinux 的三种模式是会影响到主体进程的放行与否。如果是进入 Enforcing 模式,那么接着下来会影响到主体进程的,就是target政策内的各项规则(rules)。
SELinux 各个规则的布尔值查询 gatebool
如果想要查询系统上面全部规则的启动与否 (on/off,亦即布尔值),透过 sestatus -b 或 getsebool -a 均可。
getsebool [-a] [规则的名称]
# -n:列出目前系统上面的所有 SELinux 规则的布尔值为开启或关闭值
每个规则后面都列出现在是允许放行还是不许放行的布尔值。
SELinux 各个规则规范的主体进程能够读取的文件 SELinux type 查询 seinfo, sesearch
seinfo 可以查看每个规则内到底是在限制。
seinfo [-Artub]
如果想要查询目前所有的身份识别与角色,就使用【seinfo -u】及【seinfo -r】就可以知道了,简单的统计数据,就直接输入seinfo即可。
sesearch [-A] [-s 主体类别] [-t 目标类别] [-b 布尔值]
# 找出 crond_t 这个主体进程能够读取的文件 SELinux type
sesearch -A -s crond_t | grep spool
修改 SELinux 规则的布尔值 setsebool
setsebool [-P] [规则名称] [0|1]
# -P:直接将设定值写入配置文件,该设定数据未来会生效
getsebool [规则名称] # 输出设定值(bool)
SELinux 安全文本的修改
SELinux对受限的主体进程有没有影响,首先考虑 SELinux 的三种类型,第二考虑 SELinux 的政策规则是否放行,第三则是考虑开始比对SELinuxtype 。
使用 chcon 手动修改文件的 SELinux type
chcon [-R] [-t type] [-u user] [-r role] 文件
chcon [-R] --reference=范例文件 文件
使用 restorecon 让文件恢复正确的 SELinux type
restorecon [-Rv] 文件或目录
# -R:连同此目录一起修改;
# -v:将过程显示到屏幕上
restorecon主动的回复预设的 SELinux type,而且可以一口气恢复整个目录下的文件。
semanage 默认目录的安全性本文查询与修改
restorecon可以【恢复】原本的SELinux type 的原因是有个地方在纪录每个文件/目录的SELinux默认类型。
透过 semanage可以(1)查询预设的 SELinuxtype 以及(2)增加/修改/删除预设的 SELinux type。
semanage {login|user|port|interface|fcontext|translation} -l
semanage fcontext -{a|d|m} [-frst] file_spec
还有挺多没学
。。。。这个感觉不好学。。
《鸟哥的Linux私房菜-基础篇》学习笔记