SELinux初探

(整理自鸟哥的Linux私房菜》基础篇)

 

1.什么是SELinux

SELinux 是在进行进程、文件等细部权限设定依据的一个核心模块, 由于启动网络服务的也是进程,因此刚好也能够控制网络服务能否存取系统资源的一道关卡。

这里涉及两个概念:

  •   自主式访问控制, DAC就是依据进程的拥有者与文件资源的 rwx 权限来决定有无存取的能力;
  • 强制访问控制, MAC针对特定的进程与特定的文件资源来进行权限的控管,也就是说,即使你是 root ,那么在使用不同的进程时,你所能取得的权限并不一定是 root , 而得要看当时该进程的设定而定。

举例用图表示:

 

 左图是没有 SELinux 的 DAC 存取结果,apache 这只 root 所主导的进程,可以在这三个目录内作任何文件的新建与修改;右边则是加上 SELinux 的 MAC 管理的结果,SELinux 仅会针对 Apache 这个process 放行部份的目录, 其他的非正规目录就不会放行给 Apache 使用,因此不管你是谁,就是不能穿透 MAC 。

 

2.SELinux的运行模式

介绍几个概念:

•        主体 (Subject):SELinux 主要想要管理的就是进程,因此你可以将主体跟进程划上等号;

•        目标 (Object):主体进程能否存取的目标资源一般就是文件系统。因此这个目标项目可以与文件系统划上等号;

•        策略 (Policy):由于进程与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性策略。这些策略内还会有详细的规则 (rule) 来指定不同的服务开放某些资源的存取与否。在目前的 CentOS 7.x 里面仅有提供三个主要的策略,分别是:

o targeted:针对网络服务限制较多,针对本机限制较少,是预设的策略;

o minimum:由 target 修订而来,仅针对选择的进程来保护;

o mls:完整的 SELinux 限制,限制方面较为严格。

建议使用默认的 targeted 策略即可。

•        安全性本文 (security context):主体能不能存取目标除了策略指定之外,主体与目标的安全性本文必须一致才能够顺利存取。 这个安全性本文 (security context) 有点类似文件系统的 rwx ,安全性本文的内容与设定是非常重要的,如果设定错误,你的某些服务(主体进程)就无法存取文件系统(目标资源),当然就会一直出现『权限不符』的错误讯息了。

 

 上图的重点在『主体』如何取得『目标』的资源访问权限! 由上图我们可以发现,(1)主体进程必须要通过 SELinux 政策内的规则放行后,就可以与目标资源进行安全性本文的比对, (2)若比对失败则无法存取目标,若比对成功则可以开始存取目标。

那文件的安全性本文是记录在哪里呢?事实上,安全性本文是放置到文件的 inode 内的,因此主体进程想要读取目标文件资源时,同样需要读取 inode , 这 inode 内就可以比对安全性本文以及 rwx 等权限值是否正确,而给予适当的读取权限依据。

那么安全性本文到底是什么样的存在呢?先来看看 /root 底下的文件的安全性本文。 观察安全性本文可使用『 ls -Z 』去观察如下:(注意:必须已经启动了 SELinux 才行)

 

 如上所示,安全性本文主要用冒号分为三个字段(除开最后的:s0),这三个字段的意义为:

 

 这三个字段的意义仔细的说明一下:

  • · 身份识别 (Identify):相当于账号方面的身份识别,主要的身份识别常见有底下几种常见的类型:

o   unconfined_u:不受限的用户,也就是说,该文件来自于不受限的进程所产生的。一般来说,我们使用可登入账号来取得 bash 之后, 预设的 bash 环境是不受 SELinux 管制的,因为 bash 并不是什么特别的网络服务!因此,在这个不受 SELinux 所限制的 bash 进程所产生的文件, 其身份识别大多就是 unconfined_u 这个不受限用户。

o   system_u:系统用户,大部分就是系统自己产生的文件。

基本上,如果是系统或软件本身所提供的文件,大多就是 system_u 这个身份名称,而如果是我们用户透过 bash 自己建立的文件,大多则是不受限的 unconfined_u 身份,如果是网络服务所产生的文件,或者是系统服务运作过程产生的文件,则大部分的识别就会是 system_u 。

  • · 角色 (Role):透过角色字段,我们可以知道这个数据是属于进程、文件资源还是代表使用者。一般的角色有:

o   object_r:代表的是文件或目录等文件资源;

o   system_r:代表的就是进程,不过,一般使用者也会被指定成为 system_r 。

角色的字段最后面使用『 _r 』来结尾,是 role 的意思。

  • · 类型 (Type) (最重要)

在默认的 targeted 策略中, Identify 与 Role 字段基本上是不重要的,重要的在于这个类型

(type) 字段。基本上,一个主体进程能不能读取到这个文件资源,与类型字段有关。而类型字段在文件与进程的定义不太相同,分别是:

o   type:在文件资源 (Object) 上面称为类型 (Type);

o   domain:在主体进程 (Subject) 则称为领域 (domain) 。

domain 需要与 type 搭配,则该进程才能够顺利的读取文件资源。

§ 进程与文件 SELinux type 字段的相关性

 

 基本上,这些数据在 targeted 策略下的对应如下:

身份识别

角色

该对应在 targeted 的意义

unconfined_u

unconfined_r

一般可登入使用者的进程啰!比较没有受限的进程之意!大多数都是用户已经顺利登入系统 (不论是网络还是本机登入来取得可用的 shell) 后, 所用来操作系统的进程!如 bash, X window 相关软件等。

system_u

system_r

由于为系统账号,因此是非交谈式的系统运作进程,大多数的系统进程均是这种类型!

但就如上所述,在预设的 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 权限的规范。

 

3. SELinux 三种模式的启动、关闭与观察

目前 SELinux 依据启动与否,共有三种模式,分别如下:

•        enforcing:强制模式,代表 SELinux 运作中,且已经正确的开始限制 domain/type 了;

•        permissive:宽容模式:代表 SELinux 运作中,不过仅会有警告讯息并不会实际限制 domain/type 的存取。这种模式可以运来作为 SELinux 的 debug 之用;

•        disabled:关闭,SELinux 并没有实际运作。

SELinux 的三种模式与上面谈到的策略规则、安全本文的关系为何呢?如图:

 

 首先,并不是所有的进程都会被 SELinux 所管制,因此最左边会出现一个所谓的『有受限的进程主体』。那如何观察有没有受限 (confined )呢?举例来说,看看crond 与 bash 这两只进程是否有被限制:

 

 因为在目前 target 这个策略下,只有第三个类型 (type) 字段会有影响,因此我们可以看到,crond 是有受限的主体进程,而 bash 因为是本机进程,因此就是不受限 (unconfined_t) 的类型。

三种模式的运作:首先,如果是 Disabled 的模式,那么 SELinux 将不会运作,所以受限的进程也不会经过 SELinux , 而是直接去判断 rwx 。如果是宽容 (permissive) 模式的话,也是不会将主体进程抵挡 (所以箭头是可以直接穿透的),不过万一没有通过策略规则,或者是安全本文的比对时, 那么该读写动作将会被记录起来 (log),可作为未来检查问题的判断依据。Enforcing 模式就是实际将受限主体进入规则比对、安全本文比对的流程,若失败,就直接抵挡主体进程的读写行为,并且将他记录下来。 如果通通没问题,这才进入到 rwx 权限的判断。

 那怎么知道目前的 SELinux 模式?就透过 getenforce 命令:

 

 又如何知道 SELinux 的策略 (Policy) 为何呢?这时可以使用 sestatus 命令来观察。

 

 SELinux 的配置文件其实就是 /etc/selinux/config 这个文件,看看内容:

 

 所以我们也可以直接通过修改这个文件来更改模式和策略。

§      SELinux 的启动与关闭:

如果改变了政策则需要重新启动;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成另外两个,那也必须要重新启动。

不过要注意的是,如果从 disable 转到启动 SELinux 的模式时, 由于系统必须要针对文件写入安全性本文的信息,因此开机过程会花费不少时间在等待重新写入 SELinux 安全性本文,而且在写完之后还得要再次的重新启动一次!

SELinux 模式在 enforcing 与 permissive 之间切换的方法为(无法切换到disable):

 

 在某些特殊的情况下,从 Disabled 切换成 Enforcing 之后,可能会有一堆服务无法顺利启动,都会说在 /lib/xxx 里面的数据没有权限读取,所以启动失败。这大多是由于在重新写入 SELinux type出错之故,使用 Permissive 就没有这个错误。那如何处理呢?最简单的方法就是在 Permissive 的状态下,使用『 restorecon -Rv / 』重新还原所有 SELinux 的类型,就能够处理这个错误!

4.SELinux 策略内的规则管理

§  SELinux 各个规则的布尔值查询 getsebool

如果想要查询系统上面全部规则的启动与否 (on/off,亦即布尔值),很简单的透过 sestatus -b 或 getsebool -a :

 

 §  SELinux 各个规则规范的主体进程能够读取的文件 SELinux type 查询 seinfo, sesearch

如果你想要知道每个规则内到底是在限制什么东西的话:

 

 寻找一下 crond_t 能够读取的文件 SELinux type 有哪些:

 

 所以,现在我们知道 /etc/cron.d/checktime 这个我们自己复制过去的文件会没有办法被读取的原因,就是因为 SELinux type 错误,根本就无法被读取。

 httpd_enable_homedirs 到底是什么?又是规范了哪些主体进程能够读取的 SELinux type 呢:

 

 § 修改 SELinux 规则的布尔值 setsebool

那么如果查询到某个 SELinux rule,并且以 sesearch 知道该规则的用途后,想要关闭或启动他,又该如何做:

 

 这个 setsebool 最好记得一定要加上 -P 的选项,因为这样才能将此设定写入配置文件。

5.SELinux 安全本文的修改

§  使用 chcon 手动修改文件的 SELinux type

用 restorecon让 SELinux 自己解决默认目录下的 SELinux type:

 

 §  semanage 默认目录的安全性本文查询与修改:

为什么 restorecon 可以恢复原本的 SELinux type 呢?那是有地方在纪录每个文件/目录的 SELinux 默认类型, (1)查询预设的 SELinux type 以及 (2)如何增加/修改/删除预设的 SELinux type 呢?透过 semanage 即可!他是这样使用的:

 

 如果我们要建立一个 /srv/mycron 的目录,这个目录默认也是需要变成system_cron_spool_t 时, 我们应该要如何处理呢( 这种情况肯定是假的、不存在的,现实中不可能这么干))?基本上可以这样做:

 

猜你喜欢

转载自www.cnblogs.com/ericz2j/p/12045307.html