SELinux 入门:理解 Linux 中的强制访问控制与安全策略

一、概述

我们通常依靠传统的安全措施,如强密码、权限设置和防火墙来保护Linux系统。但有时,我们需要更精细的控制,比如管理进程可能执行的操作。这时候,SELinux(安全增强型Linux)就派上用场了。

SELinux最初由美国国家安全局(NSA)开发,后来发布给开源社区。它让系统管理员能够定义特定的访问策略,以控制进程和用户与系统资源的交互方式。

在本教程中,我们将探讨SELinux是什么、它如何工作以及它的重要性。

二、SELinux到底是什么?

SELinux是一个内置于Linux内核的安全模块,它在常规的Unix风格权限系统之外提供额外的访问控制。它在防范权限提升、配置错误和零日漏洞攻击方面发挥着关键作用。

在安全性至关重要的环境中,SELinux的作用尤为突出。无论是运行Web服务器、数据库还是容器化应用,SELinux都可能决定威胁是被遏制还是导致整个系统沦陷。

要真正理解SELinux,了解它与标准Linux安全模型的区别是很有必要的。

1. 传统权限(DAC)存在的问题

在Linux中,自主访问控制(DAC)就是那些控制谁可以对文件执行何种操作的“读-写-执行”权限,它们构成了标准的安全层。简单来说,文件或进程的所有者可以决定谁能获得访问权限。

虽然这种方式很灵活,但它也可能成为一个薄弱环节。如果恶意程序设法获得了控制权,它或许能够利用这些自主权限扩大破坏范围。

例如,若一个用户拥有某个脚本,该用户可以决定谁能执行这个脚本。如果特权用户(如root)或被入侵的进程获得了控制权,它就有可能访问或修改系统上的任何资源。传统上,root用户可以绕过DAC检查。

2. 强制访问控制(MAC)的解决方案

SELinux带来的重大转变在于它改变了访问控制的工作方式。大多数管理员和用户都非常熟悉DAC,在这种机制下,文件所有者有决定权。而SELinux则向内核中添加了MAC。

在MAC机制下,是操作系统(而非单个用户)严格执行由管理员定义的系统级安全策略。每一个系统调用、每一次访问尝试,都会依据这一策略进行检查。

更重要的是,即便是root用户也必须遵守该策略。如果root用户的操作超出了已定义的策略范围,SELinux可以对其进行限制。换句话说,这是一种更为严格的安全机制。我们可以阻止对文件、进程和资源的未授权访问或修改,即便是来自超级用户账户的操作也不例外。

3. 默认拒绝原则

SELinux的MAC方法遵循默认拒绝原则。

简而言之,如果SELinux规则没有明确允许某项特定操作或访问,那么该操作或访问将被自动拒绝。这种“默认拒绝”的立场本身就通过减少攻击面提供了极大的安全优势。

4. MAC与DAC如何相辅相成

SELinux并不会取代由chmod或chown管理的基本文件权限,相反,它以特定的顺序与这些权限协同工作,提供更深入且强制性的控制。

当一个进程试图访问某个文件时,系统会首先检查DAC策略规则。只有当这些基本权限允许访问时,SELinux才会介入并评估其安全策略(MAC)。

这一顺序意味着SELinux扮演着第二个检查点的角色。这为那些DAC级别可能过于宽松,或者被入侵的进程设法绕过DAC的场景提供了额外保护。

三、SELinux核心

启用SELinux的系统依靠关键的安全概念来指导访问决策。让我们看看这些原则如何增强Linux系统的安全性。

1. 安全上下文(标签)

SELinux会为系统上的每个文件、用户和进程分配一个安全上下文(也称为安全标签)。这个上下文或标签是一组属性,SELinux用它来确定访问权限。简单来说,这些标签就像是“名称标签”,表明哪些操作是允许的,哪些是不允许的。

安全上下文由四个部分组成(用户:角色:类型:级别)。下面我们来看看每个部分的作用:

用户:映射到一个或多个Linux用户,并定义用户可以承担哪些角色,例如user_u或unconfined_u(与操作系统用户不同)角色:限制特定用户或类型可以执行的操作,定义被分配到某个角色的用户可以访问哪些类型(SELinux分配的角色名称带有_r后缀,如system_r)类型:进程的域和文件的类型,它定义了进程和文件之间如何交互(所有文件和运行中的进程都被分配一个以_t结尾的类型,例如,Web服务器进程的类型是httpd_t,/var目录中文件的类型是var_t)级别(可选):多级安全(MLS)系统中的 clearance 级别范围,用于设置敏感级别,如s0或s1

现在,我们在包含文件的目录上运行ls -Z命令,看看安全上下文的一些示例:

复制
$ ls -Z -rw-------. root root system_u:object_r:httpd_sys_content_t:s0 index.html drwxrwxrwx. root root unconfined_u:object_r:admin_home_t:s0 backup1.2.3.

在这里,该命令列出了文件的所有者(root)以及其读写执行权限。此外,-Z选项还包含了每个条目的安全上下文的四个部分(用户、角色、类型和安全级别),例如system_u:object_r:httpd_sys_content_t:s0。

2. 策略规则

SELinux使用策略模块来定义每个进程可以执行的操作。每一个可能的操作(例如X类型的进程读取Y类型的文件)都需要有明确的规则允许,否则SELinux会拒绝该操作。正如我们前面提到的,SELinux默认禁止所有操作,除非明确允许。

例如,一条策略规则可能会规定“允许httpd_t进程读取httpd_sys_content_t文件”。如果我们尝试执行规则中未涵盖的操作,SELinux会阻止该操作并记录拒绝信息。

设置策略规则时,我们需要遵循基本语法:

复制
<规则类型> <主体> <对象>:<对象类别> <权限>;1.

下面我们来分解每个部分的含义:

规则类型:SELinux应采取的操作,通常是allow(允许)、dontaudit(不审计)或neverallow(从不允许)主体:请求访问的进程的域或类型对象:被访问资源的类型对象类别:对象的类别,如file(文件)、dir(目录)、tcp_socket(TCP套接字)权限:被允许的操作,如read(读取)、write(写入)、open(打开)

例如,我们可以看一个简单的策略规则示例:

复制
ALLOW apache_process apache_log:FILE READ;1.

这条规则简单地允许标有apache_process标签的进程读取标有apache_log标签的日志文件。

3. 布尔值

如果我们想在不编辑安全策略的情况下关闭一条规则,该怎么办呢?

SELinux布尔值是一个开关,它允许在不重写整个SELinux策略的情况下改变规则的行为。例如,一个常见的布尔值是httpd_can_network_connect。默认情况下,它可能是关闭的,因此Web服务器(httpd_t)不能建立出站网络连接。

让我们看看如何使用setsebool命令将其开启:

复制
$ setsebool -P httpd_can_network_connect on1.

通过将上述布尔值设置为on,SELinux允许相应的访问,而无需修改策略文件。此外,我们可以使用等效的数值0-1来代替on-off选项。

实际上,SELinux自带了许多这样的布尔值,用于控制诸如允许FTP写入访问、使用NFS等操作,以便在运行时调整规则。我们可以使用getsebool -a命令列出所有规则:

复制
$ getsebool -a | less abrt_anon_write --> off abrt_handle_event --> off abrt_upload_watch_anon_write --> on antivirus_can_scan_system --> off antivirus_use_jit --> off auditadm_exec_content --> on authlogin_nsswitch_use_ldap --> off authlogin_radius --> off authlogin_yubikey --> off awstats_purge_apache_log_files --> off :1.2.3.4.5.6.7.8.9.10.11.12.

这里,输出内容可能很长,所以最好将其通过管道传输到less命令,以便逐页滚动查看。

4. 模式

SELinux可以在三种模式下运行,每种模式提供不同级别的安全控制:

enforcing(强制模式)(0):主动阻止违规行为permissive(宽容模式)(1):记录违规行为但不阻止disabled(禁用模式):完全关闭SELinux,系统退回到正常的DAC权限

我们可以使用getenforce命令检查当前的SELinux模式:

复制
$ getenforce Enforcing1.2.

在这种情况下,SELinux处于强制模式。

现在,我们使用setenforce命令将其切换到宽容模式:

复制
$ setenforce 01.

这里的0是宽容模式的模式ID。相反,1是强制模式的ID。

值得注意的是,setenforce命令的设置在重启后不会保留。不过,我们可以直接编辑SELinux配置文件(/etc/selinux/config)来使更改持久化。此外,编辑该配置文件也是切换到禁用模式的方法。

四、为什么SELinux很重要?

看起来Linux的文件权限(读、写、执行)和用户所有权应该足以保证系统的安全。当然,对于简单的设置来说,通常确实如此。但是,一旦我们运行复杂的面向互联网的服务,标准的访问权限就无法覆盖所有场景了。

SELinux的一个主要优势是它能够在安全漏洞出现时限制损害范围。

假设Web服务器(Apache httpd)被黑客攻击。在传统权限机制下,攻击者可能会读取/etc目录中的敏感文件、修改/var/www目录中的脚本,以及访问用户数据。

下面我们来看一个简单的例子,了解SELinux如何基于文件标签阻止即使是root用户的访问。

首先,我们在root用户的主目录中创建一个测试文件:

复制
$ echo "secret" > /root/zfile1.

现在,我们使用chcon命令更改该文件的SELinux标签:

复制
$ chcon -t admin_home_t /root/zfile1.

在这里,我们为/root/zfile分配了admin_home_t类型,这并不是供Web服务器访问的类型。

最后,我们检查Apache是否能够访问该文件:

复制
$ runcon -t httpd_t -- cat /root/testfile cat: /root/zfile: Permission denied1.2.

我们使用runcon -t命令在不同的SELinux上下文(httpd_t,即Apache运行的域)下运行cat /root/zfile命令。即便cat命令是以root身份运行的,SELinux也会介入并阻止它。

THE END
本站服务器由亿华云赞助提供-企业级高防云服务器