简介
安全增强型Linux或SELinux是大多数现代Linux发行版中内置的高级访问控制机制。它最初是由美国国家安全局开发的,目的是保护计算机系统免受恶意入侵和篡改。随着时间的推移,SELinux在公共领域发布,自那以后各种发行版都将其包含在他们的代码中。
许多系统管理员发现SELinux在某种程度上是一个未知领域。这个话题可能看起来令人望而生畏,有时也相当令人困惑。但是,正确配置的SELinux系统可以极大地降低安全风险,对其略知一二可以帮助您排除与访问相关的错误消息。在本教程中,我们将了解SELinux背后的概念-它的包、命令和配置文件-以及当访问被拒绝时它记录的错误消息。我们还将看到一些将SELinux付诸实施的实际例子。
注意事项 本教程中展示的命令、包和文件在CentOS 7上进行了测试。其他发行版的概念保持不变。
在本教程中,除非另有说明,否则我们将以根用户身份运行命令。如果您无权访问超级用户帐户并使用其他具有sudo权限的帐户,则需要在命令前添加关键字sudo
。
为什么选择SELinux
在我们开始之前,让我们先了解几个概念。
SELinux实现了所谓的MAC (强制访问控制)。这是在每个Linux发行版中已有的** DAC** (自主访问控制)的基础上实现的。
为了理解DAC,我们首先来看看传统的Linux文件安全是如何工作的。
在传统的安全模型中,我们有三个实体:用户、组和其他(u、g、o)实体,他们可以对文件或目录拥有读、写和执行(r,w,x)权限。如果用户Jo 在其主目录中创建了一个文件,则该用户将拥有该文件的读/写访问权限,** Jo** 组也是如此。其他
实体可能无法访问它。在下面的代码块中,我们可以考虑Jo的主目录的假设内容。
您不需要设置这个Jo 用户--我们将在本教程的后面部分设置大量用户。
运行如下命令:
1ls -l /home/jo/
可以显示如下所示的输出:
1total 4
2-rwxrw-r--. 1 jo jo 41 Aug 6 22:45 myscript.sh
现在jo可以更改此访问权限。jo可以授予(和限制)其他用户和组对该文件的访问权,或者更改该文件的所有者。这些操作可能会将关键文件暴露给不需要此访问权限的帐户。jo也可以进行限制以提高安全性,但这是可以自由决定的:系统管理员无法对系统中的每个文件强制执行它。
考虑另一种情况:当Linux进程运行时,它可能以根用户或具有超级用户权限的其他帐户运行。这意味着,如果黑帽黑客控制了应用程序,他们就可以使用该应用程序访问用户帐户有权访问的任何资源。对于以根用户身份运行的进程,这基本上意味着Linux服务器中的所有内容。
考虑这样一种场景,您想要限制用户从其主目录执行外壳脚本。当您让开发人员在生产系统上工作时,可能会发生这种情况。您希望他们查看日志文件,但不希望他们使用su
或sudo
命令,也不希望他们从自己的主目录运行任何脚本。你怎么做到的?
SELinux是微调此类访问控制要求的一种方式。使用SELinux,您可以定义用户或进程可以执行的操作。它将每个进程限制在其自己的域中,以便该进程只能与某些类型的文件和来自允许域的其他进程进行交互。这可以防止黑客劫持任何进程以获得系统范围的访问权限。
设置测试系统
为了帮助我们学习这些概念,我们将构建一台同时运行Web和SFTP服务器的测试服务器。我们将从安装了最小程序包的CentOS7裸露安装开始,并在该服务器上安装Apache和vsftp守护进程。但是,我们不会配置这两个应用程序中的任何一个。
我们还将在云服务器中创建一些测试用户帐户。在整个课程中,我们将在不同的地方使用这些帐户。
最后,我们将安装所需的SELinux相关软件包。这是为了确保我们可以使用最新的SELinux命令。
安装APACHE和SFTP服务
首先,让我们以根用户 的身份登录到服务器,并运行以下命令来安装APACHE:
1yum install httpd
输出将显示正在下载的程序包,并询问您是否允许安装:
1Loaded plugins: fastestmirror, langpacks
2...
3...
4================================================================================
5 Package Arch Version Repository Size
6================================================================================
7Installing:
8 httpd x86_64 2.4.6-18.el7.centos updates 2.7 M
9
10Transaction Summary
11================================================================================
12Install 1 Package
13
14Total download size: 2.7 M
15Installed size: 9.3 M
16Is this ok [y/d/N]:
按y 将安装ApacheWeb服务器守护程序。
1Downloading packages:
2httpd-2.4.6-18.el7.centos.x86_64.rpm | 2.7 MB 00:01
3Running transaction check
4Running transaction test
5Transaction test succeeded
6Running transaction
7 Installing : httpd-2.4.6-18.el7.centos.x86_64 1/1
8 Verifying : httpd-2.4.6-18.el7.centos.x86_64 1/1
9
10Installed:
11 httpd.x86_64 0:2.4.6-18.el7.centos
12
13Complete!
手动启动守护程序:
1service httpd start
运行service httpd status
命令将显示该服务正在运行:
1Redirecting to /bin/systemctl status httpd.service
2httpd.service - The Apache HTTP Server
3 Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
4 Active: active (running) since Tue 2014-08-19 13:39:48 EST; 1min 40s ago
5 Main PID: 339 (httpd)
6...
7...
接下来我们将安装vsftp:
1yum install vsftpd
输出应如下所示:
1Loaded plugins: fastestmirror, langpacks
2...
3...
4==============================================================================================================
5 Package Arch Version Repository Size
6==============================================================================================================
7Installing:
8 vsftpd x86_64 3.0.2-9.el7 base 165 k
9
10Transaction Summary
11==============================================================================================================
12Install 1 Package
13
14Total download size: 165 k
15Installed size: 343 k
16Is this ok [y/d/N]:
按y 安装程序包。
接下来,我们将使用service vsftpd start
命令启动vsftpd守护进程。输出应显示如下所示:
1Redirecting to /bin/systemctl status vsftpd.service
2vsftpd.service - Vsftpd ftp daemon
3 Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled)
4 Active: active (running) since Tue 2014-08-19 13:48:57 EST; 4s ago
5 Process: 599 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
6 Main PID: 600 (vsftpd)
7...
8...
安装SELinux程序包
SELinux中使用了许多程序包。有些是默认安装的。以下是基于Red Hat的发行版的列表:
- Policy coreutils(提供管理SELinux的实用程序)
- Policy coreutils-python(提供管理SELinux的实用程序)
- selinux-POLICY(提供SELinux参考策略)
- selinux-POLICATE-TARGLED(提供SELinux目标策略)
- libselinux-utils(提供了一些管理SELinux的工具)
- setroubl疑难解答-服务器(提供用于解密审核日志消息的工具)
- setools(提供审计日志监控、查询策略、文件上下文管理工具)
- setools-控制台(提供审计日志监控、查询策略、文件上下文管理等工具)
- mcstrans(将不同级别转换为易于理解的格式的工具)
其中一些已经安装好了。要查看您的CentOS 7系统上安装了哪些SELinux包,您可以以根用户身份运行如下命令(grep
后有不同的搜索词):
1rpm -qa | grep selinux
输出应如下所示:
1libselinux-utils-2.2.2-6.el7.x86_64
2libselinux-2.2.2-6.el7.x86_64
3selinux-policy-targeted-3.12.1-153.el7.noarch
4selinux-policy-3.12.1-153.el7.noarch
5libselinux-python-2.2.2-6.el7.x86_64
您可以使用下面的命令继续安装所有包(yum将只更新您已有的所有包),或者只安装您发现系统中缺少的包:
1yum install policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans
现在,我们应该拥有一个加载了所有SELinux包的系统。我们也有使用其默认配置运行的Apache和SFTP服务器。除了根 帐户外,我们还有四个常规用户帐户可供测试。
SELinux模式
现在是开始使用SELinux的时候了,所以让我们从SELinux模式开始。在任何时候,SELinux都可以处于三种可能的模式中的任何一种:
- 强制执行
- 宽大
- 已禁用
在强制模式下,SELinux将在Linux系统上强制执行其策略,并确保拒绝用户和进程的任何未经授权的访问尝试。访问拒绝也会写入相关的日志文件。我们稍后将讨论SELinux策略和审核日志。
许可模式类似于半启用状态。SELinux不会在许可模式下应用其策略,因此不会拒绝任何访问。但是,任何违反策略的行为仍会记录在审核日志中。这是在强制执行SELinux之前测试它的好方法。
禁用模式是不言而喻的-系统将不会以增强的安全性运行。
检查SELinux模式和状态
我们可以运行getenforce
命令来检查当前的SELinux模式。
1getenforce
SELinux当前应该被禁用,因此输出将如下所示:
1Disabled
我们还可以运行sestatus
命令:
1sestatus
当SELinux被禁用时,输出将显示:
1SELinux status: disabled
SELinux配置文件
SELinux的主要配置文件是/etc/selinux/config。我们可以运行以下命令来查看其内容:
1cat /etc/selinux/config
输出将如下所示:
1# This file controls the state of SELinux on the system.
2# SELINUX= can take one of these three values:
3# enforcing - SELinux security policy is enforced.
4# permissive - SELinux prints warnings instead of enforcing.
5# disabled - No SELinux policy is loaded.
6SELINUX=disabled
7# SELINUXTYPE= can take one of these two values:
8# targeted - Targeted processes are protected,
9# minimum - Modification of targeted policy. Only selected processes are protected.
10# mls - Multi Level Security protection.
11SELINUXTYPE=targeted
该文件中有两条指令。SELINUX指令规定了SELinux模式,如前所述,它可以有三个可能的值。
SELINUXTYPE指令确定将使用的策略。默认值为Targeted
。通过有针对性的策略,SELinux允许您自定义和微调访问控制权限。另一个可能的价值是),这是一种高级保护模式。对于MLS,您还需要安装一个额外的程序包。
SELinux开启和关闭
启用SELinux相当简单;但与禁用它不同,应该分两步完成。我们假设当前禁用了SELinux,并且您已经安装了前面部分中的所有SELinux包。
第一步,我们需要编辑/etc/selinux/config
文件,将SELINUX指令更改为许可模式。
1vi /etc/sysconfig/selinux
1...
2SELINUX=permissive
3...
首先将状态设置为PERMISSIVE 是必要的,因为系统中的每个文件都需要标记其上下文才能强制执行SELinux。除非正确标记所有文件,否则在受限域中运行的进程可能会失败,因为它们无法访问具有正确上下文的文件。这可能会导致启动过程失败或启动时出现错误。我们将在本教程的后面介绍_CONTEXTS_和_DOMAIN_。
现在发出系统重新启动命令:
1reboot
重新启动过程将看到服务器中标有SELinux上下文的所有文件。由于系统在允许模式下运行,SELinux错误和访问拒绝将被报告,但它不会停止任何操作。
再次以超级用户身份 登录到您的服务器。接下来,从/var/log/Messages文件的内容中搜索字符串SELinux正在阻止
。
1cat /var/log/messages | grep "SELinux is preventing"
如果没有报告错误,我们可以安全地进入下一步。但是,在/var/log/Messages文件中搜索包含SELinux
的文本仍然是一个好主意。在我们的系统中,我们运行了以下命令:
1cat /var/log/messages | grep "SELinux"
这显示了一些与正在运行的GNOME桌面相关的错误消息。当SELInux被禁用或处于允许模式时,会发生这种情况:
1Aug 20 11:31:14 localhost kernel: SELinux: Initializing.
2Aug 20 11:31:16 localhost kernel: SELinux: Disabled at runtime.
3Aug 20 11:31:21 localhost journal: Unable to lookup SELinux process context: Invalid argument
4Aug 20 11:33:20 localhost gnome-session: SELinux Troubleshooter: Applet requires SELinux be enabled to run.
5
6Aug 20 11:37:15 localhost kernel: SELinux: Initializing.
7Aug 20 11:37:17 localhost kernel: SELinux: Disabled at runtime.
8Aug 20 11:37:23 localhost journal: Unable to lookup SELinux process context: Invalid argument
9Aug 20 11:37:44 localhost gnome-session: SELinux Troubleshooter: Applet requires SELinux be enabled to run.
10
11Aug 20 11:39:42 localhost kernel: SELinux: Initializing.
12Aug 20 11:39:44 localhost kernel: SELinux: Disabled at runtime.
13Aug 20 11:39:50 localhost journal: Unable to lookup SELinux process context: Invalid argument
这些类型的错误是可以接受的。
在第二阶段,我们需要编辑配置文件,将/etc/sysconfig/selinux
文件中的SELINUX指令从PERMISSIVE 改为** ENCENTING** :
1...
2SELINUX=enforcing
3...
接下来,再次重新启动服务器。
1reboot
一旦服务器恢复在线,我们就可以运行sestatus
命令来检查SELinux状态。它现在应该会显示有关服务器的更多详细信息:
1SELinux status: enabled
2SELinuxfs mount: /sys/fs/selinux
3SELinux root directory: /etc/selinux
4Loaded policy name: targeted
5Current mode: permissive
6Mode from config file: error (Success)
7Policy MLS status: enabled
8Policy deny_unknown status: allowed
9Max kernel policy version: 28
查看/var/log/messages文件:
1cat /var/log/messages | grep "SELinux"
不应该有任何错误。输出应该类似于以下内容:
1Aug 20 11:42:06 localhost kernel: SELinux: Initializing.
2Aug 20 11:42:09 localhost systemd[1]: Successfully loaded SELinux policy in 183.302ms.
3
4Aug 20 11:44:25 localhost kernel: SELinux: Initializing.
5Aug 20 11:44:28 localhost systemd[1]: Successfully loaded SELinux policy in 169.039ms.
再次检查SELinux模式和状态
我们可以运行getenforce
命令来检查当前的SELinux模式。
1getenforce
如果我们的系统在强制模式下运行,输出将如下所示:
1Enforcing
如果SELinux被禁用,输出将有所不同:
1Disabled
我们还可以运行`sestatus‘命令来获得更好的图像。
1sestatus
如果SELinux未被禁用,则输出将显示其当前状态、当前模式、配置文件中定义的模式和策略类型。
1SELinux status: enabled
2SELinuxfs mount: /sys/fs/selinux
3SELinux root directory: /etc/selinux
4Loaded policy name: targeted
5Current mode: enforcing
6Mode from config file: enforcing
7Policy MLS status: enabled
8Policy deny_unknown status: allowed
9Max kernel policy version: 28
当SELinux被禁用时,输出将显示:
1SELinux status: disabled
我们还可以使用setenforce
命令在强制和允许模式之间临时切换。(请注意,当SELinux关闭时,我们不能运行setenforce
。)
首先,在我们的CentOS 7系统中,将SELinux模式从强制更改为允许:
1setenforce permissive
现在运行sestatus
命令,会发现当前模式与配置文件中定义的模式不同:
1SELinux status: enabled
2SELinuxfs mount: /sys/fs/selinux
3SELinux root directory: /etc/selinux
4Loaded policy name: targeted
5Current mode: permissive
6Mode from config file: enforcing
7Policy MLS status: enabled
8Policy deny_unknown status: allowed
9Max kernel policy version: 28
切换回强制执行 :
1setenforce enforcing
SELinux策略
SELinux安全引擎的核心是ITS_POLICY。策略顾名思义:定义系统中所有内容的安全和访问权限的一组规则。当我们说一切
时,我们指的是用户、角色、流程和文件。该策略定义了这些实体中的每一个如何相互关联。
一些基本术语
要理解政策,我们必须学习一些基本术语。我们将在稍后详细介绍,但这里有一个简短的介绍。SELinux策略定义了用户对角色的访问、角色对域的访问以及域对类型的访问。
用户
SELinux有一组预置的用户。每个常规Linux用户帐户都映射到一个或多个SELinux用户。
在Linux中,用户运行一个进程。这可以很简单,只需用户Jo 在vi编辑器中打开文档(它将是运行vi进程的Jo的帐户)或运行HTTPD守护进程的服务帐户。在SELinux世界中,进程(守护进程或正在运行的程序)称为a_Subject_。
角色
角色就像位于用户和进程之间的网关。角色定义哪些用户可以访问该流程。角色不像组,而更像筛选器:只要角色授予角色,用户就可以随时输入或承担角色。SELinux策略中的角色定义定义了哪些用户有权访问该角色。它还定义了角色本身有权访问的流程域。角色之所以发挥作用,是因为SELinux的一部分实现了被称为基于角色的访问控制 (RBAC)。
主客体
A_SUBJECT_是一个进程,可能会潜在地影响AN_OBJECT_。
在SELinux中,AN_OBJECT_是可以执行的任何操作。它可以是文件、目录、端口、TCP套接字、游标,也可以是X服务器。主体可以对对象执行的操作是主体的权限。
域名用于主题
A_DOMAIN_是SELinux主体(进程)可以在其中运行的上下文。这一背景就像是对主题的包装。它告诉流程它能做什么和不能做什么。例如,域将定义主体可以访问哪些文件、目录、链接、设备或端口。
类型针对对象
A_TYPE_是规定文件用途的文件上下文的上下文。例如,文件的上下文可能指示它是一个网页,或者该文件属于/etc
目录,或者该文件的所有者是特定的SELinux用户。文件的上下文在SELinux行话中称为ITS_TYPE_。
什么是SELinux策略?
SELinux策略定义了用户对角色的访问、角色对域的访问以及域对类型的访问。首先,必须授权用户才能输入角色,然后才能授权该角色访问该域。而该域又被限制为只能访问某些类型的文件。
策略本身是一堆规则,规定某某用户只能承担某某角色,而这些角色将被授权只能访问某某域。域反过来只能访问某某文件类型。下图显示了该概念:
术语提示:在特定域中运行的进程只能对特定类型的对象执行特定操作的最后一步称为_类型强制_(TE)。
回到策略的主题,SELinux策略实现在默认情况下也通常是目标的。如果您还记得我们之前看到的SELinux配置文件,那么SELINUXTYPE指令被设置为`Target‘。这意味着,在默认情况下,SELinux将仅限制系统中的某些进程(即仅针对某些进程)。未被锁定的病毒将在不受限的域中运行。
另一种选择是默认拒绝模式,在该模式下,除非策略批准,否则拒绝所有访问。这将是一个非常安全的实现,但这也意味着开发人员必须预测每个进程在每个可能的对象上可能需要的每一个可能的权限。根据默认行为,SELinux仅与某些进程相关。
SELinux策略行为
SELinux策略不能取代传统的DAC安全。如果DAC规则禁止用户访问文件,则不会评估SELinux策略规则,因为第一道防线已经阻止了访问。SELinux安全决策在DAC安全评估后生效。
当启用了SELinux的系统启动时,策略将加载到内存中。SELinux策略采用模块化格式,非常类似于在引导时加载的内核模块。就像内核模块一样,它们可以在运行时动态地从内存中添加和删除。SELinux使用的_POLICY STORE_跟踪已加载的模块。sestatus
命令显示策略存储名称。Semodule-l
命令列出当前加载到内存中的SELinux策略模块。
要了解这一点,让我们运行Semodule
命令:
1semodule -l | less
输出将如下所示:
1abrt 1.2.0
2accountsd 1.0.6
3acct 1.5.1
4afs 1.8.2
5aiccu 1.0.2
6aide 1.6.1
7ajaxterm 1.0.0
8alsa 1.11.4
9amanda 1.14.2
10amtu 1.2.3
11anaconda 1.6.1
12antivirus 1.0.0
13apache 2.4.0
14...
15...
Semodule
可以用于安装、删除、重载、升级、启用和禁用SELinux策略模块等其他任务。
到目前为止,您可能有兴趣知道模块文件的位置。大多数现代发行版都将这些模块的二进制版本作为SELinux包的一部分。策略文件的扩展名为.pp。对于CentOS 7,我们可以运行以下命令:
1ls -l /etc/selinux/targeted/modules/active/modules/
该清单显示了许多扩展名为.pp
的文件。如果仔细观察,它们将与不同的应用程序相关:
1...
2-rw-r--r--. 1 root root 10692 Aug 20 11:41 anaconda.pp
3-rw-r--r--. 1 root root 11680 Aug 20 11:41 antivirus.pp
4-rw-r--r--. 1 root root 24190 Aug 20 11:41 apache.pp
5-rw-r--r--. 1 root root 11043 Aug 20 11:41 apcupsd.pp
6...
不过,这些.pp
文件不是人类可读的。
SELinux模块化的工作方式是,当系统引导时,策略模块被组合成所谓的活动策略。然后将该策略加载到内存中。该加载策略的组合二进制版本可以在/etc/selinux/Target/Policy
目录下找到。
1ls -l /etc/selinux/targeted/policy/
将显示活动策略。
1total 3428
2-rw-r--r--. 1 root root 3510001 Aug 20 11:41 policy.29
更改SELinux布尔设置
虽然您不能读取策略模块文件,但有一种简单的方法可以调整它们的设置。这是通过SELinux_boolans_完成的。
要了解它是如何工作的,让我们运行Semanage boolean-l
命令。
1semanage boolean -l | less
它显示了可以打开或关闭的不同开关、它们的功能以及它们的当前状态:
1ftp_home_dir (off , off) Allow ftp to home dir
2smartmon_3ware (off , off) Allow smartmon to 3ware
3mpd_enable_homedirs (off , off) Allow mpd to enable homedirs
4xdm_sysadm_login (off , off) Allow xdm to sysadm login
5xen_use_nfs (off , off) Allow xen to use nfs
6mozilla_read_content (off , off) Allow mozilla to read content
7ssh_chroot_rw_homedirs (off , off) Allow ssh to chroot rw homedirs
8mount_anyfile (on , on) Allow mount to anyfile
9...
10...
我们可以看到,第一个选项允许ftp守护进程访问用户的主目录。此时设置已关闭。
要更改任何设置,我们可以使用setsebool
命令。作为一个例子,让我们考虑匿名的FTP写访问:
1getsebool ftpd_anon_write
这向我们表明,此时开关处于关闭状态:
1ftpd_anon_write --> off
接下来,我们更改布尔值以启用它:
1setsebool ftpd_anon_write on
再次检查该值应该会显示更改:
1ftpd_anon_write --> on
改变的布尔值不是永久性的。它们在重新启动后恢复为其旧值。要使其成为永久性的,我们可以使用带有setsebool
命令的-P开关。
结论
在本教程的第一部分中,我们尝试了解有关SELinux的一些基本概念。我们已经看到了SELinux如何保护一个系统,我们如何启用它,以及它可以在什么模式下运行。我们还谈到了SELinux政策的话题。接下来,我们将学习如何使用SELINX来限制对文件和processes.的访问