在 Linux 中使用 SELinux 或 AppArmor 实现强制访问控制
ugo/rwx
为了克服标准权限和访问控制列表的局限性并提高其提供的安全机制,美国国家安全局(NSA) 设计了一种灵活的强制访问控制(MAC) 方法,称为SELinux(安全增强型 Linux的缩写),目的在于限制进程对系统对象(如文件、目录、网络端口等)的访问或执行其他操作的能力,使其具有尽可能最小的权限,同时仍允许对该模型进行以后的修改。
另一个流行且广泛使用的 MAC 是AppArmor,除了SELinux提供的功能外,它还包括一种学习模式,允许系统“学习”特定应用程序的行为方式,并通过配置配置文件来设置限制以确保应用程序的安全使用。
在CentOS 7中,SELinux被整合到内核本身中,并且默认以强制模式启用(下一节将详细介绍),而openSUSE和Ubuntu则使用AppArmor。
在本文中,我们将讲解 SELinux 和 AppArmor 的基本知识,以及如何根据您选择的发行版使用其中一种工具为您带来好处。
SELinux 简介以及如何在 CentOS 7 上使用它
安全增强型 Linux 可以采用两种不同的方式运行:
- 执行:SELinux 根据 SELinux 策略规则(一组控制安全引擎的准则)拒绝访问。
- 宽容:SELinux 不会拒绝访问,但会记录在强制模式下运行时会被拒绝的操作。
SELinux 也可以被禁用。虽然它本身不是一种操作模式,但它仍然是一个选项。不过,学会如何使用这个工具总比直接忽略它要好。记住它!
要显示SELinux的当前模式,请使用getenforce
。如果要切换操作模式,请使用setenforce 0
(将其设置为Permissive)或setenforce 1
(Enforcing)。
由于此更改在重新启动后将不再有效,因此您需要编辑/etc/selinux/config文件并将SELINUX变量设置为enforcing
、permissive
或 ,disabled
以实现重新启动后的持久性:
附注:如果getenforce
返回“已禁用”,则必须使用所需操作模式编辑/etc/selinux/config并重新启动。否则,您将无法使用 设置(或切换)操作模式setenforce
。
的典型用途之一setenforce
是在 SELinux 模式之间切换(从强制到宽容或从宽容到强制),以排除行为不当或未按预期运行的应用程序故障。如果在将 SELinux 设置为宽容模式后,它正常工作,则可以确信您正在查看 SELinux 权限问题。
我们最有可能需要处理 SELinux 的两个典型案例是:
- 更改守护进程监听的默认端口。
- 为/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,我们会看到SELinux阻止sshd在端口9999上启动,因为这是JBoss 管理服务的保留端口(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 (例如/websrv/sites/gabriel/public_html )来设置 Apache 虚拟主机:
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 和管理员指南。