一、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 对于系统性能有什么样的影响呢?根据 Phoronix 在 2009 年使用 Fedora 11 所做的横向比较来看,开启 SELinux 仅在少数情况下导致系统性能约 5% 的降低。
SELinux 是不是会十分影响一般桌面应用及程序开发呢?原先是,因为 SELinux 的策略主要针对服务器环境。但随着 SELinux 8年来的广泛应用,目前 SELinux 策略在一般桌面及程序开发环境下依然可以同时满足安全性及便利性的要求。以刚刚发布的 Fedora 15 为例,笔者在搭建完整的娱乐(包含多款第三方原生 Linux 游戏及 Wine 游戏)及开发环境(Android SDK + Eclipse)过程中,只有 Wine 程序的首次运行时受到 SELinux 默认策略的阻拦,在图形化的“SELinux 故障排除程序”帮助下,点击一下按钮就解决了。
了解和配置 SELinux
1. 获取当前 SELinux 运行状态
getenforce
可能返回结果有三种:Enforcing、Permissive 和 Disabled。Disabled 代表 SELinux 被禁用,Permissive 代表仅记录安全警告但不阻止可疑行为,Enforcing 代表记录警告且阻止可疑行为。
目前常见发行版中,RHEL 和 Fedora 默认设置为 Enforcing,其余的如 openSUSE 等为 Permissive。
2. 改变 SELinux 运行状态
setenforce [ Enforcing | Permissive | 1 | 0 ]
该命令可以立刻改变 SELinux 运行状态,在 Enforcing 和 Permissive 之间切换,结果保持至关机。一个典型的用途是看看到底是不是 SELinux 导致某个服务或者程序无法运行。若是在 setenforce 0 之后服务或者程序依然无法运行,那么就可以肯定不是 SELinux 导致的。
若是想要永久变更系统 SELinux 运行环境,可以通过更改配置文件 /etc/sysconfig/selinux 实现。注意当从 Disabled 切换到 Permissive 或者 Enforcing 模式后需要重启计算机并为整个文件系统重新创建安全标签(touch /.autorelabel && reboot)。
3. SELinux 运行策略
配置文件 /etc/sysconfig/selinux 还包含了 SELinux 运行策略的信息,通过改变变量 SELINUXTYPE 的值实现,该值有两种可能:targeted 代表仅针对预制的几种网络服务和访问请求使用 SELinux 保护,strict 代表所有网络服务和访问请求都要经过 SELinux。
RHEL 和 Fedora 默认设置为 targeted,包含了对几乎所有常见网络服务的 SELinux 策略配置,已经默认安装并且可以无需修改直接使用。
若是想自己编辑 SELinux 策略,也提供了命令行下的策略编辑器 seedit 以及 Eclipse 下的编辑插件 eclipse-slide 。
4. coreutils 工具的 SELinux 模式
常见的属于 coreutils 的工具如 ps、ls 等等,可以通过增加 Z 选项的方式获知 SELinux 方面的信息。
如
ps auxZ | grep lldpad system_u:system_r:initrc_t:s0 root 1000 8.9 0.0 3040 668 ? Ss 21:01 6:08 /usr/sbin/lldpad -d
如
ls -Z /usr/lib/xulrunner-2/libmozjs.so -rwxr-xr-x. root root system_u:object_r:lib_t:s0 /usr/lib/xulrunner-2/libmozjs.so
以此类推,Z 选项可以应用在几乎全部 coreutils 工具里。
Apache SELinux 配置实例
1. 让 Apache 可以访问位于非默认目录下的网站文件
首先,用 semanage fcontext -l | grep '/var/www' 获知默认 /var/www 目录的 SELinux 上下文:
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
从中可以看到 Apache 只能访问包含 httpdsyscontent_t 标签的文件。
假设希望 Apache 使用 /srv/www 作为网站文件目录,那么就需要给这个目录下的文件增加 httpdsyscontent_t 标签,分两步实现。
首先为 /srv/www 这个目录下的文件添加默认标签类型:semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?' 然后用新的标签类型标注已有文件:restorecon -Rv /srv/www 之后 Apache 就可以使用该目录下的文件构建网站了。
其中 restorecon 在 SELinux 管理中很常见,起到恢复文件默认标签的作用。比如当从用户主目录下将某个文件复制到 Apache 网站目录下时,Apache 默认是无法访问,因为用户主目录的下的文件标签是 userhomet。此时就需要 restorecon 将其恢复为可被 Apache 访问的httpdsyscontent_t 类型:
restorecon reset /srv/www/foo.com/html/file.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
2. 让 Apache 侦听非标准端口
默认情况下 Apache 只侦听 80 和 443 两个端口,若是直接指定其侦听 888 端口的话,会在 service httpd restart 的时候报错:
Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:888 (13)Permission denied: make_sock: could not bind to address 0.0.0.0:888 no listening sockets available, shutting down Unable to open logs
这个时候,若是在桌面环境下 SELinux 故障排除工具应该已经弹出来报错了。若是在终端下,可以通过查看 /var/log/messages 日志然后用sealert -l 加编号的方式查看,或者直接使用 sealert -b 浏览。无论哪种方式,内容和以下会比较类似:
SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 888. ***** Plugin bind_ports (92.2 confidence) suggests ************************* If you want to allow /usr/sbin/httpd to bind to network port 888 Then you need to modify the port type. Do # semanage port -a -t PORT_TYPE -p tcp 888 `where PORT_TYPE is one of the following: ntop_port_t, http_cache_port_t, http_port_t.` ***** Plugin catchall_boolean (7.83 confidence) suggests ******************* If you want to allow system to run with NIS Then you must tell SELinux about this by enabling the 'allow_ypbind' boolean. Do setsebool -P allow_ypbind 1 ***** Plugin catchall (1.41 confidence) suggests *************************** If you believe that httpd should be allowed name_bind access on the port 888 tcp_socket by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # grep httpd /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp
可以看出 SELinux 根据三种不同情况分别给出了对应的解决方法。在这里,第一种情况是我们想要的,于是按照其建议输入:
semanage port -a -t http_port_t -p tcp 888
之后再次启动 Apache 服务就不会有问题了。
这里又可以见到 semanage 这个 SELinux 管理配置工具。它第一个选项代表要更改的类型,然后紧跟所要进行操作。详细内容参考 Man 手册
3. 允许 Apache 访问创建私人网站
若是希望用户可以通过在 ~/public_html/ 放置文件的方式创建自己的个人网站的话,那么需要在 Apache 策略中允许该操作执行。使用:
setsebool httpd_enable_homedirs 1
setsebool 是用来切换由布尔值控制的 SELinux 策略的,当前布尔值策略的状态可以通过 getsebool 来获知。
默认情况下 setsebool 的设置只保留到下一次重启之前,若是想永久生效的话,需要添加 -P 参数,比如:
setsebool -P httpd_enable_homedirs 1
总结
希望通过这一个简短的教程,扫除您对 SELinux 的误解甚至恐惧,个人感觉它并不比 iptables 策略复杂。如果希望您的服务器能有效抵挡 0-day ***时,那么 SELinux 或许就是一个值得考虑的缓和方案。
原文:http://linuxtoy.org/archives/selinux-introduction.html
二、Linux内核安全
虽然SELinux已在Linux内核中存在了近十年,但至今仍有很多管理员由于担心其配置的复杂性而弃之不用。虽然许多Linux管理员在他们的Linux服务器中禁用SELinux来避免在安装应用程序时对它进行配置,但在Linux安全性方面SELinux是一个非常有用的工具。下面让我们了解一下它的工作原理,用SELinux策略和访问控制的管理方式来保护你的Linux服务器吧。
在Linux操作系统中,SELinux实现了强制访问控制(MAC)的安全模式。在标准的Linux环境中开启了*访问控制(DAC)后,这一机制就会在Linux内核中对所有操作的安全性进行检查。
理解DAC和MAC的Linux安全模型
由于SELinux以MAC为基础,所以了解DAC(默认的Linux安全模型)的不足以及MAC相对于DAC的优势就变得非常重要。
在MAC模式下,管理员控制了系统中软件的所有交互行为。采用了最小特权方式后,默认情况下应用程序和用户没有任何权限,因为作为系统安全策略的一部分,所有的权限都必须由管理员授予。在DAC模式下,文件所有权在用户,且该用户对它们有完全的控制权限。***们***用户帐户后,便可以对该用户拥有的文件做任何事情。例如,******FTP服务器后将完全控制FTP服务器帐户拥有的所有文件。更糟的是,如果一个应用程序在根帐号下(常见的如Web和FTP服务)运行时,***者将完全控制整个操作系统。
MAC模式为每一个应用程序都提供了一个虚拟“沙漏”,只允许应用程序执行它设计需要且在安全策略中明确允许的任务。例如,Web服务器可能只能够读取网站发布的文件,并监听在指定网络的端口。即使***者将其攻破,他们也无法执行在安全策略中没有明确允许的任何活动,即使这个进程在根用户下运行。
标准Unix权限仍然会在系统中存在。当文件被访问时,标准Unix权限将先于SELinux安全策略生效。如果标准权限拒绝访问,访问直接被拒绝,SELinux在整个过程中没有参与。但是,如果标准权限允许访问,SELinux此时将参与进来并根据其源进程和目标对象的安全上下文来判断允许还是拒绝访问。
SELinux中主体和客体的定义
在MAC的安全上下文中有两个重要概念,主体和客体。MAC(或非*访问控制)框架允许你规定所有进程(称为主体)与系统其它部分如文件、设备、套接字、端口以及其它进程(称为客体)进行交互的权限。它通过对所有进程和对象定义安全策略来实现。这些进程和对象都由内核控制,安全的决定基于所有可用的信息,而不仅仅是用户的身份。在此模型中,一个进程可被授予的权限只是它需要且能发挥作用的权限。这遵循了最小权限原则,不同于DAC完全权限的概念。
举例来说,在MAC模式下,用户通常是将自己的数据存放在主目录中来保护自己的数据,但是使用chmod命令修改文件的权限将会暴露自己的数据,这时受管制的进程如果没有权限无法接触这些文件或试图修改相应的策略。
SELinux安全策略:严格和定向
SELinux遵循最小特权模式。默认情况下,所有的行为都遭到拒绝,然后我们会针对系统的每个单元(服务、程序、用户、进程)单独增加策略以允许它们执行特定的功能。如果一个服务,程序或用户试图访问或修改一个不是它们所必须的的文件或资源,访问就会被拒绝且系统会将其记录到日志中。因为SELinux在内核中运行,每个应用程序并不需要针对它进行特别的修改。如果SELinux阻止了某个操作,应用程序只是会收到一个普通的“拒绝访问”的报错。
下图描述的是SELinux默认定向策略的的工作流程:
策略是SELinux最重要的概念之一。最小特权模式就很能说明“严格”策略。SELinux可以允许很多不同的策略,在CentOS5和RHEL中默认的策略是“定向”,它主要针对的范围是关键的系统进程。在RHEL中,有超过200个这样的客体存在(包括httpd,named,dhcpd,mysqld)。除此之外,系统中其它的进程都在一个非限制域中运行,不受SELinux影响。定向策略的目标是让每一个启动时就默认安装和运行的进程都在限制域中运行。“定向”策略目的是在不严重影响终端用户体验的情况下尽可能保护最多的重要进程,大多数用户甚至完全感觉不到SELinux在运行。
另一个重要的概念是SELinux的访问控制。访问控制有三种类型,它们是类型加强(TE)的访问控制、基于角色的访问控制(RBAC)和多级安全(MLS)访问控制。在定向策略中TE是首要的访问控制机制。
建立SELinux的安全上下文
对于理解SELinux很重要的一点是:在SELinux模型中所有的进程和文件都有一个SELinux的安全上下文。可以简单的使用“-Z”参数来显示其安全上下文,如下所示:
大部分SELinux报错都是围绕着客体的安全上下文进行的。这些安全上下文格式为:
用户:角色:类型:多级安全(MLS)。最后一个字段“多级安全”始终隐藏(这在定向策略中是默认的)。举个例子,如上图所示,对于文件hello.pl,用户是root,角色是object_r,类型是httpd_sys_content_t。在定向策略中,最重要的字段是类型,主要是用它来实现TE的访问控制。
类似地,你可以在Linux中使用命令“ps -Z”来列出所有正运行进程的安全上下文,例如:
#ps -efZ | grep mail
system_u:system_r:sendmail_t root 2661 1 0
12:30 ? 00:00:00 sendmail: accepting connections
system_u:system_r:sendmail_t smmsp 2670 1 0
12:30 ? 00:00:00 sendmail: Queue [email protected]:00:00 for /var/spool/clientmqueue
上面的输出显示我的Linux服务器中的sendmail进程运行的类型是“Sendmail_t”。
三、SELinux教程:命令与管理
当你考虑在服务器上使用SELinux时,了解一些基本命令和管理工具会有所帮助。本文是三本SELinux教程的一部分,在这里,我们将提供一些命令来帮助你确保Linux服务器的安全。
除了这些新的SELinux命令,一些内置的Linux命令,如cp、mv、ls和ps,都随着SELinux的启动变成使用–Z标记。标识符命令也被修改来显示连同用户默认安全属性的用户安全环境。
SELinux配置决窍
除了Linux服务器上文件和单独流程的安全环境,SELinux还有更多安全功能。在这篇文章中涵盖所有SELinux功能和基本的安全模式几乎是不可能的,但这里我会强调关键的那些。
端口管理:你可以通过SELinux管理对系统端口的访问。默认情况下,SELinux允许应用访问默认端口(如ssh可访问端口22),不过一旦禁用SELinux,你也可以重新配置任一应用来访问任一非默认端口。
为了得到SELinux管理端口的完整清单,你可以使用以下命令:
#/home/root>semanage port –l 将ssh的访问端口从22改成24 #/home/root> semanage port –a –t ssh_port_t –p tcp 24
然后重启ssh相关的服务。
用户管理:有了SELinux严格用户管理功能的帮助,你可以让你的服务器“确实难以攻破”。它们可以在任一SELinux政策中担任重要角色。但在目标政策中(默认的SELinux政策),每个域运行一个单一角色且TE用来从其它流程中分离出受限的流程。
因此,在目标SELinux政策中,流程和对象问题以system_u的形式出现,而所有的默认Linux用户是user_u,就像下面显示的:
但在严格政策中,一些系统帐户可以运行在普通的、无特权的user_u身份下,而其它帐户可以在政策数据库中有直接身份。
自定义政策模块(Customized Policy Modules):有时候我们在在建立SELinux时面对的情况是政策和布尔运算条件可能不足。在这种情况下,我们可以利用audit2allow命令来定义我们的自定义SELinux政策。举例来说,如果否定错误登入到所有ftp相关服务的审计日志中,我们可以用以下句子来形成我们的自定义SELinux政策模块:
#/home/root> # grep ftpd_t /var/log/audit/audit.log | audit2allow -M ftplocal
这个自定义ftp相关政策模块之后可以如下方式下载到现有的SELinux目标政策:
#/home/root> semodule –i ftplocal
由于SELinux缺乏文档编制和技巧,很多管理员都忽略了它。但是有默认目标政策的SELinux模式对很多管理员来说都是一个安全的起始点。如果你准备测试它,我建议先运行几天,观察所有错误和警告的日志,如果没有错误,切换到执行模式。
如果你正运行一些特定的数据库或应用(如MySql或Oracle),也要注意,在服务器上执行SELinux政策之前,你应该为SELinux相关指令查看特定版本的文档编制。
原文链接:http://www.searchsv.com.cn/showcontent_45458.htm
四、SELinux配置
本文的主题是RHEL 5上的SELinux配置。RHEL同时提供了图形用户界面(GUI)和命令行两种方式配置SELinux。为了表现SELinux的简单易用,本文使用RHEL的GUI来启用SELinux。
要从RHEL的GUI启用SELinux,依次点击系统(system)>管理(Administration)>安全级别和防火墙(Security Level and Firewall)。进入SELinux选项卡,将SELinux设置为“允许模式(permissive mode)”,然后重启服务器。
以允许模式启动SELinux是(学习配置使用SELinux的)不错的实践。在这种模式下,你可以近距离感受和接触SELinux,但不影响服务器和应用程序/数据库中的任何东西。测试期间,你必须仔细查看日志信息,检查所有的警告以及所有由程序和数据库在操作期间产生的拒绝错误。
设置SELinux为允许模式并重启我的RHEL后,我没有发现任何不同。我以根账户登入系统,然后使用sestatus命令查看SELinux环境的运行状况。
既然SELinux已经启动并在允许模式下运行,那么是时候对SELinux进行管理了。RHEL提供了一个GUI来进行SELinux的策略管理,根用户可以使用system-config-SELinux命令对这个GUI进行初始化。该命令将打开GUI的主界面,在RHEL或Fedora Linux中你都可以看到如下的窗口:
上图中,你可以在左边框中找到SELinux管理的主要选项。第二个选项“Boolean”包含了SELinux管理中大部分默认服务和进程的布尔条件。同样的条件也可以使用getsebool命令列出。举个例子,如果你只想知道已有的关于ftpd守护进程的布尔条件,那么你可以使用如下的命令:
要改变布尔条件,如allow_ftpd_use_cifs=off——该条件意味着FTP进程不能使用cifs协议进行公共文件传输——我们可以在system-config-SELinux界面中单击“Boolean”选项卡下对应的条件(条目),如下图所示。此项操作将允许FTP服务使用cifs协议进行公共文件传输。你可以针对ftpd进程执行getsebool和grep命令,确认刚才的操作是否生效。
使用SELinux的安全上下文保护Web服务器
假设我们想要在Linux服务器上运行Apache Web服务器程序,由于这台服务器会运行一些关键应用,并暴露在互联网上,所以我们想确保这台Web服务器受到尽可能多的保护。
如果你启动Web服务并尝试配置你的Web服务器允许执行某些CGI脚本,如hello.pl,那么如果不改变SELinux的配置,Linux系统日志和SELinux审计日志都会记录到错误。要在SELinux审计日志中查看这些错误,执行sealert –b。这会打开SELinux审计日志,如下所示:
现在的问题是,为什么会出现这种情况?答案很简单,因为hello.pl是一个CGI可执行程序,它应该被归为httpd_sys_script_exec_tdomain上下文,而不是httpd_sys_content_t。
我们可以使用chcon命令解决这个问题:
[email protected] cgi-bin]# ls -lZ *.pl -rwxr-xr-x apache apache root:object_r:httpd_sys_content_t hello.pl [[email protected] cgi-bin]# chcon -v --type=httpd_sys_script_exec_t hello.pl context of hello.pl changed to root:object_r:httpd_sys_script_exec_t[[email protected] [email protected] cgi-bin] # ls -lZ *.pl -rwxr-xr-x apache apache root:object_r:httpd_sys_script_exec_t hello.pl
现在我们应该能够看到,我们的Web服务器执行了hello.pl,而且在SELinux日志中也没有产生任何警告或者错误。
以这种方式配置SELinux,***者很难通过使用未授权的CGI或perl脚本来获得系统的控制。同样地,任何想要更改文件根目录到系统其他用户的子目录的行为都会失败,除非该子目录及子目录下的索引文件已被添加到httpd域。
那么,让我们来假设,我们的Linux服务器上的用户John创建了名为html的子目录。完成该目录和index.html文件的创建后,你会发现,该目录和文件被默认归入user_home_t上下文,如下所示:
直到且除非该上下文被修改为正确的httpd上下文域,否则任何试图通过Web服务器访问这个index.html的操作都会被SELinux拒绝,并在审计日志当中留下错误记录。你可以使用chcon命令(如下图)或者semanage命令来改变上下文。
原文链接:http://www.searchsv.com.cn/showcontent_45356.htm
转载于:https://blog.51cto.com/57388/1554836