虽然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相关的命令只有几个,比如chcon
、getenforce
、setenforce
等。这也是SELinux坑的地方,遇到相关故障需要排除还必须额外安装软件包。SELinux故障排除需要的软件包名字为setools
、setroubleshoot
。对于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