内核角落 - NSA 安全增强型 Linux
NSA 安全增强型 Linux 的根基在于分布式可信操作系统 (DTOS) 和 Flask (Flux 高级安全内核) 架构。DTOS 项目是 20 世纪 90 年代初期和中期美国国家安全局 (NSA) 与 Secure Computing Corporation (SCC) 之间的合作成果。其目标是提供比标准安全方法更强大的操作系统安全机制。Flask 架构是 NSA、SCC 和犹他大学 Flux 项目共同努力的成果,该项目“经过增强以提供对动态安全策略的更好支持”(www.cs.utah.edu/flux/flask,“Flask:Flux 高级安全内核”,Stephen Smalley,NAI Labs,2000 年 12 月 26 日)。
SE Linux 实施强制访问控制或 MAC,而常规 UNIX 系统采用自主访问控制或 DAC。使用 DAC,用户可以自行决定控制应用于他们拥有的对象的访问权限。例如,在 UNIX 系统上,他们可以使用 chmod 命令来更改他们拥有的目录的权限。使用 MAC,访问控制由更权威的用户决定,他们配置安全策略来确定对象拥有的访问权限。如果策略阻止 Bob 访问 Alice 的主目录,并且 Alice 运行chmod 777在她自己的主目录上,Bob 仍然无法访问它。
当使用 MAC 时,进程以最小权限运行,并且受损进程无法向其他进程授予对其自身资源的不适当访问权限。这减少了守护进程受损时可能发生的损害程度。安全决策基于多种因素,例如用户的角色、正在运行的程序类型、该程序的受信任程度以及正在访问的数据的机密级别或完整性。
SE Linux 是在 Linux 内核中灵活、细粒度的强制访问控制的实现,现在使用 LSM 框架实现(参见 Greg Kroah-Hartman 的“使用内核安全模块接口”,LJ,2002 年 11 月)。在其当前实现中,LSM 接口仅支持限制性访问控制。因此,如果标准 UNIX 权限拒绝操作,则 SE Linux 无法允许它。SE Linux 通常用于对采用 UNIX 权限的系统应用额外的限制,并且它完全有能力自行强制执行所有必要的访问控制。但是,强烈建议将 UNIX 权限和 SE Linux 结合使用,以在生产服务器上实现“深度防御”。SE Linux 由内核补丁和实用程序(如 login 和 cron)的补丁组成。
NSA 负责官方发布。NSA 以外的许多其他人也为该项目贡献代码。软件包不断为 Debian 稳定版和非稳定版维护。由于 SE Linux 在 GPL 下获得许可,任何人都可以贡献并进行自己的修改。SE Linux 可以在 2.4.19 及更高版本的内核上使用,并且在本文撰写时(2003 年 5 月),它正在为 2.5 内核重新开发。
如前所述,SE Linux 由内核补丁和修改后的实用程序组成。修改后的实用程序确保系统上的所有文件都具有正确的安全上下文。修改后的实用程序版本,例如 login、cron 和 logrotate,以及程序,例如 ps 和 ls,均可用。例如,对于 login,当用户登录系统时拥有正确的安全上下文至关重要。否则,他可能根本无法登录。
在 SE Linux 入门 HOWTO(参见资源)中介绍了安装 login 软件包,这超出了本文的范围。但是,如果在 SE Linux 安装期间忘记安装 login 软件包,会导致在重新启动后无法为从中登录的终端设备分配正确的类型,从而导致您无法登录。未修改的 login 程序还在安全上下文中运行 shell,该安全上下文被拒绝访问用户主目录中的文件。例如,login 和 cron 的补丁告诉内核要使用哪个安全上下文。这些措施的实际强制执行由内核完成。标记至关重要,因此需要一些修改后的程序。可以创建自己的安全策略,这些策略提供基本级别的保护,而无需安装修改后的软件包,但默认配置提供更精细的安全保障。
在阅读有关 SE Linux 或邮件列表帖子的文档时,始终会使用以下术语。在您尝试安装 SE Linux 之前,尽可能熟悉它们非常重要。这样做会使以后的事情变得容易得多。
域:域详细说明了进程可以做什么和不能做什么,或者更确切地说,进程可以在各种类型上执行哪些操作。如果您在 user_t 域(标准非特权用户域)中,并且您运行命令ps aux,您只会看到在 user_t 域中运行的进程。域的一些示例包括 sysadm_t(系统管理域)和 init_t(init 运行所在的域)。passwd 程序由非特权用户运行所在的域是 passwd_t。
角色:角色决定可以使用哪些域。用户角色可以访问的域在策略数据库中预定义。如果角色未被授权进入域(在配置文件中),则会被拒绝。角色的一些示例包括通用非特权用户角色 (user_r) 和系统管理员角色 (sysadm_r)。
考虑以下示例:为了让 user_t 域的用户执行 passwd 命令,role user_r types passwd_t ;在相关配置文件中指定。此外,必须设置此处未涵盖的其他域转换规则。此添加的代码声明,用户角色 (user_r) 中的用户被允许进入 passwd_t 域,因此他可以运行 passwd 命令。另一个考虑因素是是否允许旧域转换为新域。
现在我们已经定义了域和角色,我们可以看看 SE Linux 和标准 UNIX uid(用户 ID)之间的比较。如果 root 拥有 UNIX 权限 4777 的程序(使程序 setuid root),则系统上的任何用户都可以执行该程序,从而导致安全问题。但是,使用 SE Linux,如果进程触发到特权域的域转换,并且进程的角色未被授权进入特定域,则该程序无法运行。SE Linux 系统上的每个进程都在一个域中运行,该域确定进程拥有的访问权限。
身份:SE Linux 下的身份与大多数读者可能熟悉的传统 UNIX uid 不同。SE Linux 下的身份构成安全上下文的一部分,该上下文控制您可以做什么和不能做什么。SE Linux 身份和常规 UNIX 登录名可能具有相同的文本表示形式(在大多数情况下,为了易于使用,它们是相同的),但重要的是要理解它们是两个不同的实体。默认情况下,如果相关的 SE Linux 身份存在,则它们是相同的。因此,如果我以用户 faye 身份登录 SE Linux 系统,并且策略数据库已编译到身份 faye 中,那么我的进程将被分配给 faye 身份。
为了说明标准 UNIX 用户 ID 与 SE Linux 身份不同,请考虑 su 命令。运行su不会更改 SE Linux 下的用户身份,但它会以与在非 SE Linux 系统上相同的方式更改 uid。如果 SE Linux 系统上的用户 faye 输入su -切换到 root,然后运行id命令,该命令返回她的安全上下文和其他信息,她会看到她的身份仍然是 faye 而不是 root,但她的 uid 已更改。为了进一步说明这一点,如果登录名为 faye 的非特权用户运行id命令,她将看到以下安全上下文
uid=1000(faye) gid=1000(faye) groups=1000(faye) context=faye:user_r:user_t sid=45
在这种情况下,安全上下文的身份部分是 faye。请注意 uid 为 1000。接下来,假设 faye 执行su到 root 并再次运行id命令;她现在会看到
uid=0(root) gid=0(root) groups=0(root) context=faye:user_r:user_t sid=453
身份没有更改为预期的 root,但 uid 已更改为 0。但是,如果用户 faye 被授予访问超级用户角色或 sysadm_r 的权限,她可以通过在控制台上登录并指定她想要超级用户角色或输入newrole -r稍后介绍的命令。如果她再次运行 id 命令,她现在会看到context=3Dfaye:sysadm_r:sysadm_t.
因此,身份再次保持不变,但角色和域(分别为第二和第三个字段)已更改。以这种方式维护身份在需要用户问责制的情况下很有用。它对于系统安全也至关重要,因为用户身份决定了可以使用哪些角色和域。使用常规 UNIX,如果您有一个非全局可执行的 setuid 或 setgid 程序,则是否执行它不是由您登录的用户的权限决定的,而是由您上次执行的su到达的用户的权限决定的。此限制在 SE Linux 下不存在,因为您的身份在所有操作中都会被跟踪。如果您的域未被授予执行该 setuid/setgid 程序的权限,即使您执行了su到 root,您也无法运行它。您被允许进入的域由您的角色决定,而您被允许进入的角色由您的身份决定。因此,身份间接控制您可以进入的域列表。
类型:每个对象都分配有一个类型,该类型决定了什么可以访问该对象。这里的对象是文件、目录、套接字和其他进程。类型在概念上类似于域,不同之处在于域仅适用于进程。更具体地说,域是可以应用于进程的类型。
转换:转换是指请求操作的安全上下文更改。转换分为两类。第一类是进程域的转换。当您执行给定类型的程序时,可能会从进程的当前域转换为新域。为了说明这一点,我将使用 newrole 命令。newrole 命令用于更改您的角色,例如,从 user_r 更改为 sysadm_r,假设您已被授予访问 sysadm_r 的权限。如果您以 user_r(通用非特权用户角色)开头并运行newrole -r sysadm_r更改为 sysadm_r(系统管理员角色),则会从您的 user_t 域转换为 newrole_t(newrole 进程运行所在的域),然后再转换为 sysadm_t 域。
第二类转换是在特定目录下创建文件时的文件类型转换。如果用户在他的主目录中创建一个文件,则该文件被标记为 user_home_t。但是,如果同一用户在 /tmp 中创建一个文件,则该文件被标记为 user_tmp_t。user_tmp_t 源自 /tmp 的类型,即 tmp_t,以及创建进程的域,即 user_t。当用户在 /tmp 下创建一个文件时,会转换为 user_tmp_t 类型。
策略:策略决定了各种域可以对各种类型执行哪些操作。所有守护进程都有自己的策略,并且命名约定采用 守护进程名称.te 的形式—postfix.te、apache.te 等等。作为 SE Linux 机器的系统管理员,您可以编辑您的策略文件以满足您的要求。策略数据库是策略源文件的编译形式,并在启动时由内核加载。
SE Linux 系统上的 spasswd 程序用于更改您的密码。spasswd 实际上是 Linux 系统上使用的标准 passwd 命令的包装器;它确保 passwd 程序在正确的域中运行。它还确保您的 SE Linux 身份与您的常规 UNIX 帐户名匹配。前面我提到常规 UNIX 用户 ID 与 SE Linux 身份完全不同,那么为什么在运行 spasswd 时它们必须匹配呢?spasswd 要求您具有与您的 UNIX 帐户名相同的 SE Linux 身份名称。回想一下,在 SE Linux 系统上,您的身份是确定您身份的唯一方法。因此,如果您当前不是相应的 UNIX 用户,则无法更改密码。
如果您是系统管理员用户 (sysadm_r),则 sadminpasswd 程序用于更改其他用户的密码。sadminpasswd 没有 spasswd 具有的相同匹配用户名/身份限制,但 sadminpasswd 只能由 sysadm_t 运行。
SE Linux 可以在两种模式之一中运行:许可模式或强制模式。许可模式用于调试目的,因为所有内容都会被记录,但 SE Linux 实际上并未强制执行您的策略。您仍然可以像在常规 Linux 系统上一样以 root 身份执行操作。最好在许可模式下运行您的机器,直到您对所有策略都正确感到满意为止。标签已分配给系统上的对象,但未强制执行任何操作。
强制模式应用您配置的策略,例如访问限制。只有当您确信一切正常工作后,才应启动到强制模式,在许可模式下运行一段时间后。请记住,如果您的内核在编译时没有开发支持,则无法指定许可模式。如果您的内核在编译时启用了开发模式支持,则意味着您的机器启动进入许可模式,但您必须手动将其切换到强制模式。这可以通过创建一个启动脚本轻松完成。
或者,您可以在 /etc/rc.boot/avc 和 /sbin/avc_toggle 之间建立链接。另一种选择是指定enforcing=1在内核命令行上。avc_toggle 命令可用于在许可模式和强制模式之间切换,avc_enforcing 命令可用于确定您是否处于强制模式。
希望本文让您有兴趣尝试 SE Linux。我故意省略了安装说明,因为您可以使用 RPM、源 tarball 或 Debian 软件包进行安装。即使在此处包含每种方法的基础知识也会占据整篇文章。在安装之前、期间和之后有很多东西要学习,新用户经常会感到非常困惑。如果您在执行任何其他操作之前阅读资源部分中引用的文档,并熟悉常用术语,您应该会发现它稍微容易一些。如果您遇到困难,请启动您最喜欢的 IRC 客户端并转到 irc.debian.org 上的 #selinux 频道,或订阅 SE Linux 邮件列表。
资源
Flask (Flux 高级安全内核):www.cs.utah.edu/flux/flask
SE Linux 入门 HOWTO:sourceforge.net/docman/display_doc.php?docid=15285&group_id=21266
NSA 官方 SE Linux 站点:www.nsa.gov/selinux
NSA SE Linux 常见问题解答:www.nsa.gov/selinux/faq.html
NSA SE Linux 白皮书:www.nsa.gov/selinux/docs.html
SE Linux 邮件列表:www.nsa.gov/selinux/list.html
SE Linux 邮件列表存档:marc.theaimsgroup.com/?l=selinux
SourceForge SE Linux 项目页面:sourceforge.net/projects/selinux
Faye Coker 目前担任自由系统管理员,并且经常发现自己在 ISP 运行系统并将服务器转换为 Linux。她曾在欧洲和澳大利亚工作过。在 Linux 会议上,她也被问过“你迷路了吗?”太多次了。