清单 2. 用于 socket 创建检查的间接调用
static inline int security_socket_create (int family, int type,
int protocol, int kern)
{
return security_ops->socket_create(family, type, protocol, kern);
}
security_ops 结构中的函数通过安全模块安装。在本例中,这些钩子在可载入的 SELinux 内核模块中定义。每个 SELinux 调用在 hooks 文件内部定义,该文件实现从内核函数到特定安全模块的动态调用的间接性(参见清单 3 中的 .../linux/security/selinux/hooks.c 代码)。
清单 3. SELinux socket 创建检查
static int selinux_socket_create(int family, int type,
int protocol, int kern)
{
int err = 0;
struct task_security_struct *tsec;
if (kern)
goto out;
tsec = current->security;
err = avc_has_perm(tsec->sid, tsec->sid,
socket_type_to_security_class(family, type,
protocol), SOCKET__CREATE, NULL);
out:
return err;
}
清单 3 的核心部分是一个调用,用于验证当前操作是否是当前任务(通过 current->security 定义,其中 current 代表当前正在执行的任务)所允许的。访问向量缓存(Access Vector Cache,AVC)缓存了之前的 SELinux 决策(提高进程的性能)。此调用包括源安全标识符(sid)、安全类(根据请求操作的详细信息构造)、特定 socket 调用,以及可选的辅助审计数据。如果未在缓存中找到决策,那么会调用安全服务器来获取决策(此过程如图 2 所示)。
图 2. 分层 Linux 安全进程
初始化到 security_ops 中的回调钩子被动态定义为一个可载入内核模块(通过 register_security()),但是在没有载入安全模块时,这些钩子包含伪桩(dummy stub)函数(参见 ./linux/security/dummy.c)。这些桩函数实现标准 Linux DAC 策略。始终存在回调钩子,其中必须提供对象中介(mediation)来保证安全性。这包括任务管理(创建、通知、等待)、程序载入(execve)、文件系统管理(超级块、inode、文件钩子)、IPC(消息队列、共享内存、信号量(semaphore)操作)、模块钩子(插入和删除)、网络钩子(覆盖 socket、netlink、网络设备和其他协议接口)。更多信息请参见 参考资料 小节或回顾 security.h 文件。
其他方法
SELinux 是目前最全面的安全框架之一,但它不是惟一的。本节回顾其他一些可用的方法。
AppArmor
AppArmor 最初由 Immunix 开发,随后由 Novell 维护,它是 SELinux 的替代方法,也使用了 Linux 安全模块(LSM)框架。由于 SELinux 和 AppArmor 使用了同样的框架,所以它们可以互换。AppArmor 的开发初衷是因为人们认为 SELinux 太过复杂,不适合普通用户管理。AppArmor 包含一个完全可配置的 MAC 模型和一个学习模式,在学习模式中,程序的典型行为可以转换为一个配置文件。
SELinux 的一个问题在于,它需要一个支持扩展属性的文件系统;而 AppArmor 对文件系统没有任何要求。您可以在 SUSE、OpenSUSE,以及 Ubuntu 的 Gutsy Gibbon 中找到 AppArmor。
Solaris 10(是受信任的 Solaris)
Solaris 10 操作系统通过其增强了安全性的 Trusted Extensions 组件提供了强制访问控制。该功能适用于 MAC 和 RBAC。Solaris 通过向所有对象添加敏感性标签实现了这一点,使您能够控制设备、文件、连网访问,甚至窗口管理服务。Solaris 10 中的 RBAC 的优点在于,它通过提供对管理任务(可在以后进行分配)的细粒度控制最小化了对根访问的需求。
TrustedBSD
TrustedBSD 是一个正在进行中的项目,主要开发可靠的操作系统扩展,这些扩展最终会加入 FreeBSD 操作系统。它包括构建在 Flux Advanced Security Kernel (Flask) 安全架构之上的强制访问控制,后者包括以插件模块形式提供的类型强制和多级安全(MLS)。TrustedBSD 还合并了来自 Apple Darwin 操作系统的开源 Basic Security Module (BSM) 审计实现(BSM 最初由 Sun 引入)。BSM 是一个审计 API 和文件格式,它支持普通的审计跟踪处理。TrustedBSD 还构成了供 Security Enhanced Darwin (SEDarwin) 使用的框架。
操作系统虚拟化
增强操作系统内部安全性的最后一个选择是操作系统虚拟化(也称为虚拟专用服务器(virtual private servers))。一个操作系统拥有多个独立的用户空间实例,可以实现功能分离。操作系统虚拟化对在独立用户空间内部运行的应用程序功能进行了限制。例如,一个用户空间实例也许不能修改内核(载入或移除内核模块),也不能挂载或卸载文件系统。并且不允许修改内核参数(例如,通过 proc 文件系统)。任何修改其他用户实例环境的操作都是不允许的。
许多操作系统都能实现操作系统虚拟化。GNU/Linux 支持 VServer、Parallels Viruozzo Container 和 OpenVZ。在其他操作系统中,您可以找到容器(Solaris)和 jail(BSD)。在 Linux-VServer 中,每个单独的用户空间实例称为一个安全上下文。在每个安全上下文中,会为专用服务器实例启动一个新的 init。
结束语
对于 Linux 内核来说,强制访问控制和基于角色的访问控制都是相对较新的功能。随着 LSM 框架的引入,新的安全模块将会出现。除了对框架的增强,还可以堆叠安全模块,从而允许多个安全模块共存,而且最大限度地覆盖了 Linux 的安全需求。随着对操作系统安全性的深入研究,将会引入新的访问控制方法。