1
分类: LINUX
2006-07-20 10:36:53
一.前言
Security Enhanced Linux(以下简称为SELinux)是RedHat Enterprise Linux 4(以下简称为RHEL4)上新的安全机制,在以往的RHEL系统中从未使用,这使得很多资深的系统管理员已开始使用RHEL4时弄得一头雾水,出现了很多莫名其妙的错误,随后寻找帮助才发现原来是SELinux弄的。由于SELinux有着严格的安全控制和管理权使得系统管理员一时不知如何设定,索性就关闭了,很是可惜。究其原因,是当一个事物出现时,如果他给你带来了麻烦,增加了工作量,便对其产生了厌恶感,这是人之常情。本文暂不探讨SELinux 复杂的内部运作机制,只是先让读者对SELinux有个初步的认识和了解,希望能在您的心里对SELinux留下一个好的印象,并认识到尽管一开始时有些麻烦,但当你熟悉了它以后,系统的管理会变得更轻松。
二.认识DAC与MAC
在介绍SELinux之前,读者需要了解两个基本的系统访问控制机制:
☆ DAC(Discretionary access control,自主访问控制):DAC机制就是指对象(比如程序、文件或进程等)的的拥有者可以任意的修改或授予此对象相应的权限。例如传统Linux,Windows等。
☆ MAC(Mandatory Access Control,强制访问控制):MAC机制是指系统不再允许对象(比如程序、文件或文件夹等)的拥有者随意修改或授予此对象相应的权限,而是透过强制的方式为每个对象统一授予权限,例如SELinux。
图1 DAC与MAC的不同(引自 Security Features in Red Hat Enterprise Linux 4)
三.SELinux的出身
National Security Agency(美国国家安全局,以下简称为NSA)一直非常关注计算机操作系统的安全领域。毕竟他们的工作任务之一就是要确保美国政府使用的计算机的安全,保证在其面临没完没了的攻击时仍能安全可靠的运行。NSA发现大部分操作系统的安全机制,包括Windows和大部分UNIX以及Linux系统,都是以DAC机制为安全认证基础的。由于DAC机制的设计很不利于系统安全,NSA便一直致力于开发出一套好的MAC安全认证机制。
MAC并不是由NSA发明的,它很早就出现了,但由于MAC的诸多问题,使得大型系统提供商对于将MAC集成到自己的系统中始终没有兴趣。即使是那些集成了 MAC 的提供商也通常是将其做为可选件提供,而没有默认安装使用。原因很多,一是因为MAC还不够灵活,二是对于像Windows客户系统这种面向普通用户的系统来说,MAC加大了系统管理和使用的复杂性,得不偿失。于是NSA的为了推广MAC,确立了MAC下一步的研究方向,为使MAC更灵活并且并更容易被嵌入到操作系统。
起初,NSA的MAC系统是在LOCK系统上基于类型增强而且策略灵活的强制访问控制体系,并且随后发展为两个基于Mach的系统:DTMach和DTOS,后来在犹他大学的微内核操作系统Fluke上实现出来,并命名为Flask安全体系。NSA希望有操作系统商能支持其开发的MAC机制,但由于所有的这些工作都是基于实验室,极少可以在实验室之外来进行尝试,以查看这些思想在真实的应用程序的可行性,加之为保密项目,因此很难说服某个系统商采用,谁也不敢头一个吃这个螃蟹。于是,NSA决定选择开源代码的Linux系统为实际市场试验系统。NSA把Flask安全体系集成到Linux操作系统中,SELinux便孕育而生,为了真正配合SELinux在Linux系统上的应用实施,NSA将SELinux作为一个开放源码项目发布出来,从而能获得更加广泛的开发者和用户支持。
毫无意外,使用真正的系统让 NSA 研究人员可以更好的理解SELinux在实际中的应用,而其中体现出的问题是在试验系统中无法找到的。NSA的这一开源措施,在开源界犹如一颗原子弹,业界普遍对此是欢迎的,但也不能说NSA是为此作出了牺牲,因为这是个双赢的举措,因为没有Linux这个试验田,NSA的SELinux很难修得正果。另外选择Linux不是毫无理由的:首先,Linux系统拥有着众多的使用用户,而且很多用户本身具有很高的技术水平;其次,Linux基于开源,这样使得SELinux不属用任何商业组织或公司,防止依此来牟利,也不利于SELinux的发展;最后,对于Linux,它作为新兴的操作系统,在桌面领域很难打败Windows,因此它主要面对服务器领域,而安全就显得至关重要,SELinux正好是它所迫切需要的。RedHat是个很聪明的公司,Fedora是其领导的Linux开源组织。其实说穿了,Fedora就是其企业发行版的实验田。RedHat首先选择了Fedora Core 2作为第一个SELinux实验操作系统,但是预设为不开启,但SELinux在其平台上的表现还是取得了成功。到了Fedora Core3,SELinux已经默认为开启,然后经过修改,我们便在RHEL4上也看到SELinux。
另外需要补充说明的是,读者不要以为仅仅存在SELinux这一个MAC项目,还有很多其他的MAC实现项目,用于其他不同的系统中。
四.SELinux原理
在SELinux中,每个对象(程序、档案、进程等)都拥有一个Security Context(安全上下文),它就像标签一样,贴在每个对象身上,上面记载着这个对象所具有的权限。而我们可以通过制定Security Policy(安全策略)来定义这些Security Context,从而定义哪种对象具有哪些权限。当一个对象需要执行某个动作时,系统会依照Security Policy所制定的内容来检查相对应的权限,如果全部权限都符合的话,系统就会允许这个操作的执行,否则都将遭到拒绝或失败。这些过程不会影响到其它正常运行的对象,系统会保证它们的安全系统结构以及稳定运行。这里还要说明的是,到目前为止,SELinux系统中的某个对象需要执行某个动作的时,系统权限认证不仅仅单独根据Security Policy所制定的内容来检查,同时还要根据传统DAC来检测,只有DAC以及SELinux全部认证通过了才能进行正常操作。
如果读者了解chroot,那么就能很好的理解SELinux。 chroot 就是把某程序置于文件系统下的某一处,而当运行的时候,就不会离开这个文件系统的部份,也就是不会影响整个的文件系统。就好比如果把所有的对象都分配到不同的domain(域)中。而不同的 domain 却彼此独立,而且如果没有经过授权的对象就不可以在domain之间传递数据,也就是说对象不能没有授权就由domain A 跳到 domain B中,情况就如 chroot 一样。
在传统的类Unix中,root拥有着所有权限,有些用户使用采用SELinux的Linux时发现自己就是root,但为何有些事情却不允许执行。其实说穿了就是因为 root 所属的 domain 没有授权可以跳到所需要执行某程序的domain下,也就无法做希望的工作了。
在 SELinux系统启动的时候,会加载一个叫做 policy,* 的安全策略权限文件,这文件内中就定义了相关权限。如果你之前设定了 SELinux 是不能在开机后转回 permissive 模式的话,那你的 root 则可能无法修改当中的设定!也就是说root在SELinux中已经不具有默认的所有权限。那到底这有什么好处呢?其实好处就如 chroot 一样把系统内任何东西都加上一层保护层。那就算是入侵进入了你的计算机,也只能在他破坏他入侵的这个domain环境!
对于RHEL4系统,如何检测是否已经安装了SELinux呢。首先检查你的Linux系统的核心是否有支持ACL的功能。因为Linux系统并不是每一个版本的核心都有支持ACL的功能,而最简单的方法就是检查系统目前的核心能否支持:
# cat /boot/config-
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
注:config-
此时如果能看到上面的几项则表示已经编译到核心中,ext3文件系统已支持ACL功能,这些功能在编译核心选项中也可以找到。
五.传统Linux 与SELinux
传统Linux的安全认证基于内核的DAC机制,这种机制在遇到一个有缺陷或是恶意编写的程序时就会导致很大的问题出现,尤其是对于setuid/setgid这种权限的设计。有些程序员在程序设计时,当需要设置执行权限的时候,为了省事就直接用 setuid root,这样的好处是给予程序最大的用户权限root来运行,避免了因权限引起的问题,大大简化程序的设计,但是这种方式是极其危险的。本文已经提及过,类Unix系统中的root拥有绝对的权限,如果某个有缺陷的程序以root用户运行,可能会破坏系统文件甚至系统核心部分。如果是网络服务程序,其漏洞很容易被黑客利用并发起攻击,造成不可预知的后果。
SELinux的安全认证基于内核外的MAC机制,这种机制使得系统管理员可以定义整个系统的安全策略,这个策略可以基于其他因素,例如用户的角色、程序的可信性及预期使用、程序将要使用的数据的类型等等,来限制对象所具有的权限。当你正确配置了SELinux系统,不正常的应用程序只会影响自己权限内的domain,而对其它domain中的对象没有丝毫影响。其它用户程序的安全性和他们的后台程序仍然可以正常运行,并保持着它们的安全系统结构。例如你某个服务是以 root 的权限执行的。而此服务存在着一个极严重的 bug ,而使得入侵者可以通过这个服务的漏洞进入系统。但如果你的 Linux 系统有SELinux 保护的话,那么入侵者仍没有办法破坏整个系统,因为它被这个服务所属的 domain 所限制。但是没有 SELinux 保护的系统,它就可能因此而入侵整个系统,而产生不可预料的后果。
但是前提是要有好的安全原则,SELinux 最麻烦的就是需要配置一个好的Policy 才可以让 SELinux 发挥效果。制定的太宽松会使 SELinux 毫无用武之地,而太严格又会让使用者连日常工作都变的麻烦至极。NSA让制定安全原则的工作由系统地发行者来做,而像Fedora、Redhat、Novell SUSE 、Debian、Gentoo 等都制定了一套基本的安全原则用于自己的系统。
凭借着SELinux在Linux 上这一个十分重要技术的应用,使其在加强了安全级别,传统的Linux 安全级别一直是 C1 级或 C2 级,和 Windows 服务器的安全级别相同,而 SELinux 把 Linux 的安全级别提升至 B1 级,达到了基本的军事级别。
在RHEL4中,SELinux 与一系列因特网服务加以整合,包括 BIND、Network Time Protocol (NTP)、Apache等,使得其优点能够更轻易地拓展。其要求极度安全环境的组织,可以于更多的应用程序上实作更广泛的SELinux 功能,甚至为
每一服务制定严格的SELinux 原则。。比如,传统的Linux 系统若遭黑客侵入Web Server,可能导致整个系统的瘫痪;但有了SELinux 的保护,我们可以很容易的建立一个只能在特定程序及特定的安全系络中才能执行的 Web 服务器,尽管Web Server被入侵,那么他也只能破坏这个Web Server,无法影响到其它的系统区域,将受害范围减至最少。
六.SELinux在RHEL4上的安装
下面对SELinux在RHEL 4上的安装过程中加以介绍。在安装过程中,会出现如图3 的画面,询问是否启用SELinux,默认安装选项「Active」。
图2 安装时SELinux 的选项
这3个选项的不同之处在于:
□ 已禁用:停用SELinux 功能
□ 警告:仅显示警告讯息
□ 活跃(默认值):启动SELinux 功能
系统是否启用SELinux 的设定,记录在/etc/selinux/config文件中(/etc/sysconfig/selinux为此文件的链接),安装完成后,可检查其中的内容,便可得知系统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
# SELINUXTYPE= type of policy in use. Possible values are:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
SELINUXTYPE=targeted
SELINUX 参数值:有「enforcing、permissive、disabled」分别对应安装时的
选项「活跃、警告、已禁用」。
SELINUXTYPE 参数值:有「targeted、strict」两种
SELINUXTYPE=targeted:保护网络相关服务。
SELINUXTYPE=strict:完整的保护功能,包含网络服务、一般指令及应用程序
注:RHEL 4 目前尚未支持strict policy,只提供targeted policy,如果您强行的将SELINUXTYPE=targeted改为strict,系统启动时将会出现以下的提示而无法启动。
图3 强行修改机制导致无法启动
在/etc/selinux/targeted文件夹中定义的就是targeted属性,它是RHEL 4 巳定义好的policy,这个targeted policy 的用途可为保护下列的网络服务:
dhcpd
httpd
mysqld
named
nscd
ntpd
portmap
postgres
snmpd
squid
syslogd
这样,我们的系统便受到了SELinux的保护,但我们知道,通常安全性越高,表示受到限制加多,管理起来也变得更加不方便。对于我们现在的系统到底有什么样的影响了呢?你可以发现,很多原本root可任意开启的服务,现今因为受到SELinux 控制而无法顺利执行。
在下一章节,笔者会用httpd这个实例来让读者体会启用SELinux 会对系统造成什么影响
另外,还有几个基本的SELinux 指令:
ls -Z
ps -Z
id -Z
这三个命令的-Z(大写)参数专为SELinux而增加的,可以看到文件,进程和用户的SELinux属性情况.
另外一个重要命令:chcon,用于改变文件的SELinux属性!
这里就不详细的介绍这些命令的使用了,有兴趣的读者可以查看相关资料。
七:SELinux 对httpd的保护
1、启用SELinux
若读者安装时关闭了SELinux,可再次启动SELinux,点击应用程序—系统设置—安全级别(gnome),勾选即可,或使用命令system-config-securitylevel(如果安装了系统工具对应项),如图4。其中的强制对应着前边配置文件中的enforcing,亦即安装时的“活跃”,如果不选此项配置文件对应为“permissive”,亦即安装时的“警告”。
图4 当前状态
当然,也可以直接修改/etc/selinux/config文件中的内容,把SELINUX 参数项设成enforcing即可,然后保存重新开机即可。
重启系统时,读者会发现开机时出现奇怪的错误信息,可看到是关于syslogd启动项失败的提示。其实这个信息正是因为启动了SELinux 而产生的,因为targeted policy 有针对syslogd的安全控管,所以才会出现这样的提示。当然如果你启用了其他一些由SELinux控管的服务,亦会出现同样的错误提示。
2、启动httpd
待开机完成后,请用root身份启动httpd daemon
图6 启动httpd失败
出现这样的错误讯息,竟然用root启动httpd 也出现权限问题。读者想
到原因了吗?对,就是SELinux在作怪!SELinux默认启用的环境下,root不再具有所有权限了。下面我们关闭SELinux再试试。
3、停用SELinux,重新启动httpd
可以通过图形界面方式来停用SELinux,位置就在以图形方式启动一样,将启动项勾掉,或修改SELinux设定文件/etc/selinux/config,把SELinux 这个参数设成disable(如图),然后重新开机。
图7 关闭SELINUX
重启后,我们再次尝试启动httpd,这次便没有任何问题了,如图七。这样我们便验证了这个问题是由SELinux导致的。这个问题是很多RHEL4用户遇到的,而往往在论坛中搜到的解决办法就是关闭SELinux,而这里我们要分析一下这里边的原由。
图8 成功启动httpd
4.分析:
我们打开安全级别配置看看,展开修改SELinux策略中的HTTPD Service,我们会看到其中的Disable SELinux protection for httpd daemon没有勾选()如图8。
图9 SELinux策略
我们也可以使用sestatus命令来查看SELinux的状态:
下面对其中的各项加以注解
SELinux status: enabled SELinux启用的状态
SELinuxfs mount: /selinux selinuxfs文件系统挂载点
Current mode: enforcing 目前SELinux的模式
Mode from config file: enforcing 目前SELinux模式的设定文件
Policy version: 18 SELinux Policy 的版本
Policy from config file:targeted SELinux 启用模式的设定文件的名称
Policy booleans: SELinux Policy 的布尔值,active即代表为1;inactive 即代表为0。
allow_ypbind active
dhcpd_disable_trans inactive
httpd_disable_trans inactive
httpd_enable_cgi active
httpd_enable_homedirs active
httpd_ssi_exec active
httpd_tty_comm inactive
httpd_unified active
mysqld_disable_trans inactive
named_disable_trans inactive
named_write_master_zones inactive
nscd_disable_trans inactive
ntpd_disable_trans inactive
portmap_disable_trans inactive
postgresql_disable_trans inactive
snmpd_disable_trans inactive
squid_disable_trans inactive
syslogd_disable_trans inactive
winbind_disable_trans inactive
ypbind_disable_trans inactive
看其中的httpd_disable_trans项,参数为inactive,即对应上面的Disable SELinux protection for httpd daemon项。因此,当我们把这项更改为active后再启动httpd便一切正常了。