说起SELinux,多数Linux发行版缺省都激活了它,可见它对系统安全的重要性,可惜由于它本身有一定的复杂性,如果不熟悉的话往往会产生一些看似莫名其妙的问题,导致人们常常放弃使用它,为了不因噎废食,学学如何解决SELinux问题是很有必要的。
我们以CentOS环境为例重现一个非常常见的SELinux问题:
首先需要确认SELinux处于激活状态,可以使用getenforce或sestatus命令:
- shell> getenforce
- Enforcing
- shell> sestatus
- SELinux status: enabled
- SELinuxfs mount: /selinux
- Current mode: enforcing
- Mode from config file: enforcing
- Policy version: 24
- Policy from config file: targeted
注:关于SELinux的基础知识介绍请参考鸟哥的Linux私房菜中相关的介绍。
我们还需要确认系统已经安装并启动了Apache,没有的话就YUM装一个,这很简单,就不多说了,接着在root目录创建一个测试文件test.html,如下:
- shell> cat /root/test.html
- hello, world.
然后把这个测试文件拷贝到Apache的DocumentRoot目录,我的Apache是通过YUM安装的话,缺省是/var/www/html目录,如下:
- shell> cp /root/test.html /var/www/html
接着浏览一下,如果没出什么幺蛾子,应该一切都在意料之中,如下:
- shell> curl http://localhost/test.html
- hello, world.
看到这,你可能觉得我废话连篇,别着急,下面就是见证奇迹的时候了:
同样还是那个测试文件test.html,不过这次不再是拷贝,而是移动,如下:
- shell> mv /root/test.html /var/www/html
接着浏览一下,怎么样,结果很出人意料吧,竟然提示权限错误,如下:
- shell> curl http://localhost/test.html
- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
- <html><head>
- <title>403 Forbidden</title>
- </head><body>
- <h1>Forbidden</h1>
- <p>You don't have permission to access /test.html
- on this server.</p>
- </body></html>
当然,我们现在知道这个问题是由于SELinux引起的,但还不知其所以然,实际上问题的原因此时已经被audit进程记录到了相应的日志里,可以这样查看:
- shell> audit2why < /var/log/audit/audit.log
如果看不懂的话,推荐安装setroubleshoot套件:
- shell> yum install setroubleshoot
它本身是一个GUI套件,不过其中包含的一个sealert命令对我们命令行用户很有用:
- shell> sealert -a /var/log/audit/audit.log
- Summary:
- SELinux is preventing /usr/sbin/httpd "getattr" access to
- /var/www/html/test.html.
- Detailed Description:
- SELinux denied access requested by httpd. /var/www/html/test.html may be a
- mislabeled. /var/www/html/test.html default SELinux type is httpd_sys_content_t,
- but its current type is admin_home_t. Changing this file back to the default
- type, may fix your problem.
- File contexts can be assigned to a file in the following ways.
- * Files created in a directory receive the file context of the parent
- directory by default.
- * The SELinux policy might override the default label inherited from the
- parent directory by specifying a process running in context A which creates
- a file in a directory labeled B will instead create the file with label C.
- An example of this would be the dhcp client running with the dhclient_t type
- and creating a file in the directory /etc. This file would normally receive
- the etc_t type due to parental inheritance but instead the file is labeled
- with the net_conf_t type because the SELinux policy specifies this.
- * Users can change the file context on a file using tools such as chcon, or
- restorecon.
- This file could have been mislabeled either by user error, or if an normally
- confined application was run under the wrong domain.
- However, this might also indicate a bug in SELinux because the file should not
- have been labeled with this type.
- If you believe this is a bug, please file a bug report against this package.
- Allowing Access:
- You can restore the default system context to this file by executing the
- restorecon command. restorecon '/var/www/html/test.html', if this file is a
- directory, you can recursively restore using restorecon -R
- '/var/www/html/test.html'.
- Fix Command:
- /sbin/restorecon '/var/www/html/test.html'
这次应该看懂了吧!原因是说Apache下文件上下文类型应该是httpd_sys_content_t,但是现在是admin_home_t,所以权限错误,并且在结尾处给出了修复命令。
可httpd_sys_content_t,admin_home_t都怎么看啊?很简单,借助ls命令的-Z参数即可:
- shell> ls -Z /path
回到问题的开始,拷贝之所以没出现问题,是因为cp自动修改上下文属性,而移动之所以出现问题是因为mv保留原文件的上下文属性。
注:关于SELinux和Apache的详细介绍,可以参考『man httpd_selinux』。
知道了如何解决SELinux问题,以后如果遇到类似的情况不要急着武断的关闭SELinux。