网站搜索

在 Linux 中使用 SELinux 或 AppArmor 实施强制访问控制


为了克服标准 ugo/rwx 权限和访问控制列表的限制并增强其提供的安全机制,美国国家安全局 (NSA) 设计了一种灵活的<强制访问控制 (MAC) 方法称为 SELinux安全增强型 Linux 的缩写),用于限制进程执行以下操作的能力:以尽可能少的权限对系统对象(例如文件、目录、网络端口等)进行访问或执行其他操作,同时仍然允许以后对此模型进行修改。

另一种流行且广泛使用的MAC是AppArmor,它除了SELinux提供的功能之外,还包括一种学习模式,允许系统“学习” ” ”特定应用程序的行为方式,并通过配置安全应用程序使用配置文件来设置限制。

CentOS 7 中,SELinux 被合并到内核本身中,并默认在 Enforcing 模式下启用(下一节将详细介绍),与使用 AppArmoropenSUSEUbuntu 不同。

在本文中,我们将解释 SELinux 和 AppArmor 的要点,以及如何根据您选择的发行版使用这些工具之一来为您带来好处。

SELinux 简介以及如何在 CentOS 7 上使用它

安全增强型 Linux 可以以两种不同的方式运行:

  1. 强制:SELinux 根据 SELinux 策略规则(一组控制安全引擎的准则)拒绝访问。
  2. 宽容:SELinux 不会拒绝访问,但会记录在强制模式下运行时会被拒绝的操作的拒绝。

SELinux 也可以被禁用。尽管它本身不是一种操作模式,但它仍然是一种选择。然而,学习如何使用这个工具比忽略它要好。记在心上!

要显示SELinux的当前模式,请使用getenforce。如果您想切换操作模式,请使用 setenforce 0(将其设置为Permissive)或 setenforce 1Enforcing)。

由于此更改不会在重新启动后继续存在,因此您需要编辑/etc/selinux/config文件并将SELINUX变量设置为enforcingpermissivedisabled 以便在重新启动后实现持久性:

附带说明一下,如果 getenforce 返回“已禁用”,您将必须使用所需的操作模式编辑 /etc/selinux/config 并重新启动。否则,您将无法使用 setenforce 设置(或切换)操作模式。

setenforce 的典型用途之一是在 SELinux 模式之间切换(从 enforcingpermissive 或其他方式)来对应用程序进行故障排除行为不当或未按预期工作。如果将 SELinux 设置为许可模式后它可以正常工作,那么您可以确信您正在解决 SELinux 权限问题。

我们最有可能需要处理 SELinux 的两个典型案例是:

  1. 更改守护程序侦听的默认端口。
  2. /var/www/html 之外的虚拟主机设置 DocumentRoot 指令。

让我们通过以下示例来看看这两种情况。

示例 1:更改 sshd 守护程序的默认端口

大多数系统管理员为了保护服务器的安全所做的第一件事就是更改 SSH 守护程序侦听的端口,主要是为了阻止端口扫描程序和外部攻击者。为此,我们使用 /etc/ssh/sshd_config 中的 Port 指令,后跟新端口号,如下所示(在本例中我们将使用端口 9999):


Port 9999

尝试重新启动服务并检查其状态后,我们将看到它无法启动:


systemctl restart sshd
systemctl status sshd

如果我们查看 /var/log/audit/audit.log,我们将看到 sshd 被阻止在端口 9999 上启动通过 SELinux,因为这是 JBoss Management 服务的保留端口(SELinux 日志消息包含单词 “AVC”,以便可以轻松地从其他消息中识别):


cat /var/log/audit/audit.log | grep AVC | tail -1

此时大多数人可能会禁用 SELinux,但我们不会。我们将看到有一种方法可以让 SELinux 和监听不同端口的 sshd 和谐相处。确保您已安装并运行 policycoreutils-python 软件包:


yum install policycoreutils-python

查看 SELinux 允许 sshd 侦听的端口列表。在下图中我们还可以看到端口9999被保留给另一个服务,因此我们暂时不能使用它来运行另一个服务:


semanage port -l | grep ssh

当然,我们可以为 SSH 选择另一个端口,但如果我们确定不需要使用该特定机器来执行任何 JBoss 相关服务,则可以修改现有的 SELinux 规则并将该端口分配给 SSH:


semanage port -m -t ssh_port_t -p tcp 9999

之后,我们可以使用第一个semanage命令来检查端口是否已正确分配,或者使用-lC选项(list custom的缩写):


semanage port -lC
semanage port -l | grep ssh

我们现在可以重新启动 SSH 并使用端口 9999 连接到该服务。请注意,此更改将在重新启动后保留。

示例 2:为虚拟主机选择 /var/www/html 之外的 DocumentRoot

如果您需要使用 /var/www/html 以外的目录作为 DocumentRoot 来设置 Apache 虚拟主机(例如,/websrv/sites /gabriel/public_html):


DocumentRoot “/websrv/sites/gabriel/public_html”

Apache 将拒绝提供内容,因为 index.html 已被标记为 default_t SELinux 类型,Apache 无法访问该类型:


wget http://localhost/index.html
ls -lZ /websrv/sites/gabriel/public_html/index.html

与前面的示例一样,您可以使用以下命令来验证这确实是与 SELinux 相关的问题:


cat /var/log/audit/audit.log | grep AVC | tail -1

要将 /websrv/sites/gabriel/public_html 的标签递归更改为 httpd_sys_content_t,请执行以下操作:


semanage fcontext -a -t httpd_sys_content_t "/websrv/sites/gabriel/public_html(/.*)?"

上述命令将授予 Apache 对该目录及其内容的只读访问权限。

最后,要应用该策略(并使标签更改立即生效),请执行以下操作:


restorecon -R -v /websrv/sites/gabriel/public_html

现在您应该能够访问该目录:


wget http://localhost/index.html

有关 SELinux 的更多信息,请参阅 Fedora 22 SELinux 和管理员指南。