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