现在的位置: 首页 > 综合 > 正文

安全增强 Linux (SELinux) 剖析

2013年05月25日 ⁄ 综合 ⁄ 共 2903字 ⁄ 字号 评论关闭

简介Linux一直被认为是最安全的操作系统之一,但是通过引入安全增强Linux(Security Enhanced Linux, SELinux),National Security Agency(NSA)将Linux的安全性提升到了新的高度。SELinux通过对内核和用户空间进行修改,对现有的GNU/Linux操作系统进行了扩展,从而使其变得坚不可摧。基于2.6版本的内核都实现了SELinux。

       公共网络(比如Internet)充满着危险。只要将电脑连接到Internet,你就能感受到这一点。攻击者可以利用不安全性来获得对一个系统的访问,获得对信息的未授权访问,或者对一台电脑进行改造,以利用它发送垃圾邮件或攻击其它高端系统(使用SYN泛洪攻击,一种分布式拒绝服务攻击)。

       分布式拒绝服务攻击(DDoS)通过Internet上的多个系统来实现(所以也称为僵尸电脑),这些电脑消耗目标系统上的资源,(利用TCP的三向握手)使其不能被合法的用户访问。一种带有Cookie的四向握手协议(Stream Control Transmission Protocol[SCTP])可以防御这种攻击。

       GNU/Linux非常安全,但它也非常动态:所做的更改会为操作系统带来漏洞,这些漏洞可能被攻击者利用,尽管人们都非常关心阻止未授权的访问,但是发生入侵后会发生什么呢?

       本文将探究SELinux背后的思想及其基本架构,本文只关注基本原理,使您了解SELinux的重要性及其实现过程。

访问控制方法

大多数操作系统使用访问控制来判断一个实体(用户或程序)是否能够访问给定资源。基于UNIX的系统使用一种自主访问控(discretio

nary access control, DAC)的形式。此方法通常根据对象所属的分组来限制对象的访问。例如,GNU/Linux中的文件有一个所有者、一个分组和一个权限集。权限定义谁可以访问给定文件、谁可以读取它、谁可以向其写入,以及谁可以执行它。这些权限被划分到三个用户集中,分别表示用户(文件所有者)、分组(一个用户组的所有成员)和其它(既不是所有者,又不是该分组的成员的所有用户)。

很多这样的访问控制都会带来一个问题,因为所利用的程序能够继承用户的访问控制。这样,该程序就可以在用户的访问控制层进行操作。与通过这种方式定义约束相比,使用最小特权原则更安全:程序只能执行完成任务所需的操作。例如,如果一个程序用于相应socket请求,但不需要访问文件系统,那么该程序应该能够监听给定的socket,但是不能访问文件系统。通过这种方式,如果该程序被攻击者利用,其访问权限显然是最小的。这种控制类型称为强制访问控制(MAC)。

另一种控制访问的方法是基于角色的访问控制(RBAC)。在RBAC中,权限是根据安全系统所授予的角色来提供的。角色的概念与传统的分组概念不同,因为一个分组代表一个或多个用户。一个角色可以代表多个用户,但它也代表一个用户集可以执行的权限。

SELinux将MAC和RABC都添加到了GNU/Linux操作系统中。下一节将讨论SELinux实现,以及如何将安全增强透明地添加到Linux内核中。

Linux安全实现

在早期的SELinux中,它还是一个补丁集,它提供了自己的安全性框架。这存在着一些问题,因为它将GNU/Linux限制到一个单独的访问控制框架。Linux内核继承了一种通用框架,将策略从实现中分离了出来,而不是采用单一的方法。该解决方案就是Linux安全模块(Linux Security Module,LSM)框架。LSM提供了一种通用的安全框架,允许将安全模型实现为可载入内核模块(参见图1)。


图 1. SELinux 将安全策略和实现分离


在访问内部对象之前对内核代码进行修改,以调用一个代表实施函数的钩子,该实施函数实现安全策略。该函数根据预定义的策略验证操作能否继续进行。安全函数存储在一个安全操作结构中,该结构包含必须受到保护的基本操作。例如,security_socket_creat

e钩子(security_ops->socket_create)在创建新socket之前检查权限,并考虑协议集、类型、协议,以及socket是在内核中创建还是在用户空间中创建。清单1提供了socket.c中用于创建socket的示例代码(参见./linux/net/socket.c)。


清单1. 创建socket的内核代码


security_socket_create函数在./linux/include/linux/security.h中定义。它提供了从security_socket_create到security_ops结构中动态安装的函数的间接调用(参见清单2)。

清单2. 用于socket创建检查的间接调用


security_ops结构中的函数通过安全模块安装。在本例中,这些钩子在可载入的SELinux内核模块中定义。每个SELinux调用在hooks文件内部定义,该文件实现从内核函数到特定安全模块的动态调用的间接性(参见清单3中的.../linux/security/selinux/hooks.c代码)。


清单3. SELinux socket创建检查


清单3的核心部分是一个调用,用于验证当前操作是否是当前任务(通过current->security定义,其中current代表当前正在执行的任务)所允许的。访问向量缓存(Access Vector Cache,AVC)缓存之前的SELinux决策(提高进程的性能)。此调用包括源安全标识符(sid)、安全类(根据请求操作的详细信息构造)、特定socket调用,以及可选的辅助审计数据。如果围在缓存中找到决策,那么会调用安全服务器来获取决策(此过程如图2所示)。


图2. 分层Linux安全进程


初始化到security_ops中的回调钩子被动态定义为一个可载入内核模块(通过register_security()),但是没有载入安全模块时,这些钩子包含伪桩(dummy stud)函数(参见./linux/security/dummy.c)。这些桩函数实现标准Linux DAC策略。始终存在回调钩子,其中必须提供对象中介(mediation)来保证安全性。这包括任务管理(创建、通知、等待)、模块载入(execve)、文件系统管理(超级块、inode、文件钩子)、IPC(消息队列、共享内存、信号量(semaphore)操作)、模块钩子(插入和删除)、网络钩子(覆盖socket、netlink、网络设备和其它协议接口)。

结束语

对于Linux内核来说,强制访问控制和基于角色的访问控制都是相对较新的功能。随着LSM框架的引入,新的安全模块将会出现。除了对框架的增强,还可以堆叠安全模块,从而允许多个模块共存,而且最大限度覆盖了Linux的安全需求。随着对操作系统安全性的深入研究,还会引入新的访问控制方法。



本文摘自:http://www.ibm.com/developerworks/cn/linux/l-selinux/

抱歉!评论已关闭.