实现系统安全的策略
在Linux中,一切皆为文件,实现系统安全的策略主要可分为两种:基于inode
的安全、基于文件路径的安全。
基于inode的安全
为文件引入安全属性,安全属性不属于文件内容,它是文件的元数据,应该与inode
关联,一些内核安全模块将安全属性存储在文件的扩展属性中,这种方式就是基于inode
的安全。基于inode
的安全的优点主要有两个:
- 文件的安全属性与文件路径无关。文件可以在不同目录间移动,不管它怎么移动,其安全属性都没有变化。
- 同一个文件可以有多个链接,从不同链接访问文件,其安全属性总是一样的。
基于inode
的安全的缺点是:
- 文件系统必须支持扩展属性,并且挂载文件系统时必须使用扩展属性。
- 删除文件时,文件的安全属性会随之消失。再在原来的路径处创建同名文件,并不能保证新文件和老文件的安全属性相同。
- 安装软件和升级软件需要保证系统中新的文件具有正确的安全属性。新文件来自软件包,新的安全属性自然也应该来自软件包。于是就有了下一个要求:众多软件包格式也需要支持文件的扩展属性,比如tar、cpio等。
基于inode
的安全实现策略有SELinux、SMACK等。
基于路径的安全
从用户角度看,用户通过路径访问文件,用户态进程无法用inode
号来访问文件。即使是基于inode
的安全,用户读写安全属性也需先通过路径找到文件,然后才能访问文件的安全属性。那么能否将文件的安全属性简单地与文件路径对应起来呢?比如/bin/bash
的安全属性是"system-shell
",/usr/local/bin/bash
的安全属性是"local-shell
"。不把这些安全属性存储在文件的扩展属性中,而是存储在系统内部的一张表里,这就是基于路径的安全的实现原理。这样做的优点是:
- 不需要文件系统有额外支持。
- 不怕文件更新,对打包格式也没有额外要求。用户甚至可以为还不存在的文件定义安全属性。
基于路径的安全的缺点是:同一个文件可能有多个安全属性,简单地创建链接就可能让文件拥有另一个安全属性。
基于路径的安全实现策略实现有Tomoyo、AppArmor等。
对文件读取的安全策略
实现对文件读取的安全策略也有两种,一种是使用file_permission
钩子函数,另一种是使用inode_permission
钩子函数。它们的区别如下:
inode_permission
和 file_permission
都与文件系统中的权限有关,但是它们的作用和范围不同。
inode_permission
是指针对文件 inode
的权限控制,而 file_permission
则是针对打开的文件描述符的权限控制。
当一个文件被创建时,系统为其分配一个 inode
(inode
存储了文件的元数据,如访问时间、修改时间、权限等信息),在对该文件进行权限控制时,操作系统会检查进程是否有访问该文件 inode
的权限,如果权限不足则拒绝访问。这部分的权限控制由inode_permission
完成。
而开发者在使用系统调用(如 open
、read
、write
等)打开文件时可以得到一个文件描述符,通过该描述符可以对打开的文件进行操作。在这里,系统会检查该进程是否有访问该文件描述符所代表的文件的权限,并在权限不足的情况下拒绝访问。这部分的权限控制就是由 file_permission
完成的。
因此,inode_permission
和 file_permission
虽然都是与权限有关,但是控制的范围不一样。inode_permission
主要关注于文件所在的 inode
层面,而 file_permission
则关注于打开的文件描述符层面,它们协同工作来保证文件的安全性。