linux selinux


什么是 SELinux

回到顶部
SELinux是Security Enhanced Linux的缩写,意为安全强化的Linux!
SELinux官网参考:http://www.nsa.gov/research/selinux/
SELinux由美国国家安全局(NSA)开发,用于对进程、文件等细部权限进行安全强化设置的一个内核模块! 目的是为了防止对linux资源的误用。
系统资源通过进程进行存取。传统的进程访问文件的权限控制方式称为DAC自主式访问控制(Discretionary Access Control)。 当进程访问某个文件时, 系统根据进程拥有者或群组比对文件的权限,若通过权限检查,就可以读写该文件了。
这些我们都已经非常熟悉了。
DAC自主式访问控制存在一些安全隐患,例如root具有最高权限,一旦某个恶意进程获取了root权限, 那么整部linux主机的资源就可以任意存取了。
另外如果系统管理员网络完全意识太差或者是个新手,为了操作方便,干脆将网站根目录/var/www/html/的权限设置为drwxrwxrwx。 这样任何进程都可以进入该目录随便读写了,特别是该目录通过www服务进程对外提供Internet服务, 一旦www服务进程开启了写入功能,那么任何人都可以对该目录写入数据,没几天硬盘就会被撑爆,实在太危险了。
这些问题是非常严重的! SELinux可以说是网络服务进程能否存取系统资源的一道关卡! 以政策规则订定特定进程读取特定文件:委任式访问控制, MAC
为了避免DAC可能会发生的权限安全问题,SELinux引入了MAC委任式访问控制方式(Mandatory Access Control,MAC)!
MAC委任式访问控制可以针对特定的进程与特定的文件资源进行权限的设置控管! MAC控制的主体是进程而不是用户! 即使超级用户root在使用不同的进程时,所取得的权限也不一定是root,而是根据该进程的设定。 此外,主体进程也不能任意使用系统文件资源,因为每个文件资源也有针对该主体进程设置的权限! 如此一来,控件目就细的多了!但整个系统进程那么多、文件那么多,一项一项控制可就没完没了! SELinux提供一些预设的政策(Policy),并在该政策内提供多个规则(rule),用户可以选择是否启用该控制规则!
在委任式访问控制的设定下,进程能够活动的空间就变小了! 举例来说, 提供WWW服务的httpd进程, 在MAC的控制下仅能在/var/www/目录下存取文件, 如果httpd进程想要到其他目录去存取数据, 除了规则设定要开放外,目标目录也得要设定成httpd可读取的模式(type)! 限制非常多! 所以即使httpd进程被黑客取得了控制权,也无权浏览/etc/shadow等重要的配置文件!
下图说明了WWW网络服务器Apache进程在传统DAC访问控制和加上MAC访问控制后区别: DAC和MAC的对比 图 以Apache为例说明DAC和MAC的区别 左边为DAC控制方式,apache进程的用户为root,可以在三个目录内读写文件,右边加上SELinux的MAC访问控制后, SELinux仅会针对Apache进程放行部份的目录, 其他非正规目录就不会放行给Apache使用! 即使apache本身具备root权限,也不能跨越MAC的限制!

SELinux运作模式

回到顶部
SELinux通过MAC方式来控管进程,控制的主体是进程,目标则是进程主体访问的资源文件!
主体(Subject):SELinux管理的是进程主体,主体就是进程process;
目标(Object):主体进程访问的目标资源一般就是文件系统。目标可以等同于文件系统;
政策(Policy):由于进程与文件数量庞大,因此SELinux会依据某些服务来制订基本的存取安全性政策。 这些政策内还有详细的规则(rule)来指定不同的服务开放某些资源的存取与否。
CentOS 7.x仅提供三个主要的政策,分别是:
targeted :为默认政策,针对网络服务限制较多,针对本机限制较少,是;
minimum :由targeted修订而来,仅针对选择的进程来保护!
mls: 完整的SELinux限制,限制较为严格。
建议使用默认的targeted政策。
安全上下文(security context):
主体能否访问目标除了政策指定外,主体与目标的安全上下文必须一致才能够顺利存取。 安全上下文(security context)有点类似文件系统的rwx! 安全上下文的内容与设定是非常重要的! 如果设定错误,主体进程就无法存取文件系统目标资源, 会一直出现权限不符错误信息!
由于 SELinux 重点在保护进程读取文件系统的权限,因此我们将上述的几个说明搭配起来,绘制成 底下的流程图,比较好理解: 图 16.5.2、SELinux 运作的各组件之相关性 上图的重点在主体如何取得目标的资源访问权限! 由上图我们可以发现, (1)主体进程必须通过SELinux政策内的规则放行后,就可以与目标资源进行安全上下文的比对, (2)若比对失败则无法存取目标,若比对成功则可以存取目标。 问题是,最终能否存取目标还是与文件系统的rwx权限设定有关喔! 如此一来,加入了SELinux之后,出现权限不符的情况时,你就得要一步一步的分析可能的问题了!
CentOS 7.x的target政策已经帮我们制订好非常多的规则,只需要知道如何开启和关闭某项规则的放行与否即可。 那个安全上下文比较麻烦!因为你可能需要自行配置文件案的安全上下文呢! 为何需要自行设定啊? 举例来说,你不也常常进行文件的 rwx 的重新设定吗? 这个安全上下文你就将他想成 SELinux 内必备的 rwx 就是了!这样比较好理解啦。
安全上下文存在于主体进程中与目标文件资源中。进程在内存内,所以安全上下文可以存入是没问题。 那文件的安全上下文是记录在哪里呢?事实上,安全上下文是放置到文件的 inode 内的,因此主体进程想要读取目标文件资源时, 同样需要读取inode , 这inode内就可以比对安全上下文以及rwx等权限值是否正确,而给予适当的读取权限依据。
那么安全上下文到底是什么样的存在呢?我们先来看看/root底下的文件的安全上下文好了。 观察安全上下文可使用ls -Z去观察如下:(注意:你必须已经启动了 SELinux 才行! 若尚未启动,这部份请稍微看过一遍即可。底下会介绍如何启动 SELinux 喔!)
先来观察一下root家目录底下的文件的SELinux相关信息:
            [root@initroot ~]# ls -Z
            -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
            -rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg
            -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 regular_express.txt
            
上面仅列出数个预设的文件,安全上下文分为三个字段,字段之间用冒号分隔。 这三个字段的意义为:
Identify:role:type
身份识别:角色:类型
身份识别(Identify):相当于账号方面的身份识别!主要的身份识别常见有底下几种常见的类型:
unconfined_u:不受限的用户,也就是说,该文件来自于不受限的进程所产生的! 一般来说,我们使用可登入账号来取得bash之后, 预设的bash环境是不受SELinux管制的 因为bash并不是什么特别的网络服务!因此,不受SELinux限制的bash进程所产生的文件, 其身份识别大多就是unconfined_u!
system_u:系统用户,大部分就是系统自己产生的文件!
基本上,如果是系统或软件本身所提供的文件,大多就是system_u这个身份名称, 如果是用户通过bash建立的文件,大多则是不受限的unconfined_u身份。 如果是网络服务所产生的文件,或者是系统服务运作过程产生的文件,则大部分的识别就会是system_u!
系统安装主动产生的anaconda-ks.cfs及initial-setup-ks.cfg就是system_u, 而从网络上面抓下来的regular_express.txt就是unconfined_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下的安全上下文为何?
再来观察一下系统进程的SELinux相关信息
            [root@initroot ~]# ps -eZ
            LABEL PID TTY TIME CMD
            system_u:system_r:init_t:s0 1 ? 00:00:03 systemd
            system_u:system_r:kernel_t:s0 2 ? 00:00:00 kthreadd
            system_u:system_r:kernel_t:s0 3 ? 00:00:00 ksoftirqd/0
            ....省略...
            unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 31513 ? 00:00:00 sshd
            unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 31535 pts/0 00:00:00 bash
            
基本上进程主要就分为两大类,一种是系统有受限的system_u:system_r,另一种则可能是用户自己的, 比较不受限的进程(通常是本机用户自己执行的程序),亦即是unconfined_u:unconfined_r这两种!
基本上,这些对应资料在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等文件来说明。
1. 先看看crond这个进程的安全上下文:
            [root@initroot ~]# ps -eZ | grep cron
            system_u:system_r:crond_t:s0-s0:c0.c1023 1338 ? 00:00:01 crond
            system_u:system_r:crond_t:s0-s0:c0.c1023 1340 ? 00:00:00 atd
            
这个安全上下文的类型名称为crond_t格式!
2. 再来瞧瞧执行档、配置文件等的安全上下文:
            [root@initroot ~]# ll -Zd /usr/sbin/crond /etc/crontab /etc/cron.d
            drwxr-xr-x. root root system_u:object_r:system_cron_spool_t:s0 /etc/cron.d
            -rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 /etc/crontab
            -rwxr-xr-x. root root system_u:object_r:crond_exec_t:s0 /usr/sbin/crond
            
执行/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)。
文字看起来不太容易了解,我们使用图示来说明这几个东西的关系!
图 16.5.3、主体进程取得的 domain 与目标文件资源的 type 相互关系以 crond 为例 上图的意义我们可以这样看的:
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权限的规范!
上述的流程告诉我们几个重点,第一个是政策内需要制订详细的domain/type相关性; 第二个是若文件的type设定错误, 那么即使权限设定为rwx全开的777,该主体进程也无法读取目标文件资源的啦! 不过如此一来, 也就可以避免用户将他的家目录设定为777时所造成的权限困扰。
真的是这样吗?没关系~让我们来做个测试练习吧!就是,万一你的crond配置文件的SELinux并不是system_cron_spool_t时, 该配置文件真的可以顺利的被读取运作吗?来看看底下的范例!
1. 先假设你因为不熟的缘故,因此是在root家目录建立一个如下的cron设定:
            [root@initroot ~]# vim checktime
            10 * * * * root sleep 60s
            
2. 检查后才发现文件放错目录了,又不想要保留副本,因此使用mv移动到正确目录:
            [root@initroot ~]# mv checktime /etc/cron.d
            [root@initroot ~]# ll /etc/cron.d/checktime
            -rw-r--r--. 1 root root 27 Aug 7 18:41 /etc/cron.d/checktime
            
仔细看喔,权限是 644 ,确定没有问题!任何进程都能够读取喔!
3. 强制重新启动 crond ,然后偷看一下登录档,看看有没有问题发生!
            [root@initroot ~]# systemctl restart crond
            [root@initroot ~]# tail /var/log/cron
            Aug 7 18:46:01 study crond[28174]: ((null)) Unauthorized SELinux context=system_u:system_r:system_cronjob_t:s0-s0:c0.c1023 file_context=unconfined_u:object_r:admin_home_t:s0
            (/etc/cron.d/checktime)
            Aug 7 18:46:01 study crond[28174]: (root) FAILED (loading cron table)
            
上面的意思是,有错误!因为原本的安全上下文与文件的实际安全上下文无法搭配的缘故!
您瞧瞧~从上面的测试案例来看,我们的配置文件确实没有办法被crond这个服务所读取喔!而原因在登录档内就有说明, 主要就是来自SELinux安全上下文(context)type的不同所致喔!没办法读就没办法读,先放着~后面再来学怎么处理这问题吧!

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

回到顶部
并非所有的Linux distributions都支持SELinux的,所以你必须要先观察一下你的系统版本为何! 这里介绍的 CentOS 7.x 本身就有支持 SELinux 啦! 所以你不需要自行编译 SELinux 到你的Linux 内核中! 目前 SELinux 依据启动与否,共有三种模式,分别如下:
enforcing:强制模式,代表 SELinux 运作中,且已经正确的开始限制domain/type了;
permissive:宽容模式:代表 SELinux 运作中,不过仅会有警告讯息并不会实际限制domain/type的存取。
这种模式可以运来作为SELinux的debug之用;
disabled:关闭,SELinux并没有实际运作。
这三种模式跟图 16.5.2 之间的关系如何呢?我们前面不是谈过主体进程需要经过政策规则、安全上下文 比对之后,加上 rwx 的权限规范, 若一切合理才会让进程顺利的读取文件吗? 那么这个SELinux的三种模式与上面谈到的政策规则、安全上下文的关系为何呢? 我们还是使用图标加上流程来让大家理解一下:
图 16.5.4、SELinux 的三种类型与实际运作流程图示意 就如上图所示,首先,你得要知道,并不是所有的进程都会被SELinux所管制,因此最左边会出现一个所谓的有受限的进程主体! 那如何观察有没有受限(confined )呢? 很简单啊!就通过 ps -eZ去撷取! 举例来说,我们来找一找crond与bash这两只进程是否有被限制吧?
            [root@initroot ~]# ps -eZ | grep -E 'cron|bash'
            system_u:system_r:crond_t:s0-s0:c0.c1023 1340 ? 00:00:00 atd
            unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 13888 tty2 00:00:00 bash
            unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 28054 pts/0 00:00:00 bash
            unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 28094 pts/0 00:00:00 bash
            system_u:system_r:crond_t:s0-s0:c0.c1023 28174 ? 00:00:00 crond
            
如前所述,因为在目前target这个政策底下,只有第三个类型(type)字段会有影响, 因此我们上表仅列出第三个字段的数据而已。 我们可以看到, crond确实是有受限的主体进程,而bash因为是本机进程,因此就是不受限(unconfined_t)的类型! 也就是说,bash是不需要经过图16.5.4的流程,而是直接去判断rwx而已~。
了解了受限的主体进程的意义之后,再来了解一下,三种模式的运作吧! 首先,如果是Disabled的模式,那么SELinux将不会运作,当然受限的进程也不会经过SELinux, 也是直接去判断rwx而已。 那如果是宽容(permissive) 模式呢?这种模式也是不会将主体进程抵挡(所以箭头是可以直接穿透的喔!), 不过万一没有通过政策规则,或者是安全上下文的比对时, 那么该读写动作将会被纪录起来(log),可作为未来检查问题的判断依据。
至于最终那个Enforcing模式,就是实际将受限主体进入规则比对、安全上下文比对的流程, 若失败,就直接抵挡主体进程的读写行为,并且将他记录下来。 如果通通没问题,这才进入到rwx权限的判断喔!这样可以理解三种模式的行为了吗?
那你怎么知道目前的SELinux模式呢?就通过getenforce吧!
            [root@initroot ~]# getenforce
            Enforcing
            
#显示出目前的模式为Enforcing!
如何知道SELinux的政策(Policy)为何呢?可以使用sestatus来观察:
            [root@initroot ~]# sestatus [-vb]
            
选项与参数:
-v :检查列于 /etc/sestatus.conf 内的文件与进程的安全上下文内容;
-b :将目前政策的规则布尔值列出,亦即某些规则 (rule) 是否要启动 (0/1) 之意;
列出目前的SELinux使用哪个政策(Policy):
            [root@initroot ~]# sestatus
            SELinux status: enabled #是否启动 SELinux
            SELinuxfs mount: /sys/fs/selinux #SELinux的相关文件数据挂载点
            SELinux root directory: /etc/selinux #SELinux的根目录所在
            Loaded policy name: targeted #目前的政策为何?
            Current mode: enforcing #目前的模式
            Mode from config file: enforcing #目前配置文件内规范的SELinux模式
            Policy MLS status: enabled #是否含有MLS的模式机制
            Policy deny_unknown status: allowed #是否预设抵挡未知的主体进程
            Max kernel policy version: 28
            
如上所示,目前是启动的,而且是Enforcing模式,而由配置文件查询得知亦为Enforcing模式。 目前的预设政策为targeted这一个。你应该要有疑问的是, SELinux的配置文件是哪个文件啊? 其实就是/etc/selinux/config 这个文件喔! 我们来看看内容:
            [root@initroot ~]# vim /etc/selinux/config
            SELINUX=enforcing #调整 enforcing|disabled|permissive
            SELINUXTYPE=targeted #目前仅有 targeted, mls, minimum 三种政策
            
若有需要修改预设政策的话,就直接改 SELINUX=enforcing 那一行即可喔!

启动和关闭SELinux

回到顶部
上面是默认的政策与启动的模式!你要注意的是,如果改变了政策则需要重新启动;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他两个,那也必须要重新启动。这是因为 SELinux 是整合到内核里面去的, 你只可以在 SELinux 运作下切换成为强制 (enforcing) 或宽容 (permissive) 模式,不能够直接关闭 SELinux 的! 如果刚刚你发现 getenforce 出现 disabled 时,请到上述文件 修改成为 enforcing 然后重新启动吧!
不过你要注意的是,如果从 disable 转到启动 SELinux 的模式时, 由于系统必须要针对文件写入安 全性本文的信息,因此开机过程会花费不少时间在等待重新写入 SELinux 安全上下文 (有时也称为 SELinux Label) ,而且在写完之后还得要再次的重新启动一次喔!你必须要等待粉长一段时间! 等 到下次开机成功后,再使用 getenforce 或 sestatus 来观察看看有否成功的启动到 Enforcing 的模式啰!
如果你已经在 Enforcing 的模式,但是可能由于一些设定的问题导致 SELinux 让某些服务无法正常 的运作, 此时你可以将 Enforcing 的模式改为宽容 (permissive) 的模式,让 SELinux 只会警告无法 顺利联机的讯息, 而不是直接抵挡主体进程的读取权限。让 SELinux 模式在 enforcing 与 permissive 之间切换的方法为:
            [root@initroot ~]# setenforce [0|1]
            
选项与参数:
0 :转成 permissive 宽容模式;
1 :转成 Enforcing 强制模式
范例一:将 SELinux 在 Enforcing 与 permissive 之间切换与观察
            [root@initroot ~]# setenforce 0
            [root@initroot ~]# getenforce
            Permissive
            [root@initroot ~]# setenforce 1
            [root@initroot ~]# getenforce
            Enforcing
            
不过请注意, setenforce 无法在 Disabled 的模式底下进行模式的切换喔!
在某些特殊的情况底下,你从 Disabled 切换成 Enforcing 之后,竟然有一堆服务无法 顺利启动,都会跟你说在/lib/xxx里面的数据没有权限读取,所以启动失败。 这大多是由于在重新写入SELinux type (Relabel)出错之故,使用Permissive就没有这个错误。 那如何处理呢?最简单的方法就是在Permissive的状态下,使用restorecon -Rv /重新还原所有SELinux的类型,就能够处理这个错误!

SELinux政策内的规则管理

回到顶部
从图 16.5.4 里面,我们知道 SELinux 的三种模式是会影响到主体进程的放行与否。 如果是进入Enforcing模式,那么接着下来会影响到主体进程的, 当然就是第二关: target政策内的各项规则(rules) 了! 好了,那么我们怎么知道目前这个政策里面到底有多少会影响到主体进程的规则呢?
很简单,就通过getsebool来瞧一瞧即可。
SELinux 各个规则的布尔值查询 getsebool
如果想要查询系统上面全部规则的启动与否(on/off,亦即布尔值),很简单的通过sestatus -b或getsebool -a均可!
            [root@initroot ~]# getsebool [-a] [规则的名称]
            
-a :列出目前系统上面的所有 SELinux 规则的布尔值为开启或关闭值
查询本系统内所有的布尔值设定状况:
            [root@initroot ~]# getsebool -a
            abrt_anon_write --> off
            abrt_handle_event --> off
            ....(中间省略)....
            cron_can_relabel --> off
            # 这个跟 cornd 比较有关!
            cron_userdomain_transition --> on
            ....(中间省略)....
            httpd_enable_homedirs --> off
            # 这当然就是跟网页,亦即 http 有关的啰!
            ....(底下省略)....
            
这么多的SELinux规则喔!每个规则后面都列出现在是允许放行还是不许放行的布尔值!
SELinux各个规则规范的主体进程能够读取的文件。
SELinux type查询seinfo, sesearch 我们现在知道有这么多的SELinux规则,但是每个规则内到底是在限制什么东西?如果你想要知道的话, 那就得要使用seinfo等工具! 这些工具并没有在我们安装时就安装了,因此请拿出原版光盘, 放到光驱,假设你将原版光盘挂载到 /mnt 底下,那么接下来这么作, 先安装好我们所需要的软件才行!
            [root@initroot ~]# yum install /mnt/Packages/setools-console-*
            很快的安装完毕之后,我们就可以来使用 seinfo, sesearch 等指令了!
            [root@initroot ~]# seinfo [-Atrub]
            
选项与参数:
-A :列出 SELinux 的状态、规则布尔值、身份识别、角色、类别等所有信息
-u :列出 SELinux 的所有身份识别 (user) 种类
-r :列出 SELinux 的所有角色 (role) 种类
-t :列出 SELinux 的所有类别 (type) 种类
-b :列出所有规则的种类 (布尔值)
列出SELinux在此政策下的统计状态
            [root@initroot ~]# seinfo
            Statistics for policy file: /sys/fs/selinux/policy
            Policy Version & Type: v.28 (binary, mls)
            Classes:
            83 Permissions: 255
            1 Categories: 1024
            Types: 4620 Attributes: 357
            Users: 8
            Sensitivities:
            Booleans:
            Allow:
            295
            102249
            Auditallow: 160
            Type_trans: 16863
            Roles:
            Cond. Expr.:
            Neverallow:
            Dontaudit:
            14
            346
            0
            8413
            Type_change: 74
            30
            Type_member: 35 Role allow:
            Role_trans: 412 Range_trans:
            5439
            ....(底下省略)....
            
从上面可以看到这个政策是targeted ,此政策的安全上下文类别有4620个;
而各种SELinux的规则(Booleans)共制订了295条!
我们在 16.5.2 里面简单的谈到了几个身份识别 (user) 以及角色 (role) 而已, 如果你想要查询目前所有的身份识别与角色,就使用seinfo -u及seinfo -r就可以知道了! 至于简单的统计数据,就直接输入seinfo即可! 但是上面还是没有谈到规则相关的东西耶~ 没关系~一个一个来~ 我们在16.5.1 的最后面谈到 /etc/cron.d/checktime 的 SELinux type 类型不太对~ 那我们也知道crond这个进程的type是crond_t, 能不能找一下crond_t能够读取的文件SELinux type有哪些呢?
            [root@initroot ~]# sesearch [-A] [-s 主体类别] [-t 目标类别] [-b 布尔值]
            
选项与参数:
-A :列出后面数据中,允许读取或放行的相关数据
-t :后面还要接类别,例如 -t httpd_t
-b :后面还要接 SELinux 的规则,例如 -b httpd_enable_ftp_server
找出crond_t这个主体进程能够读取的文件SELinux type
            [root@initroot ~]# sesearch -A -s crond_t | grep spool
            allow crond_t system_cron_spool_t : file { ioctl read write create getattr ..
            allow crond_t system_cron_spool_t : dir { ioctl read getattr lock search op..
            allow crond_t user_cron_spool_t : file { ioctl read write create getattr se..
            allow crond_t user_cron_spool_t : dir { ioctl read write getattr lock add_n..
            allow crond_t user_cron_spool_t : lnk_file { read getattr } ;
            
allow后面接主体进程以及文件的SELinux type,上面的数据是撷取出来的, 意思是说,crond_t可以读取system_cron_spool_t的文件/目录类型~等等!
找出crond_t是否能够读取/etc/cron.d/checktime这个我们自定义的配置文件:
            [root@initroot ~]# ll -Z /etc/cron.d/checktime
            -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /etc/cron.d/checktime
            # 两个重点,一个是 SELinux type 为 admin_home_t,一个是文件 (file)
            [root@initroot ~]# sesearch -A -s crond_t | grep admin_home_t
            allow domain admin_home_t : dir { getattr search open } ;
            allow domain admin_home_t : lnk_file { read getattr } ;
            allow crond_t admin_home_t : dir { ioctl read getattr lock search open } ;
            allow crond_t admin_home_t : lnk_file { read getattr } ;
            
虽然有crond_t admin_home_t存在,但是这是总体的信息,并没有针对某些规则的寻找~ 所以还是不确定checktime能否被读取。但是,基本上就是SELinux type出问题~因此才会无法读取的!
所以,现在我们知道/etc/cron.d/checktime这个我们自己复制过去的文件会没有办法被读取的原因, 就是因为SELinux type错误啦! 根本就无法被读取~好~那现在我们来查一查, 那getsebool -a里面看到的httpd_enable_homedirs到底是什么? 又是规范了哪些主体进程能够读取的SELinux type呢?
            [root@initroot ~]# semanage boolean -l | grep httpd_enable_homedirs
            SELinux boolean State
            httpd_enable_homedirs (off
            Default Description
            ,
            off)
            Allow httpd to enable homedirs
            
httpd_enable_homedirs的功能是允许httpd进程去读取用户家目录的意思~
            [root@initroot ~]# sesearch -A -b httpd_enable_homedirs
            
列出httpd_enable_homedirs这个规则当中,主体进程能够读取的文件
            SELinux type
            Found 43 semantic av rules:allow httpd_t home_root_t : dir { ioctl read getattr lock search open } ;
            allow httpd_t home_root_t : lnk_file { read getattr } ;
            allow httpd_t user_home_type : dir { getattr search open } ;
            allow httpd_t user_home_type : lnk_file { read getattr } ;
            ....(后面省略)....
            
从上面的数据才可以理解,在这个规则中,主要是放行 httpd_t 能否读取用户家目录的文件!
所以,如果这个规则没有启动,基本上, httpd_t 这种进程就无法读取用户家目录下的文件!
修改SELinux规则的布尔值 setsebool
那么如果查询到某个SELinux rule,并且以sesearch知道该规则的用途后,想要关闭或启动他,又该如何处置?
            [root@initroot ~]# setsebool [-P] 规则名称 [0|1]
            
-P:直接将设定值写入配置文件,该设定数据未来会生效的!
查询httpd_enable_homedirs这个规则的状态,并且修改这个规则成为不同的布尔值
            [root@initroot ~]# getsebool httpd_enable_homedirs
            httpd_enable_homedirs --> off
            #结果是 off ,依题意给他启动看看!
            [root@initroot ~]# setsebool -P httpd_enable_homedirs 1 # 会跑很久很久!请耐心等待!
            [root@initroot ~]# getsebool httpd_enable_homedirs
            httpd_enable_homedirs --> on
            
这个setsebool最好记得一定要加上-P的选项!因为这样才能将此设定写入配置文件! 这是非常棒的工具组!你一定要知道如何使用getsebool与setsebool才行!

修改SELinux安全上下文

回到顶部
再次的回到图 16.5.4 上头去,现在我们知道 SELinux 对受限的主体进程有没有影响, 第一关考虑SELinux的三种类型,第二关考虑SELinux的政策规则是否放行,第三关则是开始比对SELinux type! 可以通过sesearch来找到主体进程与文件的SELinux type关系! 现在来修改文件的SELinux type,以让主体进程能够读到正确的文件啊!
使用chcon手动修改文件的SELinux type
            [root@initroot ~]# chcon [-R] [-t type] [-u user] [-r role] 文件
            [root@initroot ~]# chcon [-R] --reference=范例文件 文件
            
选项与参数:
-R :连同该目录下的次目录也同时修改;
-t :后面接安全上下文的类型字段!例如httpd_sys_content_t ;
-u :后面接身份识别,例如 system_u; (不重要)
-r :后面街角色,例如 system_r;
-v :若有变化成功,请将变动的结果列出来(不重要)
--reference=范例文件:拿某个文件当范例来修改后续接的文件的类型!
查询/etc/hosts的SELinux type,并将该类型套用到/etc/cron.d/checktime上
            [root@initroot ~]# ll -Z /etc/hosts
            -rw-r--r--. root root system_u:object_r:net_conf_t:s0 /etc/hosts
            [root@initroot ~]# chcon -v -t net_conf_t /etc/cron.d/checktime
            changing security context of ‘/etc/cron.d/checktime’
            [root@initroot ~]# ll -Z /etc/cron.d/checktime
            -rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /etc/cron.d/checktime
            
直接以/etc/shadow SELinux type套用到/etc/cron.d/checktime 上!
            [root@initroot ~]# chcon -v --reference=/etc/shadow /etc/cron.d/checktime
            [root@initroot ~]# ll -Z /etc/shadow /etc/cron.d/checktime
            -rw-r--r--. root root system_u:object_r:shadow_t:s0 /etc/cron.d/checktime
            ----------. root root system_u:object_r:shadow_t:s0 /etc/shadow
            
上面的练习都没有正确的解答!因为正确的SELinux type应该就是要以/etc/cron.d/底下的文件为标准来处理才对啊~ 能不能让SELinux自己解决默认目录下的SELinux type呢?就用restorecon吧!
使用restorecon让文件恢复正确的SELinux type:
            [root@initroot ~]# restorecon [-Rv] 文件或目录
            
选项与参数:
-R :连同次目录一起修改;
-v :将过程显示到屏幕上
将/etc/cron.d/底下的文件通通恢复成预设的SELinux type:
            [root@initroot ~]# restorecon -Rv /etc/cron.d
            restorecon reset /etc/cron.d/checktime context system_u:object_r:shadow_t:s0->
            system_u:object_r:system_cron_spool_t:s0
            
上面这两行其实是同一行喔!表示将checktime由shadow_t改为system_cron_spool_t
重新启动crond看看有没有正确启动checktime:
            [root@initroot ~]# systemctl restart crond
            [root@initroot ~]# tail /var/log/cron
            
再去瞧瞧这个/var/log/cron的内容,应该就没有错误讯息了 其实,几乎已经忘了chcon这个指令了!因为restorecon主动的回复预设的SELinux type要简单很多! 而且可以一口气恢复整个目录下的文件! 所以,建议你几乎只要记得restorecon搭配-Rv同时加上某个目录这样的指令串即可 修改SELinux的type就变得非常的轻松!
semanage默认目录的安全上下文查询与修改
为什么restorecon可以恢复原本的SELinux type呢?那肯定就是有个地方在纪录每个文件/目录的SELinux默认类型啰? 没错!是这样~那要如何(1)查询预设的 SELinuxtype以及(2)如何增加/修改/删除预设的SELinux type呢?很简单~通过semanage即可! 他是这样使用的:
            [root@initroot ~]# semanage {login|user|port|interface|fcontext|translation} -l
            [root@initroot ~]# semanage fcontext -{a|d|m} [-frst] file_spec
            
选项与参数:
fcontext :主要用在安全上下文方面的用途,
-l 为查询的意思;
-a :增加的意思,你可以增加一些目录的默认安全上下文类型设定;
-m :修改的意思;
-d :删除的意思。
查询/etc /etc/cron.d的预设SELinux type为何?
            [root@initroot ~]# semanage fcontext -l | grep -E '^/etc |^/etc/cron'
            SELinux fcontext type Context
            /etc all files system_u:object_r:etc_t:s0
            /etc/cron\.d(/.*)? all files system_u:object_r:system_cron_spool_t:s0
            
看到上面输出的最后一行,那也是为啥我们直接使用vim去/etc/cron.d底下建立新文件时,预设的SELinux type 就是正确的! 同时,我们也会知道使用restorecon回复正确的SELinux type时,系统会去判断默认的类型为何的依据。 现在让我们来想一想, 如果 (当然是假的!不可能这么干) 我们要建立一个/srv/mycron的目录, 这个目录默认也是需要变成system_cron_spool_t时, 我们应该要如何处理呢?基本上可以这样作:
1. 先建立/srv/mycron同时在内部放入配置文件,同时观察SELinux type
            [root@initroot ~]# mkdir /srv/mycron
            [root@initroot ~]# cp /etc/cron.d/checktime /srv/mycron
            [root@initroot ~]# ll -dZ /srv/mycron /srv/mycron/checktime
            drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /srv/mycron
            -rw-r--r--. root root unconfined_u:object_r:var_t:s0 /srv/mycron/checktime
            
2. 观察一下上层/srv的SELinux type
            [root@initroot ~]# semanage fcontext -l | grep '^/srv'
            SELinux fcontext type Context
            /srv all files system_u:object_r:var_t:s0
            
怪不得mycron会是var_t啰!
3. 将mycron默认值改为system_cron_spool_t!
            [root@initroot ~]# semanage fcontext -a -t system_cron_spool_t "/srv/mycron(/.*)?"
            [root@initroot ~]# semanage fcontext -l | grep '^/srv/mycron'
            SELinux fcontext
            type
            Context/srv/mycron(/.*)?
            all files
            system_u:object_r:system_cron_spool_t:s0
            
4. 恢复/srv/mycron以及子目录相关的SELinux type!
            [root@initroot ~]# restorecon -Rv /srv/mycron
            [root@initroot ~]# ll -dZ /srv/mycron /srv/mycron/*
            drwxr-xr-x. root root unconfined_u:object_r:system_cron_spool_t:s0 /srv/mycron
            -rw-r--r--. root root unconfined_u:object_r:system_cron_spool_t:s0 /srv/mycron/checktime
            
有了默认值,未来就不会不小心被乱改了!这样比较妥当些~
semanage的功能很多,不过主要用到的仅有fcontext这个项目的动作而已。 如上所示, 你可以使用semanage来查询所有的目录默认值,也能够使用他来增加默认值的设定! 如果您学会这些基础的工具, 那么SELinux对你来说,也不是什么太难的咚咚啰!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读