看了很多网络上有关于 SELinux 的文章以及到书店去翻了一下有提到 SELinux 的 Linux 书籍。看完了的感觉不是很好,几乎都沒提到什么是 SELinux?SELinux 的运作机制是什么?

大部份提到的解决办法,都是 “停用 SELinux”,这样也只不过是治标而不是治本的方法。

SELinux 的配置

/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - SELinux is fully disabled.
SELINUX=enforcing
# SELINUXTYPE= type of policy in use. Possible values are:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
SELINUXTYPE=targeted

SELinux 的一些相关命令

sestatus

查看 SELinux 是否启用及目前状态的命令,如:

1. SELinux Disabled
$ sestatus
SELinux status:         disabled
2. SELinux Enabled

mode: enforcing

Policy: targeted

$ sestatus
SELinux status:         disabled
SELinux status:         enabled
SELinuxfs mount:        /selinux
Current mode:           enforcing
Mode from config file:  enforcing
Policy version:         18
Policy from config file:targeted
Policy booleans:
...skip...
httpd_builtin_scripting active
httpd_disable_trans     active
httpd_enable_cgi        active
httpd_enable_homedirs   active
httpd_ssi_exec          active
httpd_tty_comm          inactive
httpd_unified           active
...skip...
system-config-securitylevel

图形化工具,除了可以设置防火墙(iptables)外,也可以设置 SELinux

setenforce

在 SELinux 启动为 enforcing 的状态下,可以执行 “setenforce 0“ 来将 SELinux 暂时停用

getsebool and setsebool

/etc/selinux/targeted/booleans 这个文件里放的就是各个 Policy 的布尔值,不过,在 FC5 之后,已经没有这个文件了,你可以用

$ getsebool -a

来查看所有的 booleans 设置状况

或是使用如:

$ setsebool -P httpd_disable_trans 1

来将 httpddisabletrans 停用,这样其实也就等于是停用 SELinux 对 httpd 的保护了

chcon

传统的 chmod 命令是用来设定文件或者目录的权限的,而同样的 chcon 命令则是用来设置 SELinux 对文件或目录的 content 标签的

fixfiles

fixfiles check 命令可以用来检查文件或目录的 SELinux content

fixfiles restore 命令则可以用来修正(还原)文件或目录的 SELinux content

fixfiles relabel 则是会重新修正(还原)所有的文件或目录的 SELinux content

如何在 SELinux 启动为 enforcing 的状态下也让Web Server (httpd) 能正常运作?

前面提到,我们可以将 SELinux 停用(disabled) 或是执行 “setsebool -P httpddisabletrans 1“ 來停用 SELinux 对 httpd 的保护,这样,httpd 就可以跟平常一样运作了

那如果我们要启用 SELinux 且让 httpd 也可以正常运作呢?

示例

举个例子來说:

[root@acer:~] pwd
/root
[root@acer:~] echo "" > index.php
[root@acer:~] mv index.php /var/www/html/
`index.php' -> `/var/www/html/index.php'
[root@acer:~]

在上述命令中,我在 root 的 $HOME 目录下产生了一个 index.php 的文件,内容为显示 phpinfo ,然后再把这个文件移动到 /var/www/html 目录下,再然后开启 browser 来浏览 http://localhost/index.php 这个页面,得到的画面却是:

Forbidden You don't have permission to access /index.php on this server. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.

没错,没有权限,无法读取,我们来看一看到底是怎么回事:

[root@acer:~] ls -Z /var/www/html/index.php
-rw-r--r--  root     root     root:object_r:user_home_t        /var/www/html/index.php
[root@acer:~]
[root@acer:~] ls -Z /var/www/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_script_exec_t cgi-bin/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t error/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t html/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t icons/
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t manual/

因为 index.php 的 content type 为 userhomet 而不是 httpdsyscontent_t 所以无法读取。因此,我们可以执行:

[root@acer:~] chcon -u system_u -t httpd_sys_content_t /var/www/html/index.php
[root@acer:~] ls -Z /var/www/html/index.php
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t /var/www/html/index.php

请再开一次 browser (or reload),现在是不是可以正常读取 index.php 页面了呢?

在看另一个例子:

[root@acer:~] wget http://wordpress.org/latest.tar.gz
--13:36:59--  http://wordpress.org/latest.tar.gz
          => `latest.tar.gz'
Resolving wordpress.org... 72.232.44.122
Connecting to wordpress.org|72.232.44.122|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/octet-stream]
   [                     <=>             ] 505,475       90.49K/s
13:37:07 (90.28 KB/s) - `latest.tar.gz' saved [505475]
[root@acer:~] tar zxf latest.tar.gz
[root@acer:~] mv wordpress /var/www/html/wp
`wordpress' -> `/var/www/html/wp'

浏览 http://localhost/wp/ 的结果一样被拒绝,因为 content 的问题

[root@acer:~] ls -dZ /var/www/html/wp
drwxr-xr-x  1025     1011     root:object_r:user_home_t        /var/www/html/wp/

同样,我们可以用 chone -R 命令来修正 content

[root@acer:~] chcon -R -u system_u -t httpd_sys_content_t /var/www/html/wp/

或是使用 fixfiles restore 命令也可以

[root@acer:~] fixfiles restore /var/www/html/wp/

修正过后的状态:

[root@acer:~] ls -dZ /var/www/html/wp
drwxr-xr-x  apache   apache   system_u:object_r:httpd_sys_content_t /var/www/html/wp/