Linux【9】-进程管理4-2-7--安全模块--SELinux策略(seinfo/sesearch)

一、SELinux Targeted、MLS和Minimum策略

对于 SELinux 来说,所选择的策略类型直接决定了使用哪种策略规则来执行主体(进程)可以访问的目标(文件或目录资源)。不仅如此,策略类型还决定需要哪些特定的安全上下文属性。通过策略类型,读者可以更精确地了解 SELinux 所实现的访问控制。

SELinux 提供 3 种不同的策略可供选择,分别是 Targeted、MLS 以及 MiNimum。每个策略分别实现了可满足不同需求的访问控制,因此,为了正确地选择一个满足特定安全需求的策略,就不得不先了解这些策略类型。

Target 策略

Target 策略主要对系统中的服务进程进程访问控制,同时,它还可以限制其他进程和用户。服务进程都被放入沙盒,在此环境中,服务进程会被严格限制,以便使通过此类进程所引发的恶意攻击不会影响到其他服务或 Linux 系统。

沙盒(sandbox)是一种环境,在此环境中的进程可以运行,但对其他进程或资源的访问会被严格控制。换句话说,位于沙盒中的各个进程,都只是运行在自己的域(进程所运行的区域被称为“域”)内,它们无法访问其他进程或资源(除非被授予特殊的权限)。

通过使用此策略,可以更加安全地共享打印服务器、文件服务器、Web 服务器或其他服务,同时降低因访问这些服务而对系统中其他资源造成不利影响的风险。

MLS 策略

MLS,是 Multi-Level Security 的缩写,该策略会对系统中的所有进程进行控制。启用 MLS 之后,用户即便执行最简单的指令(如 ls),都会报错。

Minimum 策略

Minimum 策略的意思是“最小限制”,该策略最初是针对低内存计算机或者设备(比如智能手机)而创建的。

从本质上来说,Minimun 和 Target 类似,不同之处在于,它仅使用基本的策略规则包。对于低内存设备来说,Minumun 策略允许 SELinux 在不消耗过多资源的情况下运行。

注意,你自己所使用的 Linux 发行版本中,可用的策略规则可能与以上所列出的策略规则不完全相同。比如说,在较早的 Linux 发行版本中,仍然可以使用 strict 策略,但在较新的发行版本中,strict 策略被合并在 Targeted 策略中,此策略也是默认使用的策略规则。

那么,我们如何查询当前系统中所使用的 SELinux 的策略是哪一种呢?这就要使用 sestatus 命令来查看了,命令如下:

[root@localhost ~]# sestatus
SELinux status: enabled
#SELinux启用
SELinuxfs mount: /selinux
#SELinux数据的挂载位置
Current mode: enforcing
#运行模式是强制模式
Mode from config file: enforcing
#配置文件所指定的模式也是强制模式
Policy version: 24
#策略版本
Policy from config file: targeted
#目前策略是针对性保护策略

二、SELinux策略规则查看方法

我们知道,当前 SELinux 的默认策略是 targeted,那么这个策略中到底包含有多少个规则呢?使用 seinfo 命令即可查询。命令如下:

[root@localhost ~]# seinfo -b
#还记得-b选项吗?就是查询布尔值,也就是查询规则名字
Conditional Booleans:187
#当前系统中有187个规则
allow_domain_fd_use
allow_ftpd_full_access
allow_sysadm_exec_content
allow_user_exec_content
allow_zebra_write_config
…省略部分输出…

seinfo

seinfo命令只能看到所有规则的名称,如果想要知道规则的具体内容,就需要使用 sesearch 命令了。

sesearch 命令格式如下: [root@localhost ~]# sesearch [选项] [规则类型] [表达式]

选项:

-h:显示帮助信息;

规则类型:

--allow:显示允许的规则;
--neverallow:显示从不允许的规则;
--all:显示所有的规则;

表达式:

-s 主体类型:显示和指定主体的类型相关的规则(主体是访问的发起者,这个 s 是 source 的意思,也就是源类型);
-t 目标类型:显示和指定目标的类型相关的规则(目标是被访问者,这个 t 是 target 的意思,也就是目标类型);
-b 规则名:显示规则的具体内容(b 是 bool,也就是布尔值的意思,这里是指规则名);

下面举几个例子。首先我们演示一下,如果我们知道的是规则的名称,则应该如何查询具体的规则内容。命令如下:

[root@localhost ~]# seinfo -b | grep http
httpd_manage_ipa
…省略部分输出…
#查询和apache相关的规则,有httpd_manage_ipa规则
[root@localhost ~]# sesearch --all -b httpd_manage_ipa
# httpd_manage_ipa规则中具体定义了哪些规则内容呢?使用sesearch命令查询一下
Found 4 semantic av rules:
allow httpd_t var_run_t:dir { getattr search open } ;
allow httpd_t memcached_var_run_t:file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t memcached_var_run_t:dir { ioctl read write getattr lock add_name remove_name search open } ;
allow httpd_t var_t:dir { getattr search open } ;
Found 20 role allow rules:
allow system_r sysadm_r;
allow sysadm_r system_r;
…省略部分输出…

每个规则中都定义了大量的具体规则内容,这些内容比较复杂,一般不需要修改,会查询即可。

可是我们有时知道的是安全上下文的类型,而不是规则的名称。比如,我们已知 apache 进程的域是 httpd_t,而 /var/www/html/ 目录的类型是 httpd_sys_content_t。而 apache 之所以可以访问 /var/www/html/ 目录,是因为 httpd_t 域和 httpd_sys_content_t 类型匹配。

那么,该如何查询这两个类型匹配的规则呢?命令如下:

[root@localhost ~]# ps auxZ | grep httpd
unconfined_u:system_r:httpd_t:s0 root 25620 0.0 0.5 11188 36X6 ? Ss
03:44 0:03 /usr/sbin/httpd
#apache进程的域是httpd_t
[root@localhost ~]# ls -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
#/var/www/html/ 目录的类型是 httpd_sys_content_t
[root@localhost ~]# sesearch --all -s httpd_t -t httpd_sys_content_t Found 13 semantic av rules:
...省略部分输出...
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open };
allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open };
allow httpd_t httpd_sys_content_t : lnk_file { read getattr };
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open };
...省略部分输出...
#可以清楚地看到httpd_t域是允许访间和使用httpd_sys_content_t类型的

三、SELinux策略规则的开启和关闭

默认情况下,并不是所有的规则都处于开启状态,因此,虽然我们无需修改规则的具体内容,但学习如何开启和关闭规则,还是很有必要的。

规则的开启与关闭并不困难,使用 getsebool 命令来查询规则的开启和关闭状态,使用 setsebool 命令来修改规则的开启与关闭状态。

3.1 查询策略规则是否开启

先来看看如何知道哪些规则是启用的,哪些规则是关闭的。这时需要使用 getsebool 命令,命令格式如下:

[root@localhost ~]# getsebool [-a] [规则名]

-a 选项的含义是列出所有规则的开启状态。

例如:

[root@localhost ~]# getsebool -a
abrt_anon_write --> off
abrt_handle_event --> off
allow_console_login --> on
allow_cvs_read_shadow --> off
allow_daemons_dump_core --> on
allow_daemons_use_tcp_wrapper --> off
…省略部分输出…
#getsebool命令明确地列出了规则的开启状态

除此之外,还可以使用 semanage boolean -l 命令(此命令需事先手动安装),此命令的输出结构同 getsebool 命令相比,输出信息中多了默认状态、当前状态以及相关描述等信息。感兴趣的读者,可以自己尝试运行,观看输出结果。

3.2 修改规则的开启状态

能够查询到规则的开启状态,我们使用 setsebool 命令就可以开启和关闭某个规则。当然,我们先应该通过 sesearch 命令确认这个规则的作用。

sesearch 命令格式如下:

[root@localhost ~]# setsebool [-P] 规则名=[0|1]

-P 选项的含义是将改变写入配置文件,永久生效。规则名有 2 个值,分别是 0 和 1,0 代表将该规则关闭,1 代表将该规则开启。

举个例子:

[root@localhost ~]# getsebool -a | grep httpd
#查询和apache相关的规则
…省略部分输出…
httpd_enable_homedirs --> off
…省略部分输出…
#发现httpd_enable_homedirs规则是开启的,这个规则主要用于允许apache进程访问用户的家目录
#如果不开启这个规则,那么apache的userdir功能将不能使用
[root@localhost ~]# setsebool -P httpd_enable_homedirs=1
#开启httpd_enable_homedirs规则
[root@localhost ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
#查询规则状态是开启
[root@localhost ~]# setsebool -P httpd_enable_homedirs=0
#关闭规则
[root@localhost ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
#查询规则状态是关闭

3.3 SELinux导致vsftpd不能正常登录

举个实际的例子,vsftpd 是 CentOS 默认的文件服务器,这个服务主要是用来进行文件的下载和上传的。不过,如果启动了 SELinux,则会发现 vsftpd 服务是不能登录的。我们来做一个实验,命令如下:

[root@localhost ~]# yum -y install vsftpd
#安装vsftpd服务器端
[root@localhost ~]# yum -y install ftp
#安装ftp命令,也就是ftp客户端
[root@localhost ~]# useradd user
[root@localhost ~]# passwd user
#添加测试用户,并配置密码
[root@localhost ~]# service vsftpd start
#启动vsftpd服务
[root@localhost ~]# ftp 192.168.4.210
#登录本机的ftp
Connected to 192.168.4.210 (192.168.4.210).2.0 (vsFTPd 2.2.2)
Name (192.168.4.210:root):user ←输入用户名
3.1 Please specify the password.
Password: ←输入密码
5.0 OOPS:cannot change directory:/home/user
Login failed.
#登录报错,不能正常登录

这很奇怪,vsftpd 是只要安装并启动就可以正常使用的,不用修改任何配置文件,因为默认配置是非常完善而且正确的。这时我们考虑是 SELinux 引起的问题,可以使用前面章节中关于日志查看的三个命令中的任意一个,来看看是否有关于 vsftpd 的报错。命令如下:

[root@localhost ~]# audit2why < /var/log/audit/audit.log
#分析SELinux的日志
type-AVC msg-audit(1370428985.525:1146) : avc: denied {search } for pid-28408 comm-"vsftpd" name="home" dev=sda3    ino=1046530 scontext=unconfined_u:system_r:ftpd_t:s0-s0:c0.ol023
tcontext=system_u:object_r:home_root_t:s0 tclass=dir
#有关于vsftpd的错.看来确实是SELinux引起的不能登陆 ...省略部分输出...
Was caused by:
One of the following booleans was set incorrectly.
Description:
Allow ftp servers to login to local users and read/write all files on the system, governed by DAC.
Allow access by executing:
# setsebool -P allow_ftpd_full_access 1
Description:
Allow ftp to read and write files in the user home directories
Allow access by executing:
#   setsebool -P ftp_home_dir 1
#建议执行此命令,运行ftp读取和写入用户的家目录

既然给出了建议命令,我们就试试吧:

[root@localhost ~]# setsebool -P ftp_home_dir 1
#开启ftp_home_dir规则
[root@localhost ~]# ftp 192.168.4.210
Connected to 192.168.4.210 (192.168.4.210).2.0 (vsFTPd 2.2.2)
Name (192.168.4.210:root):user ←输入用户名
3.1 Please specify the password.
Password: ←输入密码
2.0 Login successful. ←登录成功

通过这个例子,我们学习了如何通过日志来解决因为规则没有开启而导致的 SELinux 问题。

参考资料

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn