标题：SELinux
简介
SELinux 是 2.6 版本的 Linux 内核中提供的强制访问控制(MAC）系统。对于目前可用的 Linux安全模块来说，SELinux 是功能最全面，而且测试最充分的，它是在 20 年的 MAC 研究基础上建立的。SELinux 在类型强制服务器中合并了多级安全性或一种可选的多类策略，并采用了基于角色的访问控制概念。[1]
大部分使用 SELinux 的人使用的都是 SELinux 就绪的发行版，例如 Fedora、Red Hat Enterprise Linux (RHEL）、Debian或 Centos。它们都是在内核中启用 SELinux 的，并且提供一个可定制的安全策略，还提供很多用户层的库和工具，它们都可以使用 SELinux 的功能。
SELinux是一种基于 域-类型 模型（domain-type）的强制访问控制（MAC）安全系统，它由NSA编写并设计成内核模块包含到内核中，相应的某些安全相关的应用也被打了SELinux的补丁，最后还有一个相应的安全策略。
众所周知，标准的UNⅨ安全模型是"任意的访问控制"DAC。就是说，任何程序对其资源享有完全的控制权。假设某个程序打算把含有潜在重要信息的文件扔到/tmp目录下，那么在DAC情况下没人能阻止他！
而MAC情况下的安全策略完全控制着对所有资源的访问。这是MAC和DAC本质的区别。
SELinux提供了比传统的UNⅨ权限更好的访问控制。
发展历程
SELinux是「Security-Enhanced Linux」的简称，是美国国家安全局「NSA=The National Security Agency」 和SCC（Secure Computing Corporation）开发的 Linux的一个扩张强制访问控制安全模块。原先是在Fluke上开发的，2000年以 GNU GPL 发布。
现在以Linux作为因特网服务器是越来越普遍的事了。在我这几年作过的项目里，WEB的开发基本都是基于Linux的，这里有给大公司做的，也给政府部门做的，当然更多的是中小企业做的。这其中给政府做的，我们把SELinux作为一个卖点，接受了不少项目。
现在不论是政府还是民间企业，大家对信息安全问题是越来越关心了，因为企业的业务平台的服务器上存储着大量的商务机密，个人资料，个人资料它直接关系到个人的隐私问题。特别是我们政府的网站，作为信息公开的平台，它的安全就更显得重要了。这些连到互联网的服务器，不可避免的要受到来自世界各地的各种威胁。最坏的时候我们的服务器被入侵，主页文件被替换，机密文件被盗走。除了来自外部的威胁外，内部人员的不法访问，攻击也是不可忽视的。对于这些攻击或者说是威胁，当然有很多的办法，有防火墙，入侵检测系统，打补丁等等。因为Linux也和其他的商用UNⅨ一样，不断有各类的安全漏洞被发现。我们对付这些漏洞不得不花很多的人力来堵住它。在这些手段之中，提高OS系统自身的牢固性就显得非常的重要。
控制切换
从fedora core 2开始， 2.6内核的版本都支持selinux.我们看看 Fedora core 5 里的/etc/sysconfig/selinux标准设定吧。
# 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
#SELINUX=disabled
# SELINUXTYPE= type of policy in use. Possible values are:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
SELINUXTYPE=targeted
SELINUX有「disabled」「permissive」，「enforcing」3种选择。
Disabled就不用说了，permissive就是Selinux有效，但是即使你违反了策略的话它让你继续操作，但是把你的违反的内容记录下来。在我们开发策略的时候非常的有用。
相当于Debug模式。
Enforcing就是你违反了策略，你就无法继续操作下去。
SELINUXTYPE呢，现在主要有2大类，一类就是红帽子开发的targeted，它只是对于，主要的网络服务进行保护，比如 apache,sendmail,bind,postgresql等，不属于那些domain的就都让他们在unconfined_t里，可导入性高，可用性好但是不能对整体进行保护。
另一类是Strict，是NAS开发的，能对整个系统进行保护，但是设定复杂，我认为虽然它复杂，但是一些基本的会了，还是可以玩得动的。
我们除了在/etc/sysconfig/selinux设它有效无效外，在启动的时候，也可以通过传递参数selinux给内核来控制它。（Fedora 5默认是有效）
kernel /boot/vmlinuz-2.6.15-1.2054_FC5 ro root=LABEL=/ rhgb quiet selinux=0
上面的变更可以让它无效。
[root@python sysconfig]# /usr/sbin/getenforce
Enforcing
确认有效后重新对文件系统赋予标签：
[root@python sysconfig]# /sbin/fixfiles relabel
或者
[root@python /]# touch /.autorelabel
然后 reboot，你就在secure的Linux环境下工作了。
基本操作
SELinux是个经过安全强化的Linux操作系统，实际上，基本上原来的运用软件没有必要修改就能在它上面运行。真正做了特别修改的RPM包只要50 多个。像文件系统EXT3都是经过了扩展。对于一些原有的命令也进行了扩展，另外还增加了一些新的命令，接下来我们就来看看这些命令。文件操作1）ls命令
在命令后加个 －Z 或者加 –context
[root@python azureus]# ls -Z
-rwxr-xr-x fu fu user_u:object_r:user_home_t azureus
-rw-r--r-- fu fu user_u:object_r:user_home_t Azureus2.jar
-rw-r--r-- fu fu user_u:object_r:user_home_t Azureus.png
2）chcon
更改文件的标签
[root@python tmp]# ls --context test.txt
-rw-r--r-- root root root:object_r:staff_tmp_t test.txt
[root@python tmp]# chcon -t etc_t test.txt
[root@python tmp]# ls -lZ test.txt
-rw-r--r-- root root root:object_r:etc_t test.txt
3）restorecon
当这个文件在策略里有定义是，可以恢复原来的 文件标签。
4）setfiles
跟chcon一样可以更改一部分文件的标签，不需要对整个文件系统重新设定标签。
5）fixfiles
一般是对整个文件系统的， 后面一般跟 relabel，对整个系统 relabel后，一般我们都重新启动。如果，在根目录下有.autorelabel空文件的话，每次重新启动时都调用 fixfiles relabel
6）star
就是tar在SELinux下的互换命令，能把文件的标签也一起备份起来。
7）cp
可以跟 -Z,--context=CONTEXT 在拷贝的时候指定目的地文件的security context
8）find
可以跟 –context 查特定的type的文件。
例子：
find /home/fu/ --context fu:fu_r:amule_t -exec ls -Z {} \:
9）run_init
在sysadm_t里手动启动一些如Apache之类的程序，也可以让它正常进行，domain迁移。进程domain的确认程序现在在那个domain里运行，我们可以在ps 命令后加 －Z
[root@python /]# ps -eZ
LABEL PID TTY TIME CMD
system_u:system_r:init_t 1 00:00:00 init
system_u:system_r:kernel_t 2 00:00:00 ksoftirqd/0
system_u:system_r:kernel_t 3 00:00:00 watchdog/0ROLE的确认和变更命令id能用来确认自己的 security context
[root@python ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:staff_r:staff_t
这里，虽然是ROOT用户，但也只是在一般的ROLE和staff_t里运行，如果在enforcing模式下，这时的ROOT对于系统管理工作来说，是什么也干不了。
[root@python ~]# newrole -r sysadm_r
Authenticating root.
口令：
[root@python ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) context=root:sysadm_r:sysadm_t模式切换1）getenforce
得到当前的SELINUX值
[root@python bin]# getenforce
Permissive
2）setenforce
更改当前的SELINUX值 ，后面可以跟 enforcing,permissive 或者 1,0。
[root@python bin]# setenforce permissive
3）sestatus
显示当前的 SELinux的信息
[root@python bin]# sestatus -v
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 20
Policy from config file: refpolicy
Process contexts:
Current context: user_u:user_r:user_t
Init context: system_u:system_r:init_t
/sbin/mingetty system_u:system_r:getty_t
/usr/sbin/sshd system_u:system_r:sshd_t
File contexts:
Controlling term: user_u:object_r:user_devpts_t
/etc/passwd system_u:object_r:etc_t
/etc/shadow system_u:object_r:shadow_t
/bin/bash system_u:object_r:shell_exec_t
/bin/login system_u:object_r:login_exec_t
/bin/sh system_u:object_r:bin_t -> system_u:object_r:shell_exec_t
/sbin/agetty system_u:object_r:getty_exec_t
/sbin/init system_u:object_r:init_exec_t
/sbin/mingetty system_u:object_r:getty_exec_t其他重要命令1）Audit2allow
很重要的一个以python写的命令，主要用来处理日志，把日志中的违反策略的动作的记录，转换成 access vector，对开发安全策略非常有用。在refpolicy里，它的功能比以前有了很大的扩展。
[root@python log]# cat dmesg | audit2allow -m local > local.te
2）checkmodule -m -o local.mod local.te
编译模块
[root@python log]# checkmodule -m -o local.mod local.te
checkmodule: loading policy configuration from local.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 5） to local.mod
3）semodule_package
创建新的模块
[root@python log]# semodule_package -o local.pp -m local.mod
4）semodule
可以显示，加载，删除 模块
加载的例子：
[root@python log]# semodule -i local.pp
5）semanage
这是一个功能强大的策略管理工具，有了它即使没有策略的源代码，也是可以管理安全策略的。因为我主要是介绍用源代码来修改策略的，详细用法大家可以参考它的man页。
定制策略
FC4,RHEL4等都是采用策略1.X版本的，并且是提供策略源代码的RPM包。从FC5开始策略的版本从1.X 升级到2.X。2.X版本的refpolicy(reference policy）最大的一个变化就是引进模块（module）这个概念，同一套策略源代码就可以支持Multi-LevelSecurity（MLS）和non-MLS。
标准的FC5里不提供源代码的RPM包。FC5提供的audit2allow,semanage,semodule也是可以开发一些简单的策略模块的。但是，要是作策略模块的开发，增加一个ROLE之类的，最好还是下载refpolicy的源代码。
⒌1策略源文件的安装
从CVS服务器下载的源代码是最新的，如果遇到象make的时候出错，那么最好就是把你系统里和SELinux有关的那些包更新到最新的状态。
安装好了的源代码目录结构如下图所示：
每一个模块有3个文件构成，比如上图的sudo.fc 就是和 命令sudo相关的文件的定义标签，（file context rabel），sudo.te是Type Enforcement定义，包括TE访问规则等，sudo.if是一个外部模块调用这个模块的接口定义。
[root@python src]# cd /etc/selinux/refpolicy/src/policy
[root@python policy]# cp build.conf build.
[root@python policy]# vi build.conf
[root@python policy]# diff build.conf build.
32c32
< DISTRO = redhat
---
> #DISTRO = redhat
43c43
< MONOLITHIC=n
---
> MONOLITHIC=y
[root@python src]# make conf
[root@python src]# make
这样，在/etc/selinux/refpolicy/src/policy下生成很多的以pp为后缀的文件，这些就是SELinux模块。接下来我们修改/etc/sysconfig/selinux，设成SELINUXTYPE=refpolicy，然后reboot.
启动后，确认策略的适用情况， 现在的版本是20。
[fu@python ~]$ /usr/sbin/sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 20
Policy from config file: refpolicy
⒌2给程序定制domain
开发程序策略的一般步骤
⒈给文件，端口之类的object赋予type 标签
⒉设置 Type Enforcement (Domain 迁移，访问许可）
⒊策略加载
⒋permissive模式下运行程序
⒌确认日志，用audit2allow生成访问许可
⒍重复1，2，3，4，5动作，直到没有违反的日志出现
⒎切换到enforcing模式，正式运用
因为我们所常用的那些服务的策略模块都已经有了，修改的时候也比较简单。在这里我就举个一般的例子。用点对点下载的朋友估计都跟我一样，在Linux上用 azureus，Amule来下载东西吧。
接下来以azureus为例，介召如何在FC5里追加一个azureus.pp模块。我们在追加azureus.pp模块之前，azureus是在系统给用户设好的user_t domain里运行。
[fu@python azureus]$ ps -efZ|grep azureus
user_u:user_r:user_t fu 1751 1732 0 22:28 pts/3 00:00:00 /bin/bash ./azureus
接下来我们在追加3个文件。
1）azureus.fc
在这里我只定义一个文件，实际要是真的用的，还要定义azureus_t能写的目录等。
[root@python apps]# more azureus.fc
/home/fu/azureus -- gen_context(user_u:object_r:azureus_exec_t,s0)
2）azureus.te
[root@python apps]# more azureus.te
policy_module(azureus,1.0.0)
type azureus_t;
type azureus_exec_t;
role user_r types azureus_t;
require {
type user_t;
};
domain_type(azureus_t)
domain_entry_file(azureus_t,azureus_exec_t)
domain_auto_trans(user_t,azureus_exec_t,azureus_t)
3）azureus.if
实际上没有别的模块要调用azureus，所以这个文件就是空文件也不要紧。
[root@python apps]# more azureus.if
# policy/modules/apps/azureus.if
## Myapp example policy
##
## Execute a domain transition to run azureus.
##
##
缺点
虽然Linux比起 Windows来说，它的可靠性，稳定定要好得多，但是他也是和其他的UNIX 一样，有以下这些不足之处。
存在特权用户root
任何人只要得到root的权限，对于整个系统都可以为所欲为。这一点Windows也一样。
对于文件的访问权的划分不够细
在linux系统里，对于文件的操作，只有「所有者」，「所有组」，「其他」这3类的划分。
对于「其他」这一类里的用户再细细的划分的话就没有办法了。
SUID程序的权限升级
如果设置了SUID权限的程序有了漏洞的话，很容易被攻击者所利用。
DAC(Discretionary Access Control）问题
文件目录的所有者可以对文件进行所有的操作，这给系统整体的管理带来不便。
对于以上这些的不足，防火墙，入侵检测系统都是无能为力的。
在这种背景下，对于访问权限大幅强化的OS SELinux来说，它的魅力的无穷的。
优点
SELinux系统比起通常的Linux系统来，安全性能要高的多，它通过对于用户，进程权限的最小化，即使受到攻击，进程或者用户权限被夺去，也不会对整个系统造成重大影响。
接下来我来介绍SELinux的一些特点。
对访问的控制彻底化
特点1：MAC(Mandatory Access Control）―――对访问的控制彻底化
对于所有的文件，目录，端口这类的资源的访问，都可以是基于策略设定的，这些策略是由管理员定制的、一般用户是没有权限更改的。
对于进程只赋予最小的权限
特点2：TE （Type Enforcement）――― 对于进程只赋予最小的权限
Te概念在 SELinux里非常的重要。它的特点是对所有的文件都赋予一个叫type的文件类型标签，对于所有的进程也赋予各自的一个叫 domain的 标签。Domain标签能够执行的操作也是由access vector在策略里定好的。
我们熟悉的apache服务器，httpd进程只能在httpd_t 里运行，这个httpd_t 的domain能执行的操作，比如能读网页内容文件赋予httpd_sys_content_t，密码文件赋予shadow_t,TCP的80端口赋予 http_port_t等等。如果在access vector里我们不允许 http_t来对http_port_t进行操作的话，Apache启动都启动不了。反过来说，我们只允许80端口，只允许读取被标为 httpd_sys_content_t的文件，httpd_t就不能用别的端口，也不能更改那些被标为httpd_sys_content_t的文件（read only）。
防止权限升级
特点3：domain迁移 ―― 防止权限升级
在用户环境里运行点对点下载软件azureus，你当前的domain是fu_t，但是，你考虑到安全问题，你打算让他在azureus_t里运行，你要是在terminal里用命令启动azureus的话，它的进程的domain就会默认继承你实行的shell的fu_t。
有了domain迁移的话，我们就可以让azureus在我们指定的azureus_t里运行，在安全上面，这种做法更可取，它不会影响到你的fu_t。
下面是domain迁移指示的例子：
domain_auto_trans(fu_t,azureus_exec_t,azureus_t)
意思就是，当在 fu_t domain里，实行了 被标为 azureus_exec_t的文件时，domain 从fu_t迁移到 azureus_t。下面是Apache启动的迁移图。注意了，因为从哪一个domain能迁移到httpd_t是在策略里定好了，所以要是我们手动 (/etc/init.d/httpd start）启动apache的话，可能仍然留在sysadm_t里，这样就不能完成正确的迁移。要用run_init命令来手动启动。
对于用户只赋予最小的权限
特点4：RBAC（role base access control) ――――― 对于用户只赋予最小的权限
对于用户来说，被划分成一些ROLE，即使是ROOT用户，你要是不在sysadm_r里，也还是不能实行sysadm_t管理操作的。因为，那些ROLE可以执行那些domain也是在策略里设定的。ROLE也是可以迁移的，但是也只能按策略规定的迁移。