10.3 SELinux安全子系统

selinux

SELinux(Security-Enhanced Linux)是美国国家安全局在Linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL 7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。

例如,您在自己的电脑上下载了一个美图软件,当您全神贯注地使用它给照片进行美颜的时候,它却在后台默默监听着浏览器中输入的密码信息,而这显然不应该是它应做的事情(哪怕是访问电脑中的图片资源,都情有可原)。SELinux安全子系统就是为了杜绝此类情况而设计的,它能够从多方面监控违法行为:对服务程序的功能进行限制(SELinux域限制可以确保服务程序做不了出格的事情);对文件资源的访问限制(SELinux安全上下文确保文件资源只能被其所属的服务程序进行访问)。

刘遄老师经常会把“SELinux域”和“SELinux安全上下文”称为是Linux系统中的双保险,系统内的服务程序只能规规矩矩地拿到自己所应该获取的资源,这样即便黑客入侵了系统,也无法利用系统内的服务程序进行越权操作。但是,非常可惜的是,SELinux服务比较复杂,配置难度也很大,加之很多运维人员对这项技术理解不深,从而导致很多服务器在部署好Linux系统后直接将SELinux禁用了;这绝对不是明智的选择。

SELinux服务有三种配置模式,具体如下。

enforcing:强制启用安全策略模式,将拦截服务的不合法请求。

permissive:遇到服务越权访问时,只发出警告而不强制拦截。

disabled:对于越权的行为不警告也不拦截。

本书中的所有实验都是在强制启用安全策略模式下进行的,虽然在禁用SELinux服务后确实能够减少报错几率,但这在生产环境中相当不推荐。建议大家检查一下自己的系统,查看SELinux服务主配置文件中定义的默认状态。如果是permissive或disabled,建议赶紧修改为enforcing。

  1. [root@linuxprobe ~]# vim /etc/selinux/config
  2. # This file controls the state of SELinux on the system.
  3. # SELINUX= can take one of these three values:
  4. # enforcing - SELinux security policy is enforced.
  5. # permissive - SELinux prints warnings instead of enforcing.
  6. # disabled - No SELinux policy is loaded.
  7. SELINUX=enforcing
  8. # SELINUXTYPE= can take one of these two values:
  9. # targeted - Targeted processes are protected,
  10. # minimum - Modification of targeted policy. Only selected processes are protected.
  11. # mls - Multi Level Security protection.
  12. SELINUXTYPE=targeted

SELinux服务的主配置文件中,定义的是SELinux的默认运行状态,可以将其理解为系统重启后的状态,因此它不会在更改后立即生效。可以使用getenforce命令获得当前SELinux服务的运行模式:

  1. [root@linuxprobe ~]# getenforce
  2. Enforcing

为了确认图10-6所示的结果确实是因为SELinux而导致的,可以用setenforce [0|1]命令修改SELinux当前的运行模式(0为禁用,1为启用)。注意,这种修改只是临时的,在系统重启后就会失效:

  1. [root@linuxprobe ~]# setenforce 0
  2. [root@linuxprobe ~]# getenforce
  3. Permissive

再次刷新网页,就会看到正常的网页内容了,如图10-7所示。可见,问题确实是出在了SELinux服务上面。

  1. [root@linuxprobe wwwroot]# firefox

10.3 SELinux安全子系统 - 图2

图10-7 页面内容按照预期显示

现在,我们来回忆一下前面的操作中到底是哪里出问题了呢?

httpd服务程序的功能是允许用户访问网站内容,因此SELinux肯定会默认放行用户对网站的请求操作。但是,我们将网站数据的默认保存目录修改为了/home/wwwroot,而这就产生问题了。在6.1小节中讲到,/home目录是用来存放普通用户的家目录数据的,而现在,httpd提供的网站服务却要去获取普通用户家目录中的数据了,这显然违反了SELinux的监管原则。

现在,我们把SELinux服务恢复到强制启用安全策略模式,然后分别查看原始网站数据的保存目录与当前网站数据的保存目录是否拥有不同的SELinux安全上下文值:

  1. [root@linuxprobe ~]# setenforce 1
  2. [root@linuxprobe ~]# ls -Zd /var/www/html
  3. drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html
  4. [root@linuxprobe ~]# ls -Zd /home/wwwroot
  5. drwxrwxrwx. root root unconfined_u:object_r:home_root_t:s0 /home/wwwroot

在文件上设置的SELinux安全上下文是由用户段、角色段以及类型段等多个信息项共同组成的。其中,用户段system_u代表系统进程的身份,角色段object_r代表文件目录的角色,类型段httpd_sys_content_t代表网站服务的系统文件。由于SELinux服务实在太过复杂,现在大家只需要简单熟悉SELinux服务的作用就可以,刘遄老师未来会在本书的进阶篇中单独拿出一个章节仔细讲解SELinux服务。

针对当前这种情况,我们只需要使用semanage命令,将当前网站目录/home/wwwroot的SELinux安全上下文修改为跟原始网站目录的一样就可以了。

semanage命令

semanage命令用于管理SELinux的策略,格式为“semanage [选项] [文件]”。

SELinux服务极大地提升了Linux系统的安全性,将用户权限牢牢地锁在笼子里。semanage命令不仅能够像传统chcon命令那样—设置文件、目录的策略,还可以管理网络端口、消息接口(这些新特性将在本章后文中涵盖)。使用semanage命令时,经常用到的几个参数及其功能如下所示:

-l参数用于查询;

-a参数用于添加;

-m参数用于修改;

-d参数用于删除。

例如,可以向新的网站数据目录中新添加一条SELinux安全上下文,让这个目录以及里面的所有文件能够被httpd服务程序所访问到:

  1. [root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
  2. [root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/*

注意,执行上述设置之后,还无法立即访问网站,还需要使用restorecon命令将设置好的SELinux安全上下文立即生效。在使用restorecon命令时,可以加上-Rv参数对指定的目录进行递归操作,以及显示SELinux安全上下文的修改过程。最后,再次刷新页面,就可以正常看到网页内容了,结果如图10-8所示。

  1. [root@linuxprobe ~]# restorecon -Rv /home/wwwroot/
  2. restorecon reset /home/wwwroot context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
  3. restorecon reset /home/wwwroot/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
  4. [root@linuxprobe ~]# firefox

Apache配置成功的页面

图10-8 正常看到网页内容

真可谓是一波三折!原本认为只要把httpd服务程序配置妥当就可以大功告成,结果却反复受到了SELinux安全上下文的限制。所以,建议大家在配置httpd服务程序时,一定要细心、耐心。一旦成功配妥httpd服务程序之后,就会发现SELinux服务并没有那么难。

因为在RHCSA、RHCE或RHCA考试中,都需要先重启您的机器然后再执行判分脚本。因此,建议读者在日常工作中要养成将所需服务添加到开机启动项中的习惯,比如这里就需要添加systemctl enable httpd命令。