几乎可以肯定每个人都听说过 SELinux (更准确的说,尝试关闭过),甚至某些过往的经验让您对 SELinux 产生了偏见。不过随着日益增长的  0-day 安全漏洞,或许现在是时候去了解下这个在 Linux 内核中强制性访问控制系统(MAC)了,在刚接触Linux的时候我们会遇到因为SELinux控制出现的问题,接下来我来初步揭开SELinux的神秘面纱:

        

SELinux 与强制访问控制系统
        SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access  Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。
        强制访问控制系统的用途在于增强系统抵御 0-Day ***(利用尚未公开的漏洞实现的***行为)的能力。所以它不是网络防火墙或 ACL  的替代品,在用途上也不重复。
举例来说,系统上的 Apache 被发现存在一个漏洞,使得某远程用户可以访问系统上的敏感文件(比如 /etc/passwd   来获得系统已存在用户),而修复该安全漏洞的 Apache 更新补丁尚未释出。
此时SELinux 可以起到弥补该漏洞的缓和方案。因为 /etc/passwd  不具有 Apache 的访问标签,所以 Apache 对于 /etc/passwd 的访问会被 SELinux 阻止。


相比其他强制性访问控制系统,SELinux 有如下优势:
        ●控制策略是可查询而非程序不可见的。
        
        ●可以热更改策略而无需重启或者停止服务。
        
        ●可以从进程初始化、继承和程序执行三个方面通过策略进行控制。
        
        ●控制范围覆盖文件系统、目录、文件、文件启动描述符、端口、消息接口和网络接口。


了解和配置 SELinux
1. 获取当前 SELinux 运行级别状态

[root@iptablesRouter ~]# getenforce 
Permissive

返回级别结果有三种:

            Enforcing - SELinux security policy is enforced.

            #Linux系统下selinux所设置的安全策略都会被启用,记录警告并且阻止可疑行为。

            Permissive - SELinux prints warnings instead of enforcing.

            #Linux系统下selinux所设置的安全策略都会被启动,但是只记录安全警告但不阻止可疑行为。

            Disabled - No SELinux policy is loaded.

            #禁用selinux,所有selinux策略将会禁用。

2.更改SELinux运行级别状态

[root@iptablesRouter ~]# setenforce [ Enforcing | Permissive | 1 | 0 ]

可以通过setenforce对selinux运行级别状态在Enforcing和Permissive之间进行切换无需重新启动操作系统即可生效。

如果需要让selinux永久变更运行级别状态,需要修改/etc/selinux/config配置文件,例如将selinux运行级别状态永久变更为Disable,则需要在/etc/selinux/config配置文件中"SELINUX=Permissive"改为"SELINUX=Disabled" 注意当从 Disabled  切换到 Permissive 或者 Enforcing 模式后需要重启操作系统。

3.SELinux 运行策略
配置文件 /etc/sysconfig/selinux 还包含了 SELinux 运行策略的信息,通过改变变量 SELINUXTYPE 的值实现,该值有两种可能:targeted 代表仅针对预制的几种网络服务和访问请求使用 SELinux 保护,strict 代表所有网络服务和访问请求都要经过 SELinux。

4.查看selinux相关信息

常见工具有"ps" "ls" 增加 Z 选项的方式获知 SELinux 方面的信息

例如1:

[root@iptablesRouter ~]# ls -Z /etc/issue
-rw-r--r--. root root system_u:object_r:etc_runtime_t:s0 /etc/issue

例如2:

[root@iptablesRouter ~]# ps auxZ | grep cron
system_u:system_r:crond_t:s0-s0:c0.c1023 root 1495 0.4  0.2 117296 1352 ?      Ss   16:52   0:01 crond


下面我们通过两个实例来理解selinux的安全机制:

案例1:允许vsftpd的匿名用户上传

1.首先安装vsftp服务并启动服务

[root@iptablesRouter ~]# yum -y install vsftpd
[root@iptablesRouter ~]# service vsftpd start
Starting vsftpd for vsftpd:                                [  OK  ]

2.创建FTP共享目录为"/var/ftp/ftpuser",进入该目录中创建一些文件,以便测试,并且设置selinux模式为Permissive模式。

[root@iptablesRouter ~]# mkdir /var/ftp/ftpuser
[root@iptablesRouter ~]# chmod 755 /var/ftp/ftpuser
[root@iptablesRouter ~]# chown ftp /var/ftp/ftpuser
[root@iptablesRouter ~]# touch /var/ftp/ftpuser/{1..5}.txt
[root@iptablesRouter ~]# ll /var/ftp/ftpuser/
total 0
-rw-r--r--. 1 root root 0 Apr 19 17:10 1.txt
-rw-r--r--. 1 root root 0 Apr 19 17:10 2.txt
-rw-r--r--. 1 root root 0 Apr 19 17:10 3.txt
-rw-r--r--. 1 root root 0 Apr 19 17:10 4.txt
-rw-r--r--. 1 root root 0 Apr 19 17:10 5.txt
[root@iptablesRouter ~]# getenforce 
Permissive

3.在客户机windows上通过ftp://172.16.100.7/ftpuser/ 访问,即可访问到/var/ftp/ftpuser下的所有文件,测试是否可以匿名上传文件:

wKiom1cWzmiwKYHFAALrBaRjuyQ729.jpg

匿名上传文件成功。

4.设置selinux运行级别状态为Enforcing:

[root@iptablesRouter ~]# setenforce 1
[root@iptablesRouter ~]# getenforce 
Enforcing

5.我们再次通过客户端匿名上传文件:

wKioL1cW0Cbyi3MIAANGNQcAMps139.jpg

现在可以说明是selinux策略生效了,可以通过#getsebool -a | grep ftp查看ftpd的selinux访问策略

[root@iptablesRouter ftpuser]# getsebool -a | grep ftp
allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
ftp_home_dir --> off
ftpd_connect_db --> off
ftpd_use_fusefs --> off
ftpd_use_passive_mode --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
tftp_use_cifs --> off
tftp_use_nfs --> off

通过setsebool -p  开ftp selinux策略:

[root@iptablesRouter ftpuser]# setsebool -P ftp_home_dir 1
[root@iptablesRouter ftpuser]# setsebool -P allow_ftpd_anon_write 1
[root@iptablesRouter ftpuser]# setsebool -P allow_ftpd_full_access 1

wKioL1cW1DXRvrErAAJbtcCY8FM256.jpg

再次匿名上传就可以实现了:

wKiom1cW1CejENtkAAHzKCNeuiY269.jpg

案例二: selinux为Enforcing状态,把httpd的DocumentRoot改为/web/htdocs:

[root@iptablesRouter ~]# rpm -qa httpd
httpd-2.2.15-29.el6.centos.x86_64
[root@iptablesRouter ~]# getenforce 
Enforcing
[root@iptablesRouter ~]# mkdir -pv /web/htdocs
[root@iptablesRouter ~]# vim /etc/httpd/conf/httpd.conf
修改配置文件为下:
DocumentRoot "/web/htdocs"
<Directory "/web/htdocs">
[root@iptablesRouter ~]# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]
建立主页文件index.html
[root@iptablesRouter ~]# vim /web/htdocs/index.html
<h1>Welcome to OpenSamlee</h1>

测试访问主页:

wKioL1cW2C-j80iRAAGOVS5A368216.jpg

我们将selinux模式改为"Permissive",再测试访问:

[root@iptablesRouter httpd]# getenforce 
Permissive

wKioL1cW2K_gSeQ8AAE9IFnNe5w474.jpg

设置selinux级别为permissive模式,可以访问

设置selinux模式为Enforcing模式,却不能访问了,这是受到了了selinux的context值的影响.

wKiom1cW2YqTgUDEAAJng0FlWk8886.jpg

可以通过ls –Z 可以查看文件的context值如下.默认情况下在任何一个目录创建文档会继承上级目录的context值, 可以看出来index.html的context值继承的是/root目录的context值,而在/var/www/html/目录下创建文件默认的context值为httpd_sys_content。


可以通过 chcon –t命令修改/web/htdocs的context值

[root@iptablesRouter ~]# chcon -R --reference=/var/www/html/ /web/htdocs/
[root@iptablesRouter ~]# ls -ldZ /web/htdocs/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /web/htdocs/

修改完成之后,即可实现访问

wKioL1cW29OD-NeyAAGbV6ELD3I111.jpg

如果需要恢复默认context值,可使用restorecon命令:

[root@iptablesRouter ~]# restorecon -R /web/htdocs/

The end!!!