跳到内容跳到页面导航:上一页 [access key p]/下一页 [access key n]
documentation.suse.com / SUSE Linux Enterprise Server 文档 / 安全指南 / SELinux 对比 / 配置 SELinux
适用范围 SUSE Linux Enterprise Server 15 SP2

33 配置 SELinux

在本章中,您将了解如何在 SUSE Linux Enterprise Server 上设置和管理 SELinux。其中包括以下主题:

  • 为何要使用 SELinux?

  • 了解 SELinux

  • 设置 SELinux

  • 管理 SELinux

33.1 为何要使用 SELinux?

SELinux 是作为附加的 Linux 安全解决方案开发的,它运用了 Linux 内核中的安全框架。其目的是除了默认的现有权限“读取”、“写入”和“执行”所能提供的安全策略,以及指派对 Linux 上提供的不同功能的权限之外,能够支持更精细的安全策略。为实现此目的,SELinux 会捕获到达内核的所有系统调用,并默认拒绝这些调用。这意味着,在启用了 SELinux 但未配置任何其他设置的系统上,一切都无法正常运行。要使系统能够执行任何操作,管理员需要编写规则并将其放入策略中。

下面的示例解释了为何需要 SELinux 这样的解决方案(或其类似产品 AppArmor):

有一天早上,我发现我的服务器被黑客入侵了。这台服务器运行的是安装了全套补丁的 SUSE Linux Enterprise Server。服务器上配置了防火墙,并且不提供任何不需要的服务。进一步的分析表明,黑客是通过一个有漏洞的 PHP 脚本入侵的,这个脚本是这台服务器上运行的某个 Apache 虚拟主机的一部分。入侵者设法通过 Apache Web 服务器所用的 wwwrun 帐户获得了外壳访问权限。入侵者以这个 wwwrun 用户的身份在 /var/tmp/tmp 目录中创建了多个脚本,这些脚本组成了针对多台服务器发起分布式拒绝服务攻击的僵尸网络。

对于这次攻击,有意思的地方在于,它是在一台实际上并无任何错误的服务器上发生的。所有权限的设置都是正确的,但入侵者还是设法进入了系统。此示例清楚地证明,在某些情况下,还需要进一步提高安全性 — 超越 SELinux 所能提供的安全性。可以使用 AppArmor 作为替代,其复杂性相对较低但功能较不完整。

AppArmor 可以限制特定进程读取/写入和执行文件的能力(及其他能力)。其主要理念是进程内部发生的操作都不能脱离控制。

而 SELinux 则是使用附加到对象(例如文件、二进制文件、网络套接字)的标签,并通过这些标签确定特权边界,从而建立一个可以跨越多个进程甚至整个系统的限制级别。

SELinux 由美国国家安全局 (NSA) 开发,Red Hat 从一开始就大力参与了它的开发。SELinux 的第一个版本在 Red Hat Enterprise Linux 4™ 时代(大约为 2006 年)推出。最初它仅提供对最关键的服务的支持,多年以来,它已发展成为一套能够提供许多规则的系统,这些规则可收集到策略中,以便为各种各样的服务提供保护。

SELinux 是根据通用准则和 FIPS 140 等一些认证标准开发的。由于某些客户特意要求解决方案符合这些标准,SELinux 很快变得相对流行。

Novell 于 2005 年收购的公司 Immunix 开发了用于替代 SELinux 的 AppArmorAppArmor 立足的安全原理与 SELinux 相同,但采用了完全不同的方法,它可以通过简单易用的向导驱动式过程,将服务限制为仅可执行需要它们执行的操作。然而,AppArmor 从未达到过与 SELinux 相同的高度,尽管有些不错的论据指出,使用 AppArmor 保护服务器的效果比使用 SELinux 的效果更好。

由于许多组织请求在他们所用的 Linux 发行套件中包含 SELinux,SUSE 在 SUSE Linux Enterprise Server 中提供了 SELinux 框架支持。这并不意味着,在不久的将来,默认的 SUSE Linux Enterprise Server 安装将从 AppArmor 改为 SELinux。

33.1.1 支持状态

SUSE Linux Enterprise Server 支持 SELinux 框架。也就是说,SLES 提供了您能够在服务器上使用 SELinux 所需的所有二进制文件和库。

SUSE Linux Enterprise Server 中的 SELinux 支持处于一个相当早期的阶段,意味着它可能会出现意外的行为。为了尽可能减少这种风险,最好仅使用 SUSE Linux Enterprise Server 上默认提供的二进制文件。

33.1.2 了解 SELinux 组件

在开始配置 SELinux 之前,您应该对 SELinux 的组织方式有个大致的了解。重要组件包括以下三个:

  • Linux 内核中的安全框架

  • SELinux 库和二进制文件

  • SELinux 策略

SUSE Linux Enterprise Server 的默认内核支持 SELinux 以及管理 SELinux 所需的工具。关于 SELinux,管理员最重要的工作是管理策略。

警告
警告:不包含默认策略

SUSE Linux Enterprise Server 中不提供任何默认策略或参考策略。SELinux 在没有策略的情况下无法运行,因此您必须构建并安装一个策略。SELinux 参考策略项目 (https://github.com/SELinuxProject/refpolicy/wiki) 提供了有关如何创建您自己的策略的示例和详细信息,应该会对您有所帮助。本章也提供了有关如何管理 SELinux 策略的指导。

在 SELinux 策略中,安全性标签将应用到 Linux 服务器上的不同对象。这些对象通常是用户、端口、进程和文件。使用这些安全性标签可以创建规则,用于定义在服务器上允许和不允许执行哪些操作。请记住,SELinux 默认会拒绝任何操作,而创建适当的规则可以允许进行确实有必要的访问。因此,您要在系统上使用的所有程序应该都有相应的规则。或者,您应将系统的某些组成部分配置为以非受限模式运行,这意味着特定的端口、程序、用户、文件和目录将不受 SELinux 的保护。如果您只想使用 SELinux 来保护某些必不可少的服务,而不特别担心其他服务,此模式将十分有用。要想使系统真正安全,应该避免这种做法。

要确保为系统提供适当的保护,您需要有 SELinux 策略。这必须是一个定制的策略,其中的所有文件都带有标签,并且所有服务和用户也都带有安全性标签,以指明哪些文件和目录可由哪个用户访问以及在服务器上处理。制定此类策略涉及到巨大的工作量。

SELinux 的复杂性也是它受到诟病的主要原因之一。由于典型的 Linux 系统太过复杂,用户很容易忽视某些问题,留下漏洞被入侵者滥用并进入其系统。即使已将 SELinux 设置为完全按照预期方式运行,管理员也仍然很难做到兼顾 SELinux 的方方面面。在复杂性方面,AppArmor 采用完全不同的方法,通过自动化过程使管理员能够设置 AppArmor 保护并确切了解发生的情况。

请注意,免费提供的 SELinux 策略在您的服务器上也许可以正常运行,但不太可能会提供与自定义策略同等程度的保护。SUSE 不支持第三方策略。

33.2 策略

策略是 SELinux 中的关键组件。请注意,SUSE Linux Enterprise Server 不包含默认策略或参考策略,您必须先构建并安装一个根据您的需求自定义的策略,然后再继续操作。(请参见警告:不包含默认策略。)

您的 SELinux 策略需定义用于指定哪些对象可以访问系统上的哪些文件、目录、端口和进程的规则。为此,需为所有这些对象定义一个安全环境。在已应用策略来标记文件系统的 SELinux 系统上,您可对任何目录使用 ls -Z 命令来查找该目录中各文件的安全环境。例 33.1: “使用 ls -Z 查找安全环境设置”显示了采用 SELinux 标记文件系统的 SUSE Linux Enterprise Server 系统上 / 目录中各目录的安全环境设置。

例 33.1︰ 使用 ls -Z 查找安全环境设置
ls -Z
system_u:object_r:bin_t bin
system_u:object_r:boot_t boot
system_u:object_r:device_t dev
system_u:object_r:etc_t etc
system_u:object_r:home_root_t home
system_u:object_r:lib_t lib
system_u:object_r:lib_t lib64
system_u:object_r:lost_found_t lost+found
system_u:object_r:mnt_t media
system_u:object_r:mnt_t mnt
system_u:object_r:usr_t opt
system_u:object_r:proc_t proc
system_u:object_r:default_t root
system_u:object_r:bin_t sbin
system_u:object_r:security_t selinux
system_u:object_r:var_t srv
system_u:object_r:sysfs_t sys
system_u:object_r:tmp_t tmp
system_u:object_r:usr_t usr
system_u:object_r:var_t var

安全环境中最重要的一行是环境类型。它是安全环境中以 _t 结尾的部分。它告知 SELinux 允许对象进行哪种访问。策略中指定了规则,用于定义哪种类型的用户或角色有权访问哪种类型的环境。例如,使用如下所示的规则可以进行这样的定义:

allow user_t bin_t:file {read execute gettattr};

此示例规则指出,允许环境类型为 user_t 的用户(此用户称为源对象)使用 read、execute 和 getattr 权限访问环境类型为 bin_t 的“file”类别对象(目标)。

您要使用的标准策略包含海量的规则。为使其更易于管理,通常会将策略分割成多个模块。这样,管理员便可为不同的系统组件打开或关闭保护。

为系统编译策略时,您可以选择使用模块化策略或单体式策略,如果选择后者,将使用一个巨型策略来保护系统上的一切组件。强烈建议使用模块化策略,而不要使用单体式策略。模块化策略要容易管理得多。

33.3 安装 SELinux 软件包并修改 GRUB 2

确保安装所有 SELinux 组件的最简单的方法是使用 YaST。下述过程说明了要在安装的 SUSE Linux Enterprise Server 上执行哪些操作:

  1. root 身份登录您的服务器并启动 YaST。

  2. 选择软件 › 软件管理

  3. 选择视图 › 模式,然后选择整个 C/C++ 开发类别进行安装。

  4. 选择视图 › 搜索,确保搜索范围名称关键字摘要处于选中状态。现在输入关键字 selinux 并单击搜索。您现在即会看到软件包列表。

  5. 确保找出的所有软件包已选中,然后单击接受安装这些软件包。

在 YaST 中选择所有 SELinux 软件包
图 33.1︰ 在 YaST 中选择所有 SELinux 软件包

安装 SELinux 软件包后,需要修改 GRUB 2 引导加载程序。请在 YaST 中选择系统 › 引导加载程序 › 内核参数来完成此操作。现在,将以下参数添加到可选内核命令行参数

security=selinux selinux=1 enforcing=0

这些选项用于以下目的:

security=selinux

此选项告知内核要使用 SELinux 而非 AppArmor

selinux=1

此选项用于启用 SELinux

enforcing=0

此选项将 SELinux 置于宽松模式。在此模式下,SELinux 可完全正常运行,但不会强制执行策略中的任何安全性设置。请使用此模式来配置您的系统。要启用 SELinux 保护,请在系统完全正常运行后,将该选项更改为 enforcing=1,并在 /etc/selinux/config 中添加 SELINUX=enforcing

安装 SELinux 软件包并启用 SELinux GRUB 2 引导参数后,重引导您的服务器以激活配置。

33.4 SELinux 策略

策略是 SELinux 不可或缺的组件。SUSE Linux Enterprise Server 15 SP2 不包含默认策略或参考策略,您必须针对您的安装构建一个自定义策略。要进行测试和学习,请参见 https://github.com/SELinuxProject/refpolicy/wiki 上的 SELinux 参考策略项目。您必须有一个策略,否则 SELinux 不会正常运行。

安装策略后,便可以开始标记文件系统了。运行

tux > sudo restorecon -Rp /

以启动 /sbin/setfiles 命令来标记系统上的所有文件。系统将使用 /etc/selinux/minimum/contexts/files/file_contexts 输入文件。file_contexts 文件需尽可能与您的实际文件系统相匹配,否则可能导致系统完全无法引导。如果发生这种情况,请使用 semanage fcontext 命令修改 file_contexts 中的记录,使之与服务器使用的文件系统的实际结构相匹配。例如,

tux > sudo semanage fcontext -a -t samba_share_t /etc/example_file

将文件类型从默认的 etc_t 更改为 samba_share_t,并将以下记录添加到相关的 file_contexts.local 文件中:

/etc/example_file    unconfined_u:object_r:samba_share_t:s0

然后运行

tux > sudo restorecon -v /etc/example_file

以使类型更改生效。

在执行此操作之前,请务必阅读本章的其余内容,以便全面了解环境类型如何应用到文件和目录。在开始之前,请不要忘记备份 file_contexts 文件。

注意
注意:用户 nobody

使用 semanage 时,您可能会收到一条消息,指出 nobody 的主目录有问题。在这种情况下,请将用户 nobody 的登录外壳更改为 /sbin/nologin。这样 nobody 的设置便与当前策略设置相匹配。

再次重引导后,SELinux 应当会正常运行。要进行校验,请使用 sestatus -v 命令。此命令应该会返回类似于例 33.2: “校验 SELinux 是否正常运行”中的输出。

例 33.2︰ 校验 SELinux 是否正常运行
tux > sudo sestatus -v
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   permissive
Mode from config file:          permissive
Policy version:                 26
Policy from config file:        minimum

Process contexts:
Current context:                root:staff_r:staff_t
Init context:                   system_u:system_r:init_t
/sbin/mingetty                  system_u:system_r:sysadm_t
/usr/sbin/sshd                  system_u:system_r:sshd_t

File contexts:
Controlling term:               root:object_r:user_devpts_t
/etc/passwd                     system_u:object_r:etc_t
/etc/shadow                     system_u:object_r:shadow_t
/bin/bash                       system_u:object_r:shell_exec_t
/bin/login                      system_u:object_r:login_exec_t
/bin/sh                         system_u:object_r:bin_t -> system_u:object_r:shell_exec_t
/sbin/agetty                    system_u:object_r:getty_exec_t
/sbin/init                      system_u:object_r:init_exec_t
/sbin/mingetty                  system_u:object_r:getty_exec_t
/usr/sbin/sshd                  system_u:object_r:sshd_exec_t
/lib/libc.so.6                  system_u:object_r:lib_t -> system_u:object_r:lib_t
/lib/ld-linux.so.2              system_u:object_r:lib_t -> system_u:object_r:ld_so_t

33.5 配置 SELinux

现在,您有了一个完全正常运行的 SELinux 系统,接下来我们来进一步配置这个系统。在当前状态下,SELinux 可正常运行,但并未处于强制模式。这意味着,它不会限制您执行任何操作,但会记录如果处于强制模式下它将会执行的所有操作。此模式很有用,因为您可以根据日志文件来确定它将阻止您执行什么操作。作为第一项测试,请将 SELinux 置于强制模式,并在采取以下做法之后确定您是否仍可使用服务器:检查在 /etc/selinux/config 中设置了 SELINUX=enforcing 的同时,是否在 GRUB 2 配置文件中设置了 enforcing=1 选项。重引导服务器,然后检查它是否仍可按预期方式正常启动。如果是,请保留当前设置,然后开始修改服务器,并使一切按预期方式工作。不过,您有可能甚至无法正常引导服务器。在这种情况下,请切换回 SELinux 的非强制模式,然后开始调整服务器。

在开始调整服务器之前,请校验 SELinux 安装。您已使用 sestatus -v 命令查看当前模式、进程和文件环境。接下来,运行

tux > sudo semanage boolean -l

以列出所有可用的布尔开关,同时校验您是否可以访问该策略。例 33.3 “获取布尔值列表并校验策略是否可访问”显示了此命令的部分输出。

例 33.3︰ 获取布尔值列表并校验策略是否可访问
tux > sudo semanage boolean -l
SELinux boolean                          Description
ftp_home_dir                   -> off   ftp_home_dir
mozilla_read_content           -> off   mozilla_read_content
spamassassin_can_network       -> off   spamassassin_can_network
httpd_can_network_relay        -> off   httpd_can_network_relay
openvpn_enable_homedirs        -> off   openvpn_enable_homedirs
gpg_agent_env_file             -> off   gpg_agent_env_file
allow_httpd_awstats_script_anon_write -> off   allow_httpd_awstats_script_anon_write
httpd_can_network_connect_db   -> off   httpd_can_network_connect_db
allow_ftpd_full_access         -> off   allow_ftpd_full_access
samba_domain_controller        -> off   samba_domain_controller
httpd_enable_cgi               -> off   httpd_enable_cgi
virt_use_nfs                   -> off   virt_use_nfs

在此阶段,可输出有用信息的另一个命令是

tux > sudo semanage fcontext -l

此命令会显示策略提供的默认文件环境设置(有关此命令的部分输出,请参见例 33.4: “获取文件环境信息”)。

例 33.4︰ 获取文件环境信息
tux > sudo semanage fcontext -l
/var/run/usb(/.*)?                                 all files          system_u:object_r:hotplug_var_run_t
/var/run/utmp                                      regular file       system_u:object_r:initrc_var_run_t
/var/run/vbe.*                                     regular file       system_u:object_r:hald_var_run_t
/var/run/vmnat.*                                   socket             system_u:object_r:vmware_var_run_t
/var/run/vmware.*                                  all files          system_u:object_r:vmware_var_run_t
/var/run/watchdog\.pid                             regular file       system_u:object_r:watchdog_var_run_t
/var/run/winbindd(/.*)?                            all files          system_u:object_r:winbind_var_run_t
/var/run/wnn-unix(/.*)                             all files          system_u:object_r:canna_var_run_t
/var/run/wpa_supplicant(/.*)?                      all files          system_u:object_r:NetworkManager_var_run_t
/var/run/wpa_supplicant-global                     socket             system_u:object_r:NetworkManager_var_run_t
/var/run/xdmctl(/.*)?                              all files          system_u:object_r:xdm_var_run_t
/var/run/yiff-[0-9]+\.pid                          regular file       system_u:object_r:soundd_var_run_t

33.6 管理 SELinux

基本 SELinux 配置现在可以正常运行,接下来可以配置 SELinux 来保护您的服务器。SELinux 中使用一组额外的规则来具体定义哪个进程或用户可以访问哪些文件、目录或端口。为此,SELinux 会将一个环境应用到每个文件、目录、进程和端口。此环境是一个安全性标签,定义应如何处理此文件、目录、进程或端口。这些环境标签由 SELinux 策略使用,该策略具体定义应该对环境标签执行什么操作。默认情况下,该策略会阻止所有非默认访问,这意味着,作为管理员,您需要在服务器上启用所有非默认的功能。

33.6.1 查看安全环境

如上文所述,您可以标记文件、目录和端口。每个标签中都使用了不同的环境。要能够执行日常管理工作,您最需要关注的就是类型环境。作为管理员,您基本上要处理的都是类型环境。许多命令允许您使用 -Z 选项列出当前环境设置。例 33.5: “根目录中各目录的默认环境”中显示了根目录中的目录采用了什么环境设置。

例 33.5︰ 根目录中各目录的默认环境
tux > sudo ls -Z
dr-xr-xr-x. root root system_u:object_r:bin_t:s0       bin
dr-xr-xr-x. root root system_u:object_r:boot_t:s0      boot
drwxr-xr-x. root root system_u:object_r:cgroup_t:s0    cgroup
drwxr-xr-x+ root root unconfined_u:object_r:default_t:s0 data
drwxr-xr-x. root root system_u:object_r:device_t:s0    dev
drwxr-xr-x. root root system_u:object_r:etc_t:s0       etc
drwxr-xr-x. root root system_u:object_r:home_root_t:s0 home
dr-xr-xr-x. root root system_u:object_r:lib_t:s0       lib
dr-xr-xr-x. root root system_u:object_r:lib_t:s0       lib64
drwx------. root root system_u:object_r:lost_found_t:s0 lost+found
drwxr-xr-x. root root system_u:object_r:mnt_t:s0       media
drwxr-xr-x. root root system_u:object_r:autofs_t:s0    misc
drwxr-xr-x. root root system_u:object_r:mnt_t:s0       mnt
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mnt2
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mounts
drwxr-xr-x. root root system_u:object_r:autofs_t:s0    net
drwxr-xr-x. root root system_u:object_r:usr_t:s0       opt
dr-xr-xr-x. root root system_u:object_r:proc_t:s0      proc
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 repo
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 root
dr-xr-xr-x. root root system_u:object_r:bin_t:s0       sbin
drwxr-xr-x. root root system_u:object_r:security_t:s0  selinux
drwxr-xr-x. root root system_u:object_r:var_t:s0       srv
-rw-r--r--. root root unconfined_u:object_r:swapfile_t:s0 swapfile
drwxr-xr-x. root root system_u:object_r:sysfs_t:s0     sys
drwxrwxrwt. root root system_u:object_r:tmp_t:s0       tmp
-rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp2.tar
-rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp.tar
drwxr-xr-x. root root system_u:object_r:usr_t:s0       usr
drwxr-xr-x. root root system_u:object_r:var_t:s0       var

在上面的列表中,您可以看到所有目录的完整环境。它由用户、角色和类型组成。s0 设置指示多级别安全环境中的安全性级别。本文不讨论这些环境。在此类环境中,请确保设置了 s0。环境类型定义在目录中允许哪种活动。例如,我们来比较一下环境类型为 admin_home_t/root 目录与环境类型为 home_root_t/home 目录。SELinux 策略中会为这些环境类型定义不同种类的访问。

安全性标签不仅与文件相关联,还与端口和进程等其他项相关联。例如,在例 33.6: “使用 ps Zaux 显示进程的 SELinux 设置”中,您可以看到服务器上进程的环境设置。

例 33.6︰ 使用 ps Zaux 显示进程的 SELinux 设置
tux > sudo ps Zaux
LABEL                           USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
system_u:system_r:init_t        root         1  0.0  0.0  10640   808 ?        Ss   05:31   0:00 init [5]
system_u:system_r:kernel_t      root         2  0.0  0.0      0     0 ?        S    05:31   0:00 [kthreadd]
system_u:system_r:kernel_t      root         3  0.0  0.0      0     0 ?        S    05:31   0:00 [ksoftirqd/0]
system_u:system_r:kernel_t      root         6  0.0  0.0      0     0 ?        S    05:31   0:00 [migration/0]
system_u:system_r:kernel_t      root         7  0.0  0.0      0     0 ?        S    05:31   0:00 [watchdog/0]
system_u:system_r:sysadm_t      root      2344  0.0  0.0  27640   852 ?        Ss   05:32   0:00 /usr/sbin/mcelog --daemon --config-file /etc/mcelog/mcelog.conf
system_u:system_r:sshd_t        root      3245  0.0  0.0  69300  1492 ?        Ss   05:32   0:00 /usr/sbin/sshd -o PidFile=/var/run/sshd.init.pid
system_u:system_r:cupsd_t       root      3265  0.0  0.0  68176  2852 ?        Ss   05:32   0:00 /usr/sbin/cupsd
system_u:system_r:nscd_t        root      3267  0.0  0.0 772876  1380 ?        Ssl  05:32   0:00 /usr/sbin/nscd
system_u:system_r:postfix_master_t root   3334  0.0  0.0  38320  2424 ?        Ss   05:32   0:00 /usr/lib/postfix/master
system_u:system_r:postfix_qmgr_t postfix  3358  0.0  0.0  40216  2252 ?        S    05:32   0:00 qmgr -l -t fifo -u
system_u:system_r:crond_t       root      3415  0.0  0.0  14900   800 ?        Ss   05:32   0:00 /usr/sbin/cron
system_u:system_r:fsdaemon_t    root      3437  0.0  0.0  16468  1040 ?        S    05:32   0:00 /usr/sbin/smartd
system_u:system_r:sysadm_t      root      3441  0.0  0.0  66916  2152 ?        Ss   05:32   0:00 login -- root
system_u:system_r:sysadm_t      root      3442  0.0  0.0   4596   800 tty2     Ss+  05:32   0:00 /sbin/mingetty tty2

33.6.2 选择 SELinux 模式

在 SELinux 中可以使用三种不同的模式:

强制:

这是默认模式。SELinux 根据策略中的规则保护服务器,并将其所有活动记录到审计日志中。

宽松:

此模式用于查错。如果设置为“宽松”,SELinux 将不保护您的服务器,但仍会将发生的所有情况记录到日志文件中。

已禁用:

在此模式下,SELinux 处于完全关闭状态,并且不会记录任何日志,但文件系统标签不会从文件系统中去除。

您已了解如何在引导时使用强制引导参数通过 GRUB 2 设置当前的 SELinux 模式。

33.6.3 修改 SELinux 环境类型

管理员的一项重要工作是设置文件的环境类型,以确保 SELinux 正常工作。

如果在特定的目录中创建了一个文件,该文件默认将继承父目录的环境类型。但是,如果将某个文件从一个位置移到另一个位置,它将保留在原来的位置中所用的环境类型。

要设置文件的环境类型,可以使用 semanage fcontext 命令。使用此命令可将新环境类型写入策略,但不会立即更改实际的环境类型!要应用策略中的环境类型,需要接着运行 restorecon 命令。

使用 semanage fcontext 时的难点在于找出您实际需要的环境。可使用

tux > sudo semanage fcontext -l

列出策略中的所有环境,但从该列表中找出所需的实际环境可能有点困难,因为该列表很长(请参见例 33.7: “查看默认文件环境”)。

例 33.7︰ 查看默认文件环境
tux > sudo semanage fcontext -l | less
SELinux fcontext                                   type               Context

/                                                  directory          system_u:object_r:root_t:s0
/.*                                                all files          system_u:object_r:default_t:s0
/[^/]+                                             regular file       system_u:object_r:etc_runtime_t:s0
/\.autofsck                                        regular file       system_u:object_r:etc_runtime_t:s0
/\.autorelabel                                     regular file       system_u:object_r:etc_runtime_t:s0
/\.journal                                         all files          X:>>None>>
/\.suspended                                       regular file       system_u:object_r:etc_runtime_t:s0
/a?quota\.(user|group)                             regular file       system_u:object_r:quota_db_t:s0
/afs                                               directory          system_u:object_r:mnt_t:s0
/bin                                               directory          system_u:object_r:bin_t:s0
/bin/.*                                            all files          system_u:object_r:bin_t:s0

可以通过三种方式找出您的服务可用的环境设置:

  • 安装服务并查看所用的默认环境设置:这是最简单的做法,也是建议的做法。

  • 查阅特定服务的手册页。某些服务提供了以 _selinux 结尾的手册页,其中包含查找正确环境设置所需的所有信息。

    找到正确的环境设置后,使用 semanage fcontext 应用该设置。此命令接受 -t 环境类型作为第一个参数,后接您要将环境设置应用到的目标目录或文件的名称。要将环境应用到目标目录(要在其中应用该环境)中已存在的所有对象,请将正则表达式 (/.*)? 添加到该目录的名称中。这表示:选择性匹配名称为一个斜线后接任何字符的对象。semanage 手册页的示例部分包含了 semanage 的一些实用的用法示例。有关正则表达式的详细信息,请参见 http://www.regular-expressions.info/ 上的教程及其他资源。

  • 显示系统上所有可用环境类型的列表:

    tux > sudo seinfo -t

    由于仅使用该命令会输出非常多的信息,应将它与 grep 或类似命令结合使用,以过滤结果。

33.6.4 应用文件环境

为帮助您正确应用 SELinux 环境,以下过程说明了如何使用 semanage fcontextrestorecon 设置环境。您会发现,在首次尝试时,具有非默认文档根的 Web 服务器不会工作。更改 SELinux 环境后,它就会正常工作:

  1. 创建 /web 目录,然后对其进行更改:

    tux > sudo mkdir /web  && cd /web
  2. 使用文本编辑器创建包含文本“welcome to my Web site”的 /web/index.html 文件。

  3. 使用编辑器打开 /etc/apache2/default-server.conf 文件,将 DocumentRoot 一行更改为 DocumentRoot /web

  4. 启动 Apache Web 服务器:

    tux > sudo systemctl start apache2
  5. 与您的本地 Web 服务器建立会话:

    tux > w3m localhost

    您会收到连接被拒绝消息。按 Enter,然后按 q 退出 w3m。

  6. 找到默认 Apache DocumentRoot(即 /srv/www/htdocs)的当前环境类型。此类型应当设置为 httpd_sys_content_t

    tux > sudo ls -Z /srv/www
  7. 在策略中设置新环境,然后按 Enter

    tux > sudo semanage fcontext -a -f "" -t httpd_sys_content_t '/web(/.*) ?'
  8. 应用新环境类型:

    tux > sudo restorecon /web
  9. 显示目录 /web 中各文件的环境。您将看到,新环境类型已正确设置到 /web 目录,但未设置到其包含的内容。

    tux > sudo ls -Z /web
  10. 以递归方式将新环境应用到 /web 目录。现已正确设置类型环境。

    tux > sudo restorecon -R /web
  11. 重启动 Web 服务器:

    tux > sudo systemctl restart apache2

    现在,您应该可以访问 /web 目录的内容了。

33.6.5 配置 SELinux 策略

更改策略行为的最简单的方法是使用布尔值。这些布尔值是一些开关,可用来更改策略中的设置。要找出可用的布尔值,请运行

tux > sudo semanage boolean -l

此命令会显示一个较长的布尔值列表,其中简短说明了每个布尔值的作用。找到想要设置的布尔值后,可以使用 setsebool -P 后接您要更改的布尔值的名称。使用 setsebool 时,务必始终使用 -P 选项。此选项会将设置写入到磁盘上的策略文件,这是确保系统重引导后自动应用布尔值的唯一方式。

下面的过程提供了更改布尔设置的示例

  1. 列出与 FTP 服务器相关的布尔值。

    tux > sudo semanage boolean -l | grep ftp
  2. 关闭布尔值:

    tux > sudo setsebool allow_ftpd_anon_write off

    请注意,写入更改不会花费太长时间。然后校验布尔值是否确实关闭:

    tux > sudo semanage boolean -l|grep ftpd_anon
  3. 重引导服务器。

  4. 再次检查以确认 allow_ftpd_anon_write 布尔值是否仍处于开启状态。由于此布尔设置尚未写入策略,因此您会发现它处于关闭状态。

  5. 切换布尔值并将设置写入策略:

    tux > sudo setsebool -P allow_ftpd_anon_write

33.6.6 使用 SELinux 模块

默认情况下,SELinux 使用模块化策略。这意味着,实现 SELinux 功能的策略不是单个巨型策略,而是由许多较小模块构成。每个模块都涉及 SELinux 配置的特定部分。引入 SELinux 模块概念的目的是方便第三方供应商使其服务与 SELinux 兼容。要获取各 SELinux 模块的概览,可以使用 semodule -l 命令。此命令会列出 SELinux 当前使用的所有模块及其版本号。

作为管理员,您可以开启或关闭模块。如果您只想禁用 SELinux 的某个部件(而不是所有部件),以便在不受 SELinux 保护的情况下运行特定的服务,此功能非常有用。尤其是在尚无完全受支持的 SELinux 策略的 SUSE Linux Enterprise Server 中,有效的做法可能是关闭您不需要的所有模块,以便将精力集中在确实需要 SELinux 保护的服务上。要关闭 SELinux 模块,请使用

tux > sudo semodule -d MODULENAME

要再次将它开启,可以使用

tux > sudo semodule -e modulename

要更改任何策略模块文件的内容,请在新策略模块文件中编辑更改。为此,请先安装 selinux-policy-devel 软件包。然后,在 audit2allow 创建的文件所在的目录中,运行:

tux > make -f /usr/share/selinux/devel/Makefile

完成 make 后,可以使用 semodule -i 将模块手动装载到系统中。

33.7 查错

默认情况下,如果 SELinux 是导致出错的原因,系统会将与此结果相关的日志消息发送到 /var/log/audit/audit.log 文件。这涉及到 auditd 服务是否正在运行。如果您发现 /var/log/audit 是空的,请使用以下命令启动 auditd 服务

tux > sudo systemctl start auditd

并使用以下命令在系统目标中启用它

tux > sudo systemctl enable auditd

例 33.8: “/etc/audit/audit.log 中的示例行”中提供了 /var/log/audit/audit.log 的部分示例内容

例 33.8︰ /etc/audit/audit.log 中的示例行
type=DAEMON_START msg=audit(1348173810.874:6248): auditd start, ver=1.7.7 format=raw kernel=3.0.13-0.27-default auid=0 pid=4235 subj=system_u:system_r:auditd_t res=success
type=AVC msg=audit(1348173901.081:292): avc:  denied  { write } for  pid=3426 comm="smartd" name="smartmontools" dev=sda6 ino=581743 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:293): avc:  denied  { remove_name } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:294): avc:  denied  { unlink } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:295): avc:  denied  { rename } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582373 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:296): avc:  denied  { add_name } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:297): avc:  denied  { create } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:298): avc:  denied  { write open } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:299): avc:  denied  { getattr } for  pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.309:300): avc:  denied  { append } for  pid=1316

乍看之下,audit.log 中的行读起来有点困难。但如果仔细分析,就会发现它们不是那么难以理解。每一行都可细分为不同的部分。例如,最后一行包含以下部分:

type=AVC

每个 SELinux 相关审计日志行都以类型标识 type=AVC 开头

msg=audit(1348173901.309:300)

这是时戳,遗憾的是,它是以纪元时间(自 1970 年 1 月 1 日开始经过的秒数)写入的。您可以针对纪元时间表示法中点号前面的部分使用 date -d,以确定该事件是何时发生的:

tux > date -d @1348173901
Thu Sep 20 16:45:01 EDT 2012
avc: denied { append }

已被拒绝的特定操作。在本例中,系统已拒绝将数据追加到文件。在浏览审计日志文件时,您可以看到其他系统操作,例如 write open、getattr 等等。

for pid=1316

发起操作的命令或进程的进程 ID

comm="rsyslogd"

与该 PID 关联的特定命令

name="smartmontools"

操作主体的名称

dev=sda6 ino=582296

相关文件的块设备和 inode 编号

scontext=system_u:system_r:syslogd_t

源环境,即操作发起者的环境

tclass=file

主体的类标识

您可以采用另一种方法来取代在 audit.log 中自行截获事件的做法。您可以使用 audit2allow 命令,它会帮助分析 /var/log/audit/audit.log 中晦涩难懂的日志消息。audit2allow 查错会话一律由三个不同的命令组成。首先,您会使用 audit2allow -w -a 以更易于理解的方式显示审计信息。audit2allow -w -a 默认对 audit.log 文件运行。如果您要分析 audit.log 文件中的特定消息,请将此消息复制到临时文件,然后使用以下命令分析该临时文件:

tux > sudo audit2allow -w -i FILENAME
例 33.9︰ 分析审计消息
tux > sudo audit2allow -w -i testfile
type=AVC msg=audit(1348173901.309:300): avc:  denied  { append } for  pid=1316
comm="rsyslogd" name="acpid" dev=sda6 ino=582296
scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
发生此问题的原因是:

缺少类型强制 (TE) 允许规则。

要生成可装载的模块以允许这种访问,请运行

tux > sudo audit2allow

要确定具体哪条规则拒绝了访问,您可以使用 audit2allow -a 显示已记录到 audit.log 文件的所有事件中的强制规则,或使用 audit2allow -i FILENAME 显示应用于您储存在特定文件中的消息的规则:

例 33.10︰ 查看哪些行拒绝了访问
tux > sudo audit2allow -i testfile
#============= syslogd_t ==============
allow syslogd_t apmd_log_t:file append;

要创建您可以装载以允许先前被拒绝的访问的 SELinux 模块 mymodule,请运行

tux > sudo audit2allow -a -R -M mymodule

如果您要对已记录到 audit.log 的所有事件执行此操作,请使用 -a -M 命令参数。要仅针对特定文件中的特定消息执行此操作,请按下面的示例所示使用 -i -M

例 33.11︰ 创建允许先前被拒绝的操作的策略模块
tux > sudo audit2allow -i testfile -M example
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i example.pp

audit2allow 命令所示,您现在可按以下方式运行此模块:使用 semodule -i 命令,后接 audit2allow 为您创建的模块的名称(在上例中为 example.pp)。