SELinux 故障的排除

虽然SELinux十分难用,经常是出了问题找半天找不到原因,后来一看/var/log/message才发现是SELinux的Policy阻止了。相比于网上说的遇到问题直接就setenforce 0将SELinux设置成Passive模式,或者说直接Disable掉SELinux,找到问题所在才是更可取的做法。毕竟SELinux虽然设计得反人类,但是出发点却是为了更加安全。对于一些常见的应用场景,完全可以将其启用以增强安全性。

对于桌面用户,安装好Fedora等发行版之后,SELinux默认开启,以日常使用场景来看,完全可以忽略SELinux的存在

注意,本文不是对SELinux的全面介绍,只是想记录一下如何快速排除SELinux故障的一些方法。

SELinux简介

Linux中的核心概念是文件,同时由一个个进程或者程序执行特定命令。进程或程序时时刻刻需要和文件进行交互。这样就产生了一个问题,一个进程(程序)是否应该访问一个文件,或者说,这个进程(程序)有没有访问某个文件的权限。在没有SELinux的时候,由简单的用户、用户组的rwx来限制,但是越来越复杂的安全环境使得只用rwx限制权限变得十分脆弱。而且有些情形下,单靠用户很难满足复杂的权限要求。

SELinux的设计理念是最小权限原则。在完全没有Policy的情况下,SELinux认为所有操作都是可疑的从而拒绝该操作。所以SELinux相当于是一个白名单制度。系统维护了一张巨大的白名单,对于常见的应用场景设定了一些规则。对于特定的进程和程序,只能访问有相应标记的文件。

说了这么多,还没有提到故障解决。但是理解这些概念对于SELinux的运行机制应该会有所帮助。

以下的操作请确保自己对SELinux有一定的了解

SELinux故障排除

在默认安装的CentOS和Fedora下,自带的SELinux相关的命令只有几个,比如chcongetenforcesetenforce等。这也是SELinux坑的地方,遇到相关故障需要排除还必须额外安装软件包。SELinux故障排除需要的软件包名字为setoolssetroubleshoot。对于RHEL系列操作系统可以通过dnf install setools setroubleshoot(Fedora)或者yum install setools setroubleshoot(CentOS)进行安装。

SELinux的错误信息会被重定向到/var/log/messages,同时/var/log/audit/audit.log中也存有SELinux的日志。查看日志是定位问题的最有效途径。

通过

sealert -a /var/log/audit/audit.log > /path/to/mylogfile.txt

可以输出可读性较高的日志。

内置布尔值

有部分SELinux故障可以通过修改内置的布尔值来修复。semanage boolean -l可以列出当前系统可用的布尔值。利用grep选出和你服务相关的条目。例如,在部署vsftpd的时候,就会遇到虚拟用户不能上传文件的问题,那么我们执行

semanage boolean -l | grep ftp

输出如下

ftp_home_dir (on , on) Allow ftp to home dir
ftpd_use_cifs (off , off) Allow ftpd to use cifs
sftpd_full_access (off , off) Allow sftpd to full access
ftpd_use_nfs (off , off) Allow ftpd to use nfs
sftpd_enable_homedirs (off , off) Allow sftpd to enable homedirs
tftp_anon_write (off , off) Allow tftp to anon write
ftpd_use_passive_mode (off , off) Allow ftpd to use passive mode
httpd_enable_ftp_server (off , off) Allow httpd to enable ftp server
sftpd_write_ssh_home (off , off) Allow sftpd to write ssh home
ftpd_full_access (on , on) Allow ftpd to full access
sftpd_anon_write (off , off) Allow sftpd to anon write
ftpd_use_fusefs (off , off) Allow ftpd to use fusefs
ftpd_connect_all_unreserved (off , off) Allow ftpd to connect all unreserved
ftpd_connect_db (off , off) Allow ftpd to connect db
ftpd_anon_write (off , off) Allow ftpd to anon write
tftp_home_dir (off , off) Allow tftp to home dir
httpd_can_connect_ftp (off , off) Allow httpd to can connect ftp

此处列出了输出信息。可以看到和ftp相关的布尔值,以及相关解释,可以很容易理解。对于vsftpd,要让用户可以有完全访问权限(具体权限还要看vsftp的相关配置),这里相关的是ftpd_full_access,执行下面的命令设置布尔值

setsebool -P ftpd_full_access on

也可以用

setsebool -P ftpd_full_access=1

自定义规则

有的时候,SELinux自带的布尔值并没有我们想要的服务,或者有特殊的业务需求,那么仅仅靠改布尔值来控制显然不现实。这时候就可以通过SELinux的自定义规则来白名单化我们的需求。

比如,以http服务器nginx访问符号链接为例,如果需要如此,可以首先将SELinux的模式调整为Passive

setenforce 0

等待一段时间,让系统捕获相应的SELinux日志。使用下面的命令,分析日志导出策略

grep nginx /var/log/audit/audit.log | audit2allow -m nginx_symlink > nginx_symlink.te

audit2allow是通过分析日志中的拒绝信息来创建规则的工具。其中-m参数指定要输出策略的详细内容,nginx_symlink为策略名称。

接着cat nginx_symlink.te,确认策略中是否是自己需要放行的策略,在本例中,可以看到文件中有如下的信息。

allow httpd_t file_t:lnk_file { read getattr };

确认无误后,执行

grep nginx /var/log/audit/audit.log | audit2allow -M nginx_symlink

即改用-M选项生成可导入的策略文件。

最后执行

semodule -i nginx_symlink.pp

会将策略添加到/etc/selinux/targeted/modules/active/modules/下面。通过semodule -l可以检查已装载的策略模块。

最后再设置SELinux为Enforcing

setenforce 1

结语

本文简单地介绍了一下如何快速排除SELinux的故障,并没有更加深入地去介绍相关命令的使用方法。也没有对文件、进程的安全性脉络进行讲解。本文主要参考了CentOS Wiki上的相关条目。更多关于SELinux的信息以及更详细的设置请参阅参考资料。

参考资料

https://wiki.centos.org/zh/HowTos/SELinux

https://wiki.centos.org/zh/TipsAndTricks/SelinuxBooleans

《鸟哥的Linux私房菜》http://linux.vbird.org/linux_basic/0440processcontrol.php

audit2allow Man Page https://fedoraproject.org/wiki/SELinux/audit2allow

另请参阅

https://fedoraproject.org/wiki/SELinux

https://wiki.archlinux.org/index.php/SELinux

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注