近年来Linux系统因为其出色的性能和稳定性,开放源代码特性带来的灵活性和可扩展性,以及较低廉的成本,而受到计算机工业界的普遍关注和应用。但在安全性方面,Linux内核只提供了经典的UNIX自主访问控制(root用户,用户ID,模式位安全机制),以及部分的支持了POSIX.1e标准草案中的capabilities安全机制,这对于Linux系统的安全性是不足够的,影响了Linux系统的进一步发展和更普遍的应用。html
有不少安全访问控制模型和框架已经被研究和开发出来,用以加强Linux系统的安全性,比较知名的有安全加强Linux(SELinux),域和类型加强(DTE),以及Linux入侵检测系统(LIDS)等等。可是因为没有一个系统可以得到统治性的地位而进入Linux内核成为标准;而且这些系统都大多以各类不一样的内核补丁的形式提供,使用这些系统须要有编译和定制内核的能力,对于没有内核开发经验的普通用户,得到并使用这些系统是有难度的。在2001年的Linux内核峰会上,美国国家安全局(NSA)介绍了他们关于安全加强Linux(SELinux)的工做,这是一个灵活的访问控制体系Flask在Linux中的实现,当时Linux内核的创始人Linus Torvalds赞成Linux内核确实须要一个通用的安全访问控制框架,但他指出最好是经过可加载内核模块的方法,这样能够支持现存的各类不一样的安全访问控制系统。所以,Linux安全模块(LSM)应运而生。node
Linux安全模块(LSM)是Linux内核的一个轻量级通用访问控制框架。它使得各类不一样的安全访问控制模型可以以Linux可加载内核模块的形式实现出来,用户能够根据其需求选择适合的安全模块加载到Linux内核中,从而大大提升了Linux安全访问控制机制的灵活性和易用性。目前已经有不少著名的加强访问控制系统移植到Linux安全模块(LSM)上实现,包括POSIX.1e capabilities,安全加强Linux(SELinux),域和类型加强(DTE),以及Linux入侵检测系统(LIDS)等等。虽然目前Linux安全模块(LSM)仍然是做为一个Linux内核补丁的形式提供,可是其同时提供Linux 2.4稳定版本的系列和Linux 2.5开发版本的系列,而且颇有但愿进入Linux 2.6稳定版本,进而实现其目标:被Linux内核接受成为Linux内核安全机制的标准,在各个Linux发行版中提供给用户使用。linux
回页首安全
Linux安全模块(LSM)的设计必须尽可能知足两方面人的要求:让不须要它的人尽量少的所以获得麻烦;同时让须要它的人所以获得有用和高效的功能。网络
以Linus Torvalds为表明的内核开发人员对Linux安全模块(LSM)提出了三点要求:数据结构
另外一方面,各类不一样的Linux安全加强系统对Linux安全模块(LSM)提出的要求是:可以容许他们以可加载内核模块的形式从新实现其安全功能,而且不会在安全性方面带来明显的损失,也不会带来额外的系统开销。框架
为了知足这些设计目标,Linux安全模块(LSM)采用了经过在内核源代码中放置钩子的方法,来仲裁对内核内部对象进行的访问,这些对象有:任务,inode结点,打开的文件等等。用户进程执行系统调用,首先游历Linux内核原有的逻辑找到并分配资源,进行错误检查,并通过经典的UNIX自主访问控制,刚好就在Linux内核试图对内部对象进行访问以前,一个Linux安全模块(LSM)的钩子对安全模块所必须提供的函数进行一个调用,从而对安全模块提出这样的问题"是否容许访问执行?",安全模块根据其安全策略进行决策,做出回答:容许,或者拒绝进而返回一个错误。socket
另外一方面,为了知足大多数现存Linux安全加强系统的须要,Linux安全模块(LSM)采起了简化设计的决策。Linux安全模块(LSM)如今主要支持大多数现存安全加强系统的核心功能:访问控制;而对一些安全加强系统要求的其余安全功能,好比安全审计,只提供了的少许的支持。Linux安全模块(LSM)如今主要支持"限制型"的访问控制决策:当Linux内核给予访问权限时,Linux安全模块(LSM)可能会拒绝,而当Linux内核拒绝访问时,就直接跳过Linux安全模块(LSM);而对于相反的"容许型"的访问控制决策只提供了少许的支持。对于模块功能合成,Linux安全模块(LSM)容许模块堆栈,可是把主要的工做留给了模块自身:由第一个加载的模块进行模块功能合成的最终决策。全部这些设计决策可能暂时影响了Linux安全模块(LSM)的功能和灵活性,可是大大下降了Linux安全模块(LSM)实现的复杂性,减小了对Linux内核的修改和影响,使得其进入Linux内核成为安全机制标准的可能性大大提升;等成为标准后,能够改变决策,增长功能和灵活性。函数
回页首工具
Linux安全模块(LSM)目前做为一个Linux内核补丁的形式实现。其自己不提供任何具体的安全策略,而是提供了一个通用的基础体系给安全模块,由安全模块来实现具体的安全策略。其主要在五个方面对Linux内核进行了修改:
下面对这五个方面的修改逐个作简要的介绍。
安全域是一个void*类型的指针,它使得安全模块把安全信息和内核内部对象联系起来。下面列出被修改加入了安全域的内核数据结构,以及各自所表明的内核内部对象:
另外,msg_msg结构,msg_queue结构,shmid_kernel结构被移到include/linux/msg.h和include/linux/shm.h这两个头文件中,使得安全模块可使用这些定义。
Linux安全模块(LSM)提供了两类对安全钩子函数的调用:一类管理内核对象的安全域,另外一类仲裁对这些内核对象的访问。对安全钩子函数的调用经过钩子来实现,钩子是全局表security_ops中的函数指针,这个全局表的类型是security_operations结构,这个结构定义在include/linux/security.h这个头文件中,这个结构中包含了按照内核对象或内核子系统分组的钩子组成的子结构,以及一些用于系统操做的顶层钩子。在内核源代码中很容易找到对钩子函数的调用:其前缀是security_ops->。对钩子函数的详细说明留到后面。
Linux安全模块(LSM)提供了一个通用的安全系统调用,容许安全模块为安全相关的应用编写新的系统调用,其风格相似于原有的Linux系统调用socketcall(),是一个多路的系统调用。这个系统调用为security(),其参数为(unsigned int id, unsigned int call, unsigned long *args),其中id表明模块描述符,call表明调用描述符,args表明参数列表。这个系统调用缺省的提供了一个sys_security()入口函数:其简单的以参数调用sys_security()钩子函数。若是安全模块不提供新的系统调用,就能够定义返回-ENOSYS的sys_security()钩子函数,可是大多数安全模块均可以本身定义这个系统调用的实现。
在内核引导的过程当中,Linux安全模块(LSM)框架被初始化为一系列的虚拟钩子函数,以实现传统的UNIX超级用户机制。当加载一个安全模块时,必须使用register_security()函数向Linux安全模块(LSM)框架注册这个安全模块:这个函数将设置全局表security_ops,使其指向这个安全模块的钩子函数指针,从而使内核向这个安全模块询问访问控制决策。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,直到这个安全模块被使用unregister_security()函数向框架注销:这简单的将钩子函数替换为缺省值,系统回到UNIX超级用户机制。另外,Linux安全模块(LSM)框架还提供了函数mod_reg_security()和函数mod_unreg_security(),使其后的安全模块能够向已经第一个注册的主模块注册和注销,但其策略实现由主模块决定:是提供某种策略来实现模块堆栈从而支持模块功能合成,仍是简单的返回错误值以忽略其后的安全模块。这些函数都提供在内核源代码文件security/security.c中。
Linux内核如今对POSIX.1e capabilities的一个子集提供支持。Linux安全模块(LSM)设计的一个需求就是把这个功能移植为一个可选的安全模块。POSIX.1e capabilities提供了划分传统超级用户特权并赋给特定的进程的功能。Linux安全模块(LSM)保留了用来在内核中执行capability检查的现存的capable()接口,但把capable()函数简化为一个Linux安全模块(LSM)钩子函数的包装,从而容许在安全模块中实现任何须要的逻辑。Linux安全模块(LSM)还保留了task_struck结构中的进程capability集(一个简单的位向量),而并无把它移到安全域中去。Linux内核对capabilities的支持还包括两个系统调用:capset()和capget()。Linux安全模块(LSM)一样保留了这些系统调用但将其替换为对钩子函数的调用,使其基本上能够经过security()系统调用来从新实现。Linux安全模块(LSM)已经开发而且移植了至关部分的capabilities逻辑到一个capabilities安全模块中,但内核中仍然保留了不少原有capabilities的残余。这些实现方法都最大程度的减小了对Linux内核的修改影响,而且最大程度保留了对原有使用capabilities的应用程序的支持,同时知足了设计的功能需求。之后要使capabilities模块彻底独立,剩下要作的主要步骤是:把位向量移到task_struct结构中合适的安全域中,以及从新定位系统调用接口。
Linux安全模块(LSM)对于内核开发人员和安全研究人员的价值就在于:可使用其提供的接口将现存的安全加强系统移植到这一框架上,从而可以以可加载内核模块的形式提供给用户使用;或者甚至能够直接编写适合本身须要的安全模块。Linux安全模块(LSM)提供的接口就是钩子,其初始化时所指向的虚拟函数实现了缺省的传统UNIX超级用户机制,模块编写者必须从新实现这些钩子函数来知足本身的安全策略。下面简要介绍Linux安全模块(LSM)提供的钩子,详细状况请参考源代码,特别是include/linux/security.h头文件中security_operations结构的定义。至于具体如何根据本身须要的安全策略编写安全模块,能够参考SELinux,DTE,LIDS等系统的安全模块实现。
首先是任务钩子,Linux安全模块(LSM)提供了一系列的任务钩子使得安全模块能够管理进程的安全信息而且控制进程的操做。模块可使用task_struct结构中的安全域来维护进程安全信息;任务钩子提供了控制进程间通讯的钩子,例如kill();还提供了控制对当前进程进行特权操做的钩子,例如setuid();还提供了对资源管理操做进行细粒度控制的钩子,例如setrlimit()和nice()。
其次是程序装载钩子。不少安全模块,包括Linux capabilities,SELinux,DTE都须要有在一个新程序执行时改变特权的能力。所以Linux安全模块(LSM)提供了一系列程序装载钩子,用在一个execve()操做执行过程的关键点上。linux_binprm结构中的安全域容许安全模块维护程序装载过程当中的安全信息;提供了钩子用于容许安全模块在装载程序前初始化安全信息和执行访问控制;还提供了钩子容许模块在新程序成功装载后更新任务的安全信息;还提供了钩子用来控制程序执行过程当中的状态继承,例如确认打开的文件描述符。
再次是进程间通讯IPC钩子。安全模块可使用进程间通讯IPC钩子来对System V IPC的安全信息进行管理,以及执行访问控制。IPC对象数据结构共享一个子结构kern_ipc_perm,而且这个子结构中只有一个指针传给现存的ipcperms()函数进行权限检查,所以Linux安全模块(LSM)在这个共享子结构中加入了一个安全域。为了支持单个消息的安全信息,Linux安全模块(LSM)还在msg_msg结构中加入了一个安全域。Linux安全模块(LSM)在现存的ipcperms()函数中插入了一个钩子,使得安全模块能够对每一个现存的Linux IPC权限执行检查。因为对于某些安全模块,这样的检查是不足够的,Linux安全模块(LSM)也在单个的IPC操做中插入了钩子。另外还有钩子支持对经过System V消息队列发送的单个消息进行细粒度的访问控制。
下面是文件系统钩子。对于文件操做,定义了三种钩子:文件系统钩子,inode结点钩子,以及文件钩子。Linux安全模块(LSM)在对应的三个内核数据结构中加入了安全域,分别是:super_block结构,inode结构,file结构。超级块文件系统钩子使得安全模块可以控制对整个文件系统进行的操做,例如挂载,卸载,还有statfs()。Linux安全模块(LSM)在permission()函数中插入了钩子,从而保留了这个函数,可是也提供了不少其余inode结点钩子来对单个inode结点操做进行细粒度访问控制。文件钩子中的一些容许安全模块对read()和write()这样的文件操做进行额外的检查;还有文件钩子容许安全模块控制经过socket IPC接收打开文件描述符;其余的文件钩子对像fcntl()和ioctl()这样的操做提供细粒度访问控制。
接下来是网络钩子。对网络的应用层访问使用一系列的socket套接字钩子来进行仲裁,这些钩子基本覆盖了全部基于socket套接字的协议。因为每一个激活的用户socket套接字有伴随有一个inode结构,因此在socket结构或是更底层的sock结构中都没有加入安全域。socket套接字钩子对有关进程的网络访问提供了一个通用的仲裁,从而显著扩展了内核的网络访问控制框架(这在网络层是已经由Linux内核防火墙netfilter进行处理的)。例如sock_rcv_skb钩子容许在进入内核的包排队到相应的用户空间socket套接字以前,按照其目的应用来对其进行仲裁。另外Linux安全模块(LSM)也为IPv4,UNIX域,以及Netlink协议实现了细粒度的钩子,之后还可能实现其余协议的钩子。网络数据以包的形式被封装在sk_buff结构(socket套接字缓冲区)中游历协议栈,Linux安全模块(LSM)在sk_buff结构中加入了一个安全域,使得可以在包的层次上对经过网络层的数据的安全信息进行管理,并提供了一系列的sk_buff钩子用于维护这个安全域的整个生命周期。硬件和软件网络设备被封装在一个net_device结构中,一个安全域被加到这个结构中,使得可以在设备的层次上维护安全信息。
最后是其余的钩子。Linux安全模块(LSM)提供了两种其余系列的钩子:模块钩子和顶层的系统钩子。模块钩子用来控制建立,初始化,清除内核模块的内核操做。系统钩子用来控制系统操做,例如设置主机名,访问I/O端口,以及配置进程记账。虽然如今的Linux内核经过使用capability检查对这些系统操做提供了一些支持,可是这些检查对于不一样操做差异很大而且没有提供任何参数信息。
Linux安全模块(LSM)对于普通用户的价值就在于:能够提供各类安全模块,由用户选择适合本身须要加载到内核,知足特定的安全功能。Linux安全模块(LSM)自己只提供加强访问控制策略的机制,而由各个安全模块实现具体特定的安全策略。下面简要介绍一些已经实现的安全模块。
SELinux。这是一个Flask灵活访问控制体系在Linux上的实现,而且提供了类型加强,基于角色的访问控制,以及可选的多级安全策略。SELinux原来是做为一个内核补丁实现的,如今已经使用Linux安全模块(LSM)从新实现为一个安全模块。SELinux能够被用来限制进程为最小特权,保护进程和数据的完整性和机密性,而且支持应用安全需求。
DTE Linux。这是一个域和类型加强在Linux上的实现。就像SELinux同样,DTE Linux原来是做为一个内核补丁实现的,如今已经使用Linux安全模块(LSM)从新实现为一个安全模块。当这个安全模块被加载到内核上时,类型被赋给对象,域被赋给进程。DTE策略限制域之间和从域到类型的访问。
Openwall 内核补丁的LSM移植。Openwall内核补丁提供了一系列的安全特性集合来保护系统免受例如缓冲区溢出和临时文件竞争这样的攻击。有安全模块正在被开发出来以支持Openwall补丁的一个子集。
POSIX.1e capabilities。Linux内核中已经存在有POSIX.1e capabilities逻辑,可是Linux安全模块(LSM)把这个逻辑划分到了一个安全模块中。这样的修改使得不须要的用户能够从他们的内核中把这个功能略去;也使得capabilities逻辑的开发能够脱离内核开发得到更大的独立性。
LIDS。这是中国人谢华刚发起的项目。开始时做为一个入侵检测系统开发,后来逐渐演变为使用访问控制系统的形式来进行入侵预防,它经过描述一个给定的程序能够访问哪些文件来进行访问控制。一样的,LIDS原来是做为一个内核补丁实现的并附带了一些管理工具,如今已经使用Linux安全模块(LSM)从新实现为一个安全模块。
固然还有缺省的传统超级用户机制。这个安全模块是Linux安全模块(LSM)缺省的,实现了传统的UNIX超级用户特权机制。
Linux安全模块(LSM)目前做为一个Linux内核补丁的形式实现,在GPL许可证下发布供用户自由使用。
首先用户能够在http://lsm.immunix.org/lsm_download.html下载到对应于Linux 2.4稳定版本和Linux 2.5开发版本的LSM补丁,放在某个目录下,例如是目录/path/to/linux-2.4.x,经过执行下面的命令来使LSM补丁做用在Linux内核上:
# cd /path/to/linux-2.4.x # zcat /path/to/patch-2.4.x-lsm.gz | patch -p1
而后用户能够在http://lsm.immunix.org/lsm_modules.html链接到已经实现安全模块的站点,下载到所须要的安全模块,将安全模块加载到Linux内核中,这样用户须要的安全策略就能够起做用了,从而加强了系统的安全性。具体安全模块的安装方法这里就略过了,各个安全模块都会提供详细的安装说明文件,用户能够参考这些文件,例如SELinux的安全模块安装说明文件在:http://www.nsa.gov/selinux/doc/readme.html,又如LIDS的安全模块安装说明文件在:http://www.lids.org/install.html。
若是用户有Linux内核和安全的相关背景知识和开发经验,想根据本身须要的安全策略编写安全模块。能够在http://lsm.immunix.org/lsm_bk.html跟踪查看Linux安全模块(LSM)的源代码和现有安全模块的源代码,参考其实现方法编写本身的安全模块。这样在知足本身安全需求的同时,也能够为Linux安全模块(LSM)的发展做出一些贡献,使其早日被Linux内核接受成为Linux内核安全机制的标准,使更多的用户得益。
Linux安全模块(LSM)的原由是:一方面Linux内核现有的安全机制是不足够的;另外一方面现存的安全加强系统又各自为战而且难以使用。Linux安全模块(LSM)比较好的解决了这个问题:一方面补丁比较小,对内核源代码的修改影响很少,所带来的负载也不大;另外一方面对现存的安全加强系统提供了比较好的接口支持,并已经有很多很好的安全模块可使用。Linux安全模块(LSM)目前仍然是做为一个Linux内核补丁的形式提供,可是其同时提供Linux 2.4稳定版本的系列和Linux 2.5开发版本的系列,而且颇有但愿进入Linux 2.6稳定版本。咱们期待着那一天:Linux安全模块(LSM)被Linux内核接受成为Linux内核安全机制的标准,在各个Linux发行版中提供给愈来愈多的用户使用。