Linux权限连载之四-SELinux详解,你了解多少?

2019-07-28   Linux学习教程

请关注本头条号,每天坚持更新原创干货技术文章。

如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习

1. 前言

我们在使用Linux系统的过程中,一定会接触到一个工具:SElinux,对系统有所了解的人,应该会很大几率会直接关闭这项功能。因为这个工具并不好理解,也比较复杂。但不得不说,有了这个工具以后,我们的系统的安全性达到一个前所未有的高度,所以我们更有必要去学习和理解这个工具。

2. SELinux是什么

安全增强式 Security-Enhanced Linux(SELinux)是一个在内核中实践的强制存取控制(MAC)安全性机制。SELinux 首先在 CentOS 4 出现,并在其后的 CentOS 发行版本获得重大改善。这些改善代表用 SELinux 解决问题的方法亦随著时间而改变。

SELinux 全称 Security Enhanced Linux (安全强化 Linux),是美国国家安全局2000年以 GNU GPL 发布,是 MAC (Mandatory Access Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。强制访问控制系统 的用途在于增强系统抵御 0-Day 攻击(利用尚未公开的漏洞实现的攻击行为)的能力。所以它不是网络防火墙或 ACL 的替代品,在用途上也 不重复。在目前的大多数发行版中,已经默认在内核集成了SELinux。

3. SELinux怎么关闭

很多系统的管理员可能第一时间就会想到关闭SElinux,要关闭SELinux不难,但并不推荐这样做。

3.1 第一种:临时关闭(重启后失效)

[root@centos7 ~]# setenforce 0

3.2 第二种:永久关闭

[root@centos7 ~]# vi /etc/selinux/config

将SELINUX=enforcing改为SELINUX=disabled,保存后退出

[root@centos7 ~]# reboot

注意:重启后生效

不建议直接关闭SElinux,我们继续了解一下SElinux这个系统加固工具。

4. SELinux的设计初衷

SELinux 是由美国国家安全局 (NSA) 开发的,当初开发的目的是因为很多企业界发现, 通常系统出现问题的原因大部分都在于内部员工的错误配置所导致的,实际由外部发动的攻击反而没有这么严重。 举例来说,如果有个不是很懂系统的系统管理员为了自己配置的方便,将网页所在目录 /var/www/html/ 的权限配置为 drwxrwxrwx 时,你觉得会有什么事情发生?

现在我们知道所有的系统资源都是透过程序来进行存取的,那么 /var/www/html/ 如果配置为 777 , 代表所有程序均可对该目录存取,万一你真的有启动 WWW 服务器软件,那么该软件所触发的程序将可以写入该目录, 而该程序却是对整个 Internet 提供服务的!只要有心人接触到这个程序,而且该程序刚好又有提供使用者进行写入的功能, 那么外部的人很可能就会对你的系统写入些莫名其妙的东西!那可真是不得了!一个小小的 777 问题可是大大的!

为了控管这方面的权限与程序的问题,所以美国国家安全局就着手处理操作系统这方面的控管。 由于Linux 是自由软件,源代码都是公开的,因此她们便利用Linux 来作为研究的目标, 最后更将研究的结果整合到 Linux 核心里面去,那就是 SELinux 。所以说, SELinux 是整合到核心的一个模块。

这也就是说:其实 SELinux 是在进行程序、文件等细部权限配置依据的一个核心模块! 由于启动网络服务的也是程序,因此刚好也能够控制网络服务能否存取系统资源的一道关卡! 所以,在讲到 SELinux 对系统的存取控制之前,我们得先来回顾一下之前谈到的系统文件权限与使用者之间的关系。 因为先谈完这个你才会知道为何需要 SELinux 的啦!

5. SELinux的运行模式

SELinux 拥有三个基本的操作模式,当中 Enforcing 是预设的模式。此外,它还有一个 targeted 或 mls 的修饰语。这管制 SELinux 规则的应用有多广泛,当中 targeted 是较宽松的级别。

  • Enforcing: 这个预设模式会在系统上启用并实施 SELinux 的安全性政策,拒绝存取及记录行动
  • Permissive: 在 Permissive 模式下,SELinux 会被启用但不会实施安全性政策,而只会发出警告及记录行动。Permissive 模式在排除 SELinux 的问题时很有用
  • Disabled: SELinux 已被停用

SELinux 的模式可以透过 Adminstration 选单里的 SELinux 图像管理界面、或者在指令行执行 system-config-selinux 来检视及更改(SELinux 图像管理界面是 policycoreutils-gui 套件的一部分,预设是不会被安装的)。

用户可使用sestatus这个指令来查看当前的 SELinux 状况:

[root@centos7 ~]# sestatus

查看当前的 SELinux 状况

使用命令getenforce查询当前的 SELinux 模式

[root@zcwyou ~]# getenforce

得到以下显示

Enforcing

查询当前的 SELinux 模式

表明当前运行在Enforcing模式

另外,我们又如何知道 SELinux 的政策 (Policy) 为何呢?这时可以来观察配置文件啦:

[root@zcwyou ~]# cat /etc/selinux/config

SELINUX=enforcing <==可以调整为enforcing|disabled|permissive

SELINUXTYPE=targeted <==目前仅有 targeted 与 mls

查看selinux的配置文件

setenforce这个命令可以即时切换 Enforcing 及 Permissive 这两个模式,但请注意这些改动在系统重新开机时不会被保留,即只能临时生效。

如果需要下次开机自动生效,请修改配置文件/etc/selinux/config

把SELINUX= 这一行修改为enforcing或permissive 或 disabled。

例如:SELINUX=permissive

注: 当你由 Diabled 切换至 Permissive 或 Enforcing 模式时,我们强烈建议你重新启动系统并重新标签档案系统。

上面是默认的政策与启动的模式,你要注意的是,如果改变了政策则需要重新启动;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他两个,那也必须要重新启动。这是因为 SELinux 是整合到核心里面去的, 你只可以在 SELinux 运作下切换成为强制 (enforcing) 或宽容 (permissive) 模式,不能够直接关闭 SELinux 的! 如果刚刚你发现 getenforce出现 disabled 时,请到上述配置文件修改成为 enforcing 然后重新启动系统。

不过你要注意的是,如果从 disable 转到启动 SELinux 的模式时, 由于系统必须要针对文件写入安全性本文的信息,因此开机过程会花费不少时间在等待重新写入 SELinux 安全性本文 (有时也称为 SELinux Label) ,而且在写完之后还得要再次的重新启动一次,你必须要等待一段很长的时间, 等到下次开机成功后,再使用 getenforce 来观察看看有否成功的启动到 Enforcing 的模式。

如果你已经在 Enforcing 的模式,但是可能由于一些设定的问题导致 SELinux 让某些服务无法正常的运作, 此时你可以将 Enforcing 的模式改为宽容 (permissive) 的模式,让 SELinux 只会警告无法顺利联机的信息, 而不是直接阻止主体程序的读取权限。让 SELinux 模式在 enforcing 与 permissive 之间切换的方法为:

[root@zcwyou ~]# setenforce [0|1]

选项与参数:

0 :转成 permissive 宽容模式;

1 :转成 Enforcing 强制模式

示例一:将 SELinux 在 Enforcing 与 permissive 之间切换与查询

[root@zcwyou ~]# setenforce 0
[root@zcwyou ~]# getenforce

Permissive

[root@zcwyou ~]# setenforce 1
[root@zcwyou ~]# getenforce

Enforcing

不过请注意, setenforce 无法在 Disabled 的模式底下进行模式的切换

Tips:

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

6. 传统的文件权限与帐号关系

传统的文件权限与帐号关系:自主式存取控制, DAC

系统的帐号主要分为系统管理员 (root) 与一般用户,而这两种身份能否使用系统上面的文件资源则与 rwx 的权限配置有关。 不过你要注意的是,各种权限配置对 root 是无效的。因此,当某个程序想要对文件进行存取时, 系统就会根据该程序的拥有者/群组,并比对文件的权限,若通过权限检查,就可以存取该文件了。

这种存取文件系统的方式被称为自主式存取控制 (Discretionary Access Control, DAC),基本上,就是依据程序的拥有者与文件资源的 rwx 权限来决定有无存取的能力。 不过这种 DAC 的存取控制有几个困扰,那就是:

root 具有最高的权限:如果不小心某个程序被有心人士取得, 且该程序属于 root 的权限,那么这个程序就可以在系统上进行任何资源的存取。

使用者可以取得程序来变更文件资源的存取权限:如果你不小心将某个目录的权限配置为 777 ,由于对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取。

这些问题是非常严重的!尤其是当你的系统是被某些漫不经心的系统管理员所掌控时!他们甚至不懂777权限带来的严重后果。

7. 什么是MAC

以政策守则订定特定程序读取特定文件:委任式存取控制, MAC

现在我们知道 DAC 的困扰就是当使用者取得程序后,他可以借用程序与自己默认的权限来处理他自己的文件资源。 万一这个使用者对 Linux 系统不熟,那就很可能会有资源误用的问题产生。为了避免 DAC 容易发生的问题,因此 SELinux 导入了委任式存取控制 (Mandatory Access Control, MAC) 的方法!

委任式存取控制 (MAC) 可以针对特定的程序与特定的文件资源来进行权限的控制。也就是说,即使你是 root ,那么在使用不同的程序时,你所能取得的权限并不一定是 root , 而得要看当时该程序的配置而定。如此一来,我们针对控制的主体变成了程序而不是用户。 此外,这个主体程序也不能任意使用系统文件资源,因为每个文件资源也有针对该主体程序配置可取用的权限。 如此一来,控制项目就细的多了,但整个系统程序那么多、文件那么多,一项一项控制可就没完没了。 所以 SELinux 也提供一些默认的政策 (Policy) ,并在该政策内提供多个守则 (rule) ,让你可以选择是否激活该控制守则。

在委任式存取控制的配置下,我们的程序能够活动的空间就变小了。举例来说, WWW 服务器软件的达成程序为 httpd 这个程序, 而默认情况下, httpd 仅能在 /var/www/ 这个目录底下存取文件,如果 httpd 这个程序想要到其他目录去存取数据时, 除了相应的配置要开放外,目标目录也得要配置成 httpd 可读取的模式 (type) 才行喔!限制非常多! 所以,即使不小心 httpd 被恶意取得了控制权,他也无权浏览 /etc/shadow 等重要的配置文件。

8. SELinux的概念

SELinux是使用 MAC 的方式来管理程序的,它控制的主体是程序, 而目标则是该程序能否读取的文件资源,所以学习一些相关的概念:

  • 主体 (Subject):
  • SELinux 主要想要管理的就是程序,因此你可以将主体跟本文谈到的 process 划上等号;
  • 目标 (Object):
  • 主体程序能否存取的目标资源一般就是文件系统。因此这个目标项目可以与文件系统划上等号;
  • 政策 (Policy):
  • 由于程序与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的守则 (rule) 来指定不同的服务开放某些资源的存取与否。

CentOS 的 targeted SELinux 政策包含四种存取控制方法:

  • 强制类别(TE):TE 是 targeted 政策所采用的主要存取控制机制
  • 基于⻆色的存取控制(RBAC):它以 SELinux 用户(未必等同 Linux 用户)为基础,但预设的 targeted 政策设定并未采用它
  • 多层保障(MLS):普遍不获采用,而且经常隐藏在预设的 targeted 政策内。
  • 多种类保障(MCS): 多层保障的延伸,在 targeted 政策内透过 sVirt 实践虚拟电脑和容器的分隔。

9. 安全性本文 (security context)

我们刚刚谈到了主体、目标与政策面,但是主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。 这个安全性本文 (security context) 有点类似文件系统的 rwx。安全性本文的内容与配置是非常重要的, 如果配置错误,你的某些服务(主体程序)就无法存取文件系统(目标资源),当然就会一直出现权限不符的错误信息了!

selinux的处理机制

上图的重点在主体如何取得目标的资源存取权限, 由上图我们可以发现,主体程序必须要通过 SELinux 政策内的守则放行后,就可以与目标资源进行安全性本文的比对, 若比对失败则无法存取目标,若比对成功则可以开始存取目标。问题是,最终能否存取目标还是与文件系统的 rwx 权限配置有关!如此一来,加入了 SELinux 之后,出现权限不符的情况时,你就得要一步一步的分析可能的问题了

10. 查看安全性文本 (Security Context)

10.1 使用ls查看安全性文本

ls 加选项-z就可以查看安全性文本内容

[root@centos7 ~]# ls -Z

drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 abc

使用ls查看安全性文本

如上所示,安全性本文主要用冒号分为三个字段 (最后一个字段先略过不看),这三个字段的意义为:

Identify:role:type

翻译起来就是:

身份识别:角色:类型

10.2 理解身份识别类型

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

  • root:表示 root 的账号身份,如同上面的表格显示的是 root 家目录下的数据
  • system_u:表示系统程序方面的识别,通常就是程序
  • user_u:代表的是一般使用者账号相关的身份

10.3 理解角色类型

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

object_r:代表的是档案或目录等档案资源,这应该是最常见的

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

10.4 理解类型 (Type)

类型 (Type): 在预设的 targeted 政策中, Identify 与 Role 字段基本上是不重要的。重要的在于这个类型 (type) 字段,基本上,一个主体程序能不能读取到这个档案资源,与这个类型字段有关。而类型字段在档案与程序的定义不太相同,分别是:

  • type:在文件资源 (Object) 上面称为类型 (Type)
  • domain:在程序文件 (Subject) 则称为领域 (domain)

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

其实最重要的字段是类型字段,主体与目标之间是否具有可以读写的权限,与程序的 domain 及档案的 type 有关,这两者的关系我们可以使用达成 WWW 服务器功能的 httpd 这支程序与 /var/www/html 这个网页放置的目录来说明。 首先,检查一下这些文件的安全性本文内容先:

[root@centos7 ~]# yum -y install httpd

安装httpd服务

[root@centos7 ~]# ll -Zd /usr/sbin/httpd /var/www/html

-rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd

drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html

查看http服务有关的selinux政策

上图可以看出,两者的角色字段都是 object_r ,代表都是文件,而 httpd 属于 httpd_exec_t 类型,

/var/www/html 则属于 httpd_sys_content_t 这个类型,

httpd 属于 httpd_exec_t 这个可以执行的类型,而 /var/www/html 则属于 httpd_sys_content_t 这个可以让 httpd 领域 (domain) 读取的类型。文字看起来不太容易了解,下图可以说明两者之间的关系。

主体程序取得的 domain 与目标档案资源的 type 相互关系

解释一下上图的流程:

Step1:我们执行一个程序文件,那就是具有 httpd_exec_t 这个类型的 /usr/sbin/httpd

该文件的类型会让这个文件所造成的主体程序 (Subject) 具有 httpd 这个领域 (domain), 我们的政策针对这个领域已经制定了许多规则,其中包括这个领域可以读取的目标资源类型;

Step2:由于 httpd domain 被设定为可以读取 httpd_sys_content_t 这个类型的目标文件 (Object), 因此你的网页放置到 /var/www/html/ 目录下,就能够被 httpd 这个程序所读取了;

Step3:最终能不能访问 /var/www/html/ 目录下的文件,还要看 rwx 是否符合 Linux 权限的规范

上图告诉我们的是,即使我们错误把文件或者目录权限为777,也未必可以让所有人访问。这就是SElinux安全策略的意义。

11. 修改SELinux type字段

既然 SELinux 的类型字段 (type) 这么重要,那如何修改与变更这个字段呢?

案例1:将 /etc/hosts 复制到 root 家目录,并观察相关的 SELinux 类型变化

[root@zcwyou ~]# cp /etc/hosts /root
[root@zcwyou ~]# ls -dZ /etc/hosts /root/hosts /root

-rw-r--r--. root root system_u:object_r:net_conf_t:s0 /etc/hosts

dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root

-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/hosts

案例2:将 /root/hosts 移动到 /tmp 下,并观察相关的 SELinux 类型变化

[root@zcwyou ~]# mv /root/hosts /tmp
[root@zcwyou ~]# ls -dZ /tmp /tmp/hosts

drwxrwxrwt. root root system_u:object_r:tmp_t:s0 /tmp

-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /tmp/hosts

当复制文件时,SELinux 的 type 字段是会继承目标目录的,所以 /root/hosts 的类型就会变成 admin_home_t 这个类型了。如果是移动文件,那就连同 SELinux 的类型也会被移动过去,因此 /tmp/hosts 会依旧保持 admin_home_t 而不会变成 /tmp 的 tmp_t 这个类型了。那如何将 /tmp/hosts 变更成为最原始的 net_conf_t 这个类型呢?那就得要使用命令chcon

11.1 chcon命令使用案例

[root@zcwyou ~]# chcon [-R] [-t type] [-u user] [-r role] 档案
[root@zcwyou ~]# chcon [-R] --reference=范例文件 档案

选项与参数:

-R :连同该目录下的次目录也同时修改;

-t :后面接安全性本文的类型字段!例如 httpd_sys_content_t ;

-u :后面接身份识别,例如 system_u;

-r :后面街角色,例如 system_r;

--reference=范例文件:拿某个档案当范例来修改后续接的档案的类型!

范例1:将刚刚的 /tmp/hosts 类型改为 etc_t 的类型

[root@zcwyou ~]# chcon -t net_conf_t /tmp/hosts
[root@zcwyou ~]# ll -Z /tmp/hosts

-rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /tmp/hosts

范例2.:以 /var/spool/mail/ 为依据,将 /tmp/hosts 修改成该类型

[root@zcwyou ~]# ll -dZ /var/spool/mail

drwxrwxr-x. root mail system_u:object_r:mail_spool_t:s0 /var/spool/mail

[root@zcwyou ~]# chcon --reference=/var/spool/mail /tmp/hosts
[root@zcwyou ~]# ll -Z /tmp/hosts

-rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /tmp/hosts

chcon的修改方式中,我们必须要知道最终我们的 SELinux type 是什么类型,才能够变更成功。 如果你想要作的是复原成原有的 SELinux type呢?可以使用以下命令修改

11.2 restorecon命令使用案例

[root@www ~]# restorecon [-Rv] 档案或目录

选项与参数:

-R :连同次目录一起修改;

-v :将过程显示到屏幕上

范例:将刚刚 /tmp/hosts 移动至 /root 并以预设的安全性本文改正过来

[root@www ~]# mv /tmp/hosts /root
[root@www ~]# ll -Z /root/hosts

-rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /root/hosts

[root@www ~]# restorecon -Rv /root

restorecon reset /root/hosts context system_u:object_r:mail_spool_t:s0->

system_u:object_r:admin_home_t:s0

上面表示将 hosts 由 mail_spool_t 改为 admin_home_t

13. 默认目录的安全性本文查询与修改

restorecon 怎么会知道每个目录记载的默认 SELinux type 类型呢?这是因为系统有记录相关的记录,它由 /etc/selinux/targeted/contexts配置文件定义,但是该目录内有很多不同的数据, 要使用文本编辑器去查阅很麻烦,此时,我们可以使用 semanage 这个指令的功能来查询与修改。

安装semanage

[root@zcwyou ~]# yum -y install policycoreutils-python
[root@www ~]# semanage {login|user|port|interface|fcontext|translation} -l
[root@www ~]# semanage fcontext -{a|d|m} [-frst] file_spec

选项与参数:

fcontext :主要用在安全性本文方面的用途, -l 为查询的意思;

-a :增加的意思,你可以增加一些目录的默认安全性本文类型设定;

-m :修改的意思;

-d :删除的意思。

范例:查询一下 /var/www/ 的预设安全性本文设定为何

[root@www ~]# semanage fcontext -l | grep '/var/www'

SELinux fcontext 类型 Context

/var/www(/.)? all files system_u:object_r:httpd_sys_content_t:s0 /var/www(/.)?/logs(/.*)? all files system_u:object_r:httpd_log_t:s0

那么如果我们想要增加某些自定义的目录的安全性本文呢? 举例来说,我想要制订 /srv/vbird 成为 public_content_t 的类型时,应该如何指定呢?

范例:利用 semanage 设定 /srv/vbird 目录的默认安全性本文为 public_content_t

[root@www ~]# mkdir /srv/vbird
[root@www ~]# ll -Zd /srv/vbird

drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /srv/vbird

如上所示,默认的type应该是var_t

[root@www ~]# semanage fcontext -l | grep '/srv'

/srv directory system_u:object_r:var_t:s0

/srv/.* all files system_u:object_r:var_t:s0

上面则是/srv 里默认的安全性本文数据,不过,并没有指定到 /srv/vbird

修改Type字段,并查看

[root@www ~]# semanage fcontext -a -t public_content_t "/srv/vbird(/.*)?"
[root@www ~]# semanage fcontext -l | grep '/srv/vbird'

/srv/vbird(/.*)? all files system_u:object_r:public_content_t:s0

可以看出Type字段被修改为public_content_t

查看刚刚自动生成的配置文件:

[root@www ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local

This file is auto-generated by libsemanage

Please use the semanage command to make changes

/srv/vbird(/.*)? system_u:object_r:public_content_t:s0

以上文件内容是自动生成的。

尝试恢复默认值

[root@www ~]# restorecon -Rv /srv/vbird*

查看

[root@www ~]# ll -Zd /srv/vbird

drwxr-xr-x. root root system_u:object_r:public_content_t:s0 /srv/vbird

有了默认值,以后用 restorecon 来修改比较简单。

semanage 的功能很多,不过本文主要用到fcontext 这个设置功能而已。如上所示, 你可以使用 semanage 来查询所有的目录的默认值,也能够使用它来增加默认值的设定。如果您学会这些基础的工具, 那么 SELinux 对你来说,也不是难事。

14. 查看SElinux与修改selinux默认规则的布尔值

前面的内容提到,要通过 SELinux 的验证之后才能开始档案权限 rwx 的判断,而 SELinux 的判断主要是内容是:

  • 政策内的规则比对与
  • 程序与档案的 SELinux type 要符合才能够放行。

前一个小节谈的是 SELinux 的 type ,这个小节就是要谈一下政策内的规则, 包括如何查询与修改相关的规则放行与否。

14.1 查看默认策略

CentOS 预设使使用 targeted 政策,那么这个政策提供多少相关的规则呢?此时可以透过 seinfo 来查询,命令如下:

[root@zcwyou ~]# yum install setools-console -y
[root@www ~]# seinfo [-Atrub]

选项与参数:

-A :列出 SELinux 的状态、规则布尔值、身份识别、角色、类别等所有信息

-t :列出 SELinux 的所有类别 (type) 种类

-r :列出 SELinux 的所有角色 (role) 种类

-u :列出 SELinux 的所有身份识别 (user) 种类

-b :列出所有规则的种类 (布尔值)

范例一:列出 SELinux 在此政策下的统计状态

[root@www ~]# seinfo

tatistics for policy file: /etc/selinux/targeted/policy/policy.24

Policy Version & Type: v.24 (binary, mls) <==列出政策所在档与版本

Classes: 77 Permissions: 229

Sensitivities: 1 Categories: 1024

Types: 3076 Attributes: 251

Users: 9 Roles: 13

Booleans: 173 Cond. Expr.: 208

Allow: 271307 Neverallow: 0

Auditallow: 44 Dontaudit: 163738

Type_trans: 10941 Type_change: 38

Type_member: 44 Role allow: 20

Role_trans: 241 Range_trans: 2590

从上面我们可以看到这个政策是 targeted ,此政策的 SELinux type 有 3076 个;

而针对网络服务的规则 (Booleans) 共制订了 173 条规则

范例二:列出与 httpd 有关的规则 (booleans) 有哪些?

[root@www ~]# seinfo -b | grep httpd

Conditional Booleans: 173

allow_httpd_mod_auth_pam

httpd_setrlimit

httpd_enable_ftp_server

你可以看到,有非常多的与 httpd 有关的规则订定

从上面我们可以看到与 httpd 有关的布尔值,同样的,如果你想要找到有 httpd 字样的安全性本文类别时, 就可以使用seinfo -t | grep httpd来查询了,如果查询到相关的类别或者是布尔值后,想要知道详细的规则时, 就得要使用命令sesearch

[root@www ~]# sesearch [--all] [-s 主体类别] [-t 目标类别] [-b 布尔值]

选项与参数:

--all :列出该类别或布尔值的所有相关信息

-t :后面还要接类别,例如 -t httpd_t

-b :后面还要接布尔值的规则,例如 -b httpd_enable_ftp_server

范例一:找出目标档案资源类别为 httpd_sys_content_t 的有关信息

[root@www ~]# sesearch --all -t httpd_sys_content_t

Found 683 semantic av rules:

allow avahi_t file_type : filesystem getattr ;

allow corosync_t file_type : filesystem getattr ;

allow munin_system_plugin_t file_type : filesystem getattr ;

理解:

allow 主体程序安全性本文类别 目标档案安全性本文类别

如上,说明这个类别可以被那个主体程序的类别所读取,以及目标文档资源的格式。

你可以很轻易的查询到某个主体程序 (subject) 可以读取的目标文件资源 (Object)。 那如果是布尔值呢?里面又规范了什么?让我们来看看先:

范例三:我知道有个布尔值为 httpd_enable_homedirs ,请问该布尔值规范多少规则?

[root@www ~]# sesearch -b httpd_enable_homedirs --all

Found 43 semantic av rules:

allow httpd_user_script_t user_home_dir_t : dir { getattr search open } ;

allow httpd_sys_script_t user_home_dir_t : dir { ioctl read getattr } ;

从这个布尔值的设定我们可以看到里面规范了非常多的主体程序与目标档案资源的放行与否, 所以你知道了,实际规范这些规则的,就是布尔值的项目,那也就是我们之前所说的一堆规则。你的主体程序能否对某些目标文件进行读写,与这个布尔值非常有关系,因为布尔值可以将规则设定为启动 (1) 或者是关闭 (0)

14.2 查看与修改布尔值

上面我们通过了解sesearch知道了,其实 Subject 与 Object 能否有存取的权限,是与布尔值有关的, 那么系统有多少布尔值可以透过 seinfo -b 来查询,但每个布尔值是启动的还是关闭的呢?这就来查询看看吧:

[root@www ~]# getsebool [-a] [布尔值条款]

选项与参数:

-a :列出目前系统上面的所有布尔值条款设定为开启或关闭值

范例一:查询本系统内所有的布尔值设定状况

[root@www ~]# getsebool -a

abrt_anon_write --> off

allow_console_login --> on

allow_cvs_read_shadow --> off

显示出目前的布尔值状态

那么如果查询到某个布尔值,并且以 sesearch 知道该布尔值的用途后,想要关闭或启动他,又该如何处置?

[root@www ~]# setsebool [-P] 布尔值=[0|1]

选项与参数:

-P :直接将设定值写入配置文件,该设定数据未来会生效的!

范例一:查询 httpd_enable_homedirs 是否为 on,若不为 on 请启动他

[root@www ~]# getsebool httpd_enable_homedirs

httpd_enable_homedirs --> off <==结果是 off ,依题意给他启动!

[root@www ~]# setsebool -P httpd_enable_homedirs=1
[root@www ~]# getsebool httpd_enable_homedirs

httpd_enable_homedirs --> on

这个 setsebool 最好记得一定要加上 -P 的选项,因为这样才能将此设定写入配置文件。这是非常棒的工具组。你一定要知道如何使用 getsebool 与 setsebool 才行。

15. SELinux 登录文件记录所需服务

上述的指令功能当中,尤其是 setsebool, chcon, restorecon 等,都是为了当你的某些网络服务无法正常提供相关功能时, 才需要进行修改的一些指令动作。但是,我们怎么知道哪个时候才需要进行这些指令的修改啊?我们怎么知道系统因为 SELinux 的问题导致网络服务不对劲?CentOS提供几个服务记录 SELinux 产生的错误,那就是 auditd 与 setroubleshootd

setroubleshoot --> 错误讯息写入 /var/log/messages

几乎所有 SELinux 相关的程序都会以 se 为开头,这个服务也是以 se 为开头!而 troubleshoot 大家都知道是错误克服, 因此这个 setroubleshoot 自然就得要启动他啦,这个服务会将关于 SELinux 的错误讯息与克服方法记录到 /var/log/messages 与 /var/log/setroubleshoot/ 里头,所以你一定得要启动这个服务才好。启动这个服务之前当然就是得要安装它, 它总共需要两个软件,分别是 setroublshoot 与 setroubleshoot-server,如果你没有安装,请自行使用 yum 安装。

此外,原本的 SELinux 信息本来是以两个服务来记录的,分别是 auditd 与 setroubleshootd。既然是同样的信息, 因此 CentOS 6.x 将两者整合在 auditd 当中啦!所以,并没有 setroubleshootd 的服务存在了喔!因此, 当你安装好了 setroubleshoot-server 之后,请记得要重新启动 auditd,否则 setroubleshootd 的功能不会被启动的。

[root@www ~]# yum install setroubleshoot setroubleshoot-server

整合到 auditd 当中

[root@www ~]# /etc/init.d/auditd restart

Tips:

事实上,CentOS 6.x 对 setroubleshootd 的运作方式是: (1)先由 auditd 去呼叫 audispd 服务, (2)然后 audispd 服务去启动 sedispatch 程序, (3)sedispatch 再将原本的 auditd 讯息转成 setroubleshootd 的讯息,进一步储存下来的!

那么如果有发生错误时,讯息像什么呢?我们使用 httpd 这支程序产生的错误来说明好了。假设你需要启动 WWW 服务器, 我们的 WWW 是由 httpd 这支服务提供的,因此你必须要安装且启动它才行:

[root@www ~]# /etc/init.d/httpd start
[root@www ~]# netstat -tlnp | grep http

tcp 0 0 :::80 :::* LISTEN 2218/httpd

看到80端口表示http服务已经启动。

这个时候我们的 WWW 服务器就安装妥当了。我们的首页其实是放置到 /var/www/html 目录下的,且文件名必须要是 index.html。 那如果我使用底下的模式来进行首页的处理时,可能就会产生 SELinux 的问题了!我们就来模拟一下出问题的状况吧!

[root@www ~]# echo "My first selinux check" > index.html
[root@www ~]# ll index.html

-rw-r--r--. 1 root root 23 2011-07-20 18:16 index.html <==权限没问题

[root@www ~]# mv index.html /var/www/html

此时我们就可以打开浏览器,然后在浏览器上面输入 Linux 自己的 IP 来查察看,看能不能连上自己的 WWW 首页。 因为我们这次安装并没有图形接口,所以使用 links 来查察 http://localhost/index.html 看看!你会得到如下的讯息:

[root@www ~]# links http://localhost/index.html -dump
Forbidden

You don't have permission to access /index.html on this server.

Apache/2.2.15 (CentOS) Server at localhost Port 80

画面最明显的地方就是告诉你,你并没有权限可以存取 index.html 的!见鬼了!明明权限是对的喔!那怎办? 没关系,就透过 setroubleshoot 的功能去检查看看。此时请分析一下 /var/log/messages 的内容吧!有点像这样:

[root@www ~]# cat /var/log/messages | grep setroubleshoot

Jul 21 14:53:20 www setroubleshoot: SELinux is preventing /usr/sbin/httpd

"getattr" access to /var/www/html/index.html. For complete SELinux messages.

run sealert -l 6c927892-2469-4fcc-8568-949da0b4cf8d

上面的错误讯息可是同一行喔!大纲说的是‘SElinux 被用来避免 httpd 读取到错误的安全性本文, 想要查阅完整的数据,请执行 sealert -l …’没错!你注意到了!重点就是 sealert -l 啦! 上面提供的信息并不完整,想要更完整的说明得要靠 sealert 配合侦测到的错误代码来处理。 实际处理后会像这样:

[root@www ~]# sealert -l 6c927892-2469-4fcc-8568-949da0b4cf8d

Summary:

SELinux is preventing /usr/sbin/httpd "getattr" access to

/var/www/html/index.html. <==刚刚在 messages 里面看到的信息!

Detailed Description: <==接下来是详细的状况解析!要看喔!

SELinux denied access requested by httpd. /var/www/html/index.html may

be a mislabeled. /var/www/html/index.html default SELinux type is

httpd_sys_content_t, but its current type is admin_home_t. Changing

this file back to the default type, may fix your problem.

….(中间省略)….

Allowing Access: <==超重要的项目!要看要看!

You can restore the default system context to this file by executing the

restorecon command. restorecon '/var/www/html/index.html', if this file

is a directory, you can recursively restore using restorecon -R

'/var/www/html/index.html'.

Fix Command:

/sbin/restorecon '/var/www/html/index.html' <==知道如何解决了吗?

Additional Information: <==还有一些额外的信息!

….(底下省略)….

[root@www ~]# restorecon -Rv '/var/www/html/index.html'

restorecon reset /var/www/html/index.html context unconfined_u:object_r:

admin_home_t:s0->system_u:object_r:httpd_sys_content_t:s0

重点就是上面特殊字体显示的地方!你只要照着‘Allowing Access’里面的提示去进行处理, 就能够完成你的 SELinux 类型设定了!比对刚刚我们上个小节提到的 restorecon 与 chcon 你就能够知道, setroubleshoot 提供的讯息有多有效了吧!不管出了啥 SELinux 的问题,绝大部分在 setroubleshoot 的服务中就会告诉你解决之道!所以,很多东西都不用背的!

用 email 或在指令列上面直接提供 setroubleshoot 错误讯息

如果每次测试都得要到 /var/log/messages 去分析,那真是挺麻烦的啊!没关系,我们可以透过 email 或 console 的方式来将信息产生!也就是说,我们可以让 setroubleshoot 主动的发送产生的信息到我们指定的 email,这样可以方便我们实时的分析喔!怎么办到?就修改 setroubleshoot 的配置文件即可。你可以查阅 /etc/setroubleshoot/setroubleshoot.cfg 这个档案的内容,我们只需要修改的地方如下:

[root@www ~]# vim /etc/setroubleshoot/setroubleshoot.cfg

[email]

大约在 81 行左右,这行要存在才行!

recipients_filepath = /var/lib/setroubleshoot/email_alert_recipients

大约在 147 行左右,将原本的 False 修改成 True 先!

console = True

[root@www ~]# vim /var/lib/setroubleshoot/email_alert_recipients

root@localhost

your@email.address

[root@www ~]# /etc/init.d/auditd restart

之后你就可以透过分析你的 email 来取得 SELinux 的错误讯息啰!非常的简单吧!只是要注意,上述的填写 email 的档案中, 不能只写账号,你要连同 @localhost 都写上,这样本机上面的 root 才能收到信件喔!就这么简单哩!

16. SELinux 错误克服的总结

我们来简单的做个总结吧!因为你的网络联机要通过 SELinux 才的权限判定后才能够继续 rwx 的权限比对。而 SELinux 的比对主要又分为: (1)需要通过政策的各项规则比对后 (2)才能够进行 SELinux type 安全性本文的比对,这两项工作都得要正确才行。而后续的 SELinux 修改主要是透过 chcon, restorecon, setsebool 等指令来处理的。但是如何处理呢?可以透过分析 /var/log/messages 内提供的 setroubleshoot 的信息来处置!这样就很轻松的可以管理你的 SELinux 啰!

但是如果因为某些原因,举例来说 CentOS 没有规范到的 setroubleshoot 信息时,可能你还是无法了解到事情到底是哪里出错。 那此时我们会这样建议:

在服务与 rwx 权限都没有问题,却无法成功的使用网络服务时;

先使用 setenforce 0 设定为宽容模式;

再次使用该网络服务,如果这样就能用,表示 SELinux 出问题,请往下继续处理。如果这样还不能用,那问题就不是在 SELinux 上面!请再找其他解决方法,底下的动作不适合你;

分析 /var/log/messages 内的信息,找到 sealert -l 相关的信息并且执行;

找到 Allow Access 的关键词,照里面的动作来进行 SELinux 的错误克服;

处理完毕重新 setenforce 1 ,再次测试网络服务吧!

这样就能够很轻松的管理你的 SELinux 啦!不需要想太多!分析登录档就对啦!

本文已同步至博客站,尊重原创,转载时请在正文中附带以下链接:

https://www.linuxrumen.com/rmxx/806.html

点击了解更多,快速查看更多的技术文章列表。