简介
在我们的SELinux series,的第一部分中,我们了解了如何启用和禁用SELinux,以及如何使用布尔值更改某些策略设置。在这第二部分中,我们将讨论文件和进程安全上下文。
为了让您回想起上一篇教程中的内容,文件安全上下文是a_type_,进程安全上下文是a_domain_。
注意事项 本教程中展示的命令、包和文件在CentOS 7上进行了测试。其他发行版的概念与此相同。
在本教程中,除非另有说明,否则我们将以root用户身份运行命令。如果你没有权限访问root帐户,而使用另一个具有sudo权限的帐户,你需要在命令前加上sudo
关键字。
创建测试用户账号
首先,让我们创建四个用户帐户来演示SELinux功能。
- 规则用户
- 切换用户
- 来宾用户
- 受限用户
您当前应该是超级用户 用户。我们运行以下命令来添加** RegarUser** 帐号:
1useradd -c "Regular User" regularuser
然后运行passwd
命令更改其密码:
1passwd regularuser
输出将要求我们输入新密码。提供后,帐户即可登录:
1Changing password for user regularuser.
2New password:
3Retype new password:
4passwd: all authentication tokens updated successfully.
让我们也创建其他帐户:
1useradd -c "Switched User" switcheduser
2passwd switcheduser
1useradd -c "Guest User" guestuser
2passwd guestuser
1useradd -c "Restricted Role User" restricteduser
2passwd restricteduser
SELinux用于进程和文件
SELinux的目的是保护进程在Linux环境中访问文件的方式。如果没有SELinux,像Apache守护进程这样的进程或应用程序将在启动它的用户的上下文中运行。因此,如果您的系统受到在root用户下运行的流氓应用程序的危害,该应用程序可以做任何它想做的事情,因为root用户对每个文件都有无所不包的权限。
SELinux试图更进一步,消除这种风险。有了SELinux,进程或应用程序将只拥有运行所需的权限,没有其他权限。应用程序的SELinux策略将确定它需要访问哪些类型的文件,以及它可以转换到哪些进程。SELinux策略由应用程序开发人员编写,并随支持它的Linux发行版一起提供。策略基本上是一组将进程和用户映射到他们的权限的规则。
我们将从理解SELinux_CONTEXTS_和_DOMAINS_的含义开始讨论本教程的这一部分。
安全性的第一部分是在Linux系统中的每个实体上放置一个_Label_。标签类似于任何其他文件或进程属性(所有者、组、创建日期等);它显示资源的_CONTEXT_。那么,什么是背景呢?简而言之,上下文是帮助SELinux做出访问控制决策的安全相关信息的集合。Linux系统中的任何东西都可以有一个安全上下文:用户帐户、文件、目录、守护进程或端口都可以有它们的安全上下文。但是,安全上下文对于不同类型的对象意味着不同的事情。
SELinux文件上下文
让我们从了解SELinux文件上下文开始。让我们看一下针对/etc目录的常规ls-L命令的输出。
1ls -l /etc/*.conf
这将向我们展示一个熟悉的输出:
1...
2-rw-r--r--. 1 root root 19 Aug 19 21:42 /etc/locale.conf
3-rw-r--r--. 1 root root 662 Jul 31 2013 /etc/logrotate.conf
4-rw-r--r--. 1 root root 5171 Jun 10 07:35 /etc/man_db.conf
5-rw-r--r--. 1 root root 936 Jun 10 05:59 /etc/mke2fs.conf
6...
很简单,对吧?现在让我们添加-Z标志:
1ls -Z /etc/*.conf
现在,我们在用户和组所有权之后有一列额外的信息:
1...
2-rw-r--r--. root root system_u:object_r:locale_t:s0 /etc/locale.conf
3-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf
4-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/man_db.conf
5-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/mke2fs.conf
6...
此列显示文件的安全上下文。当您拥有一个文件的可用信息时,它就被称为已使用其安全上下文进行了标记。让我们更仔细地看看其中的一个安全上下文。
1-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf
安全上下文是这一部分:
1system_u:object_r:etc_t:s0
有四个部分,安全上下文的每个部分都用冒号(:)分隔。第一部分是文件的SELinux_USER_CONTEXT。我们稍后将讨论SELinux用户,但现在,我们可以看到它是system_u 。每个Linux用户帐号映射到一个SELinux用户,在本例中,拥有该文件的** 根** 用户被映射到** system_u** SELinux用户。此映射由SELinux策略完成。
第二部分指定SELinux_ROLE_,即OBJECT_r 。要熟悉SELinux角色,请回顾第一篇SELinux文章。
这里最重要的是第三部分,即这里列出的文件的_type_,即etc_t 。这是定义文件或目录所属的类型的部分。我们可以看到,在/etc
目录中,大部分文件属于** etc_t** 类型。假设,您可以将类型视为文件的一种组
或_属性:它是对文件进行分类的一种方式。
我们还可以看到一些文件可能属于其他类型,比如Locale.con
,它有一个Locale_t 类型。即使此处列出的所有文件都具有相同的用户和组所有者,它们的类型也可能不同。
作为另一个示例,让我们检查用户主目录的类型上下文:
1ls -Z /home
主目录将具有不同的上下文类型:user_home_dir_t
1drwx------. guestuser guestuser unconfined_u:object_r:user_home_dir_t:s0 guestuser
2drwx------. root root system_u:object_r:lost_found_t:s0 lost+found
3drwx------. regularuser regularuser unconfined_u:object_r:user_home_dir_t:s0 regularuser
4drwx------. restricteduser restricteduser unconfined_u:object_r:user_home_dir_t:s0 restricteduser
5drwx------. switcheduser switcheduser unconfined_u:object_r:user_home_dir_t:s0 switcheduser
6drwx------. sysadmin sysadmin unconfined_u:object_r:user_home_dir_t:s0 sysadmin
安全上下文的第四部分S0 与多级安全或MLS有关。基本上,这是实施SELinux安全策略的另一种方式,这部分显示了资源的敏感度(** s0** )。我们稍后将简要讨论敏感度和类别。对于SELinux的大多数普通设置而言,前三个安全上下文更为重要。
SELinux进程上下文
现在让我们来讨论一下进程安全上下文。
启动APACHE和SFTP服务。我们在第一个SELinux教程中安装了这些服务。
1service httpd start
2service vsftpd start
我们可以运行带有几个标志的ps
命令来显示在我们的服务器上运行的Apache和SFTP进程:
1ps -efZ | grep 'httpd\|vsftpd'
同样,-Z标志用于显示SELinux上下文。输出显示运行进程的用户、进程ID和父进程ID:
1system_u:system_r:httpd_t:s0 root 7126 1 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
2system_u:system_r:httpd_t:s0 apache 7127 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
3system_u:system_r:httpd_t:s0 apache 7128 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
4system_u:system_r:httpd_t:s0 apache 7129 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
5system_u:system_r:httpd_t:s0 apache 7130 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
6system_u:system_r:httpd_t:s0 apache 7131 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
7system_u:system_r:ftpd_t:s0-s0:c0.c1023 root 7209 1 0 16:54 ? 00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
8unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 7252 2636 0 16:57 pts/0 00:00:00 grep --color=auto httpd\|vsftpd
安全上下文是这一部分:
1system_u:system_r:httpd_t:s0
安全上下文有四个部分:用户、角色、域和敏感度。用户、角色和敏感度的工作方式与文件的相同上下文相同(在上一节中进行了解释)。该域对于进程来说是唯一的。
在上面的示例中,我们可以看到有几个进程在httpd_t 域内运行,而有一个进程在** ftpd_t** 域内运行。
那么,域为进程做了什么呢?它为进程提供了在其中运行的上下文。它就像一个气泡,围绕着这个过程,把它限制住了。它告诉流程它能做什么,不能做什么。这种限制确保每个过程域只能作用于某些类型的文件,而不能作用于其他类型的文件。
使用此模型,即使一个进程被另一个恶意进程或用户劫持,它所能做的最糟糕的事情就是损坏它有权访问的文件。例如,vsftp守护程序将无法访问sendmail或samba使用的文件。这个限制是从内核级别实现的:它是在SELinux策略加载到内存时强制执行的,因此访问控制变成了_MANDIRED_。
命名约定
在我们继续之前,这里有一个关于SELinux命名约定的说明。SELinux用户以)或域(进程)以_t
为后缀。
进程如何访问资源
到目前为止,我们已经看到文件和进程可以有不同的上下文,并且它们被限制到它们自己的类型或域。那么,流程如何运行呢?要运行,进程需要访问其文件并对其执行一些操作(打开、读取、修改或执行)。我们还了解到,每个进程只能访问某些类型的资源(文件、目录、端口等)。
SELinux在策略中规定了这些访问规则。访问规则遵循standard allow statement structure:
1allow <domain> <type>:<class> { <permissions> };
我们已经讨论了域和类型。类 定义资源的实际表示(文件、目录、符号链接、设备、端口、游标等)。
下面是这个通用ALLOW语句的含义:
- 如果进程属于某个域
- 并且它试图访问的资源对象属于特定的类和类型
- 然后允许访问
- 否则拒绝访问
为了了解它的工作原理,让我们考虑一下在CentOS 7系统上运行的HTTPD守护进程的安全上下文:
1system_u:system_r:httpd_t:s0 7126 ? 00:00:00 httpd
2system_u:system_r:httpd_t:s0 7127 ? 00:00:00 httpd
3system_u:system_r:httpd_t:s0 7128 ? 00:00:00 httpd
4system_u:system_r:httpd_t:s0 7129 ? 00:00:00 httpd
5system_u:system_r:httpd_t:s0 7130 ? 00:00:00 httpd
6system_u:system_r:httpd_t:s0 7131 ? 00:00:00 httpd
Web服务器的默认主目录为/var/www/html
。让我们在该目录中创建一个文件并检查其上下文:
1touch /var/www/html/index.html
2ls -Z /var/www/html/*
我们Web内容的文件上下文将是HTTPD_SYS_CONTENT_t :
1-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
我们可以使用sesearch
命令来检查HTTPD守护进程允许的访问类型:
1sesearch --allow --source httpd_t --target httpd_sys_content_t --class file
该命令使用的标志是相当不言自明的:源域是 httpd_t ,与Apache运行的域相同。我们感兴趣的目标资源是文件,并具有类型上下文** httpd_sys_content_t** 。您的输出应该如下所示:
1Found 4 semantic av rules:
2 allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
3 allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
4 allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
5 allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename execute open } ;
请注意第一行:
1allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
这说明HTTPD守护进程(Apache Web服务器)对HTTPD_SYS_CONTENT 类型的文件具有I/O控制、读取、获取属性、锁定和打开访问权限。在本例中,我们的index.html
文件具有相同的类型。
更进一步,我们首先修改网页(/var/www/html/index.html
)。编辑文件以包含此内容:
1<html>
2 <title>
3 This is a test web page
4 </title>
5 <body>
6 <h1>This is a test web page</h1>
7 </body>
8</html>
接下来,我们将更改/var/www/
文件夹的权限及其内容,然后重启HTTPD守护进程:
1chmod -R 755 /var/www
2service httpd restart
然后,我们将尝试从浏览器访问它:
访问网页
注意事项 根据您的服务器的设置,您可能需要在iptabes防火墙中启用端口80,以允许来自服务器外部的传入HTTP流量。在这里,我们不会深入到iptabes中启用端口的细节。在这个主题上有一些很好的数字海洋articles,你可以使用。
到目前一切尚好。HTTPD守护程序被授权访问特定类型的文件,我们可以在通过浏览器访问时看到它。接下来,让我们通过更改文件的上下文来做一些不同的事情。我们将对其使用chcon
命令。该命令的--type
标志允许我们为目标资源指定新类型。这里,我们将文件类型更改为var_t 。
1chcon --type var_t /var/www/html/index.html
我们可以确认类型更改:
1ls -Z /var/www/html/
1-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 index.html
接下来,当我们尝试访问网页时(即HTTPD守护进程试图读取文件),您可能会收到禁止 的错误,或者您可能会看到通用的CentOSTesting 123
页面:
访问网页
这是怎么回事显然,现在有些访问被拒绝了,但这是谁的访问?就SELinux而言,Web服务器只被授权访问某些类型的文件,而var_t不是这些上下文之一。由于我们将index.html文件的上下文更改为var_t,Apache无法再读取它,因此我们得到一个错误。
为了让它再次正常工作,让我们使用Restorecon
命令更改文件类型。-v开关显示上下文标签的更改:
1restorecon -v /var/www/html/index.html
1restorecon reset /var/www/html/index.html context unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
如果我们现在尝试访问该页面,它将再次显示这是一个测试网页
文本。
这是一个需要理解的重要概念:确保文件和目录具有正确的上下文是确保SELinux正常运行的关键。我们将在本节的末尾看到一个实际用例,但在此之前,让我们再谈几件事。
文件和目录的上下文继承
SELinux强制执行我们可以称之为上下文继承
的东西。这意味着,除非策略指定,否则进程和文件将使用其父进程的上下文创建。
因此,如果我们有一个名为proc_a
的进程生成另一个名为proc_b
的进程,则所派生的进程将在与proc_a
相同的域中运行,除非SELinux策略另有指定。
类似地,如果我们有一个类型为some_context_t
的目录,则在其下创建的任何文件或目录都将具有相同的类型上下文,除非策略另有说明。
为了说明这一点,我们来查看/var/www/
目录的上下文:
1ls -Z /var/www
/var/www/
中的html
目录包含HTTPD_SYS_CONTENT_t 类型的上下文。正如我们之前看到的,其中的index.html
文件具有相同的上下文(即,父文件的上下文):
1drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
2drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
将文件复制到其他位置时,不会保留此继承。在复制操作中,复制的文件或目录将采用目标位置的类型上下文。在下面的代码片段中,我们将index.html
文件(类型为)复制到/var/
目录:
1cp /var/www/html/index.html /var/
如果我们检查复制的文件的上下文,我们将看到它已更改为var_t ,即其当前父目录的上下文:
1ls -Z /var/index.html
1-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /var/index.html
这种上下文更改可以被cp
命令中的--preserver=context
子句覆盖。
移动文件或目录时,会保留原始上下文。在下面的命令中,我们将/var/index.html
移到/etc/
目录下:
1mv /var/index.html /etc/
当我们检查被移动的文件的上下文时,我们看到 var_t 上下文已经被保留在/etc/
目录下:
1ls -Z /etc/index.html
1-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /etc/index.html
那么,为什么我们如此关注文件上下文呢?为什么这个复制和移动概念很重要?想一想:也许你决定将所有Web服务器的HTML文件复制到根文件夹下的一个单独的目录中。您这样做是为了简化备份过程并加强安全性:您不希望任何黑客轻松猜测您网站的文件在哪里。您已经更新了目录的访问控制,更改了Web配置文件以指向新位置,重新启动了服务,但它仍然不起作用。也许您可以查看目录及其文件的上下文作为下一个故障排除步骤。让我们运行它作为一个实际的例子。
SELinux实际操作:测试文件上下文错误
首先,让我们在根目录下创建一个名为www
的目录。我们还将在www
下创建一个名为html
的文件夹。
1mkdir -p /www/html
如果我们运行ls-z
命令,我们将看到这些目录是在DEFAULT_T 上下文中创建的:
1ls -Z /www/
1drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 html
接下来,我们将/var/www/html
目录的内容复制到/www/html
:
1cp /var/www/html/index.html /www/html/
复制的文件的上下文为DEFAULT_T 。这是父目录的上下文。
现在,我们编辑httpd.conf
文件,使其指向这个新目录,作为网站的根文件夹。我们还必须放宽对此目录的访问权限。
1vi /etc/httpd/conf/httpd.conf
首先注释掉文档根目录的现有位置,并在/www/html
中添加一个新的DocumentRoot
指令:
1# DocumentRoot "/var/www/html"
2
3DocumentRoot "/www/html"
我们还注释掉了现有文档根目录的访问权限部分,并添加了一个新部分:
1#<Directory "/var/www">
2# AllowOverride None
3 # Allow open access:
4# Require all granted
5#</Directory>
6
7<Directory "/www">
8 AllowOverride None
9 # Allow open access:
10 Require all granted
11</Directory>
我们保留cgi-bin
目录的位置不变。我们在这里不会讨论详细的Apache配置;我们只希望我们的站点能够为SELinux目的而工作。
最后,重新启动HTTPD守护进程:
1service httpd restart
一旦服务器重新启动,访问网页将给我们相同的),我们看到过。
发生该错误是因为index.html
文件的上下文在复制操作期间发生了更改。需要将其更改回其原始上下文(HTTPD_SYS_CONTENT_T)。
但我们要怎么做呢?
更改和恢复SELinux文件上下文
在前面的代码示例中,我们看到了两个用于更改文件内容的命令:chcon
和Restorecon
。运行chconn
是一项临时措施。您可以使用它临时更改文件或目录上下文,以排除访问拒绝错误。然而,这种方法只是暂时的:文件系统重新标记或运行Restorecon
命令会将文件恢复到其原始上下文。
此外,运行chcon
需要知道文件的正确上下文;--type
标志指定目标的上下文。Restorecon
不需要指定此参数。如果您运行Restorecon
,文件将重新应用正确的上下文,并且更改将永久生效。
但如果你不知道文件的正确上下文,系统如何知道在运行Restorecon
时应用哪个上下文?
SELinux可以方便地记住
服务器中每个文件或目录的上下文。在CentOS7中,系统中已存在的文件的上下文列在/etc/selinux/targeted/contexts/files/file_contexts
文件中。这是一个大文件,它列出了与Linux发行版支持的每个应用程序相关联的所有文件类型。新目录和文件的上下文记录在/etc/selinux/targeted/contexts/files/file_contexts.local
文件中。因此,当我们运行Restorecon
命令时,SELinux将从这两个文件之一中查找正确的上下文,并将其应用于目标。
下面的代码片段显示了其中一个文件的摘录:
1cat /etc/selinux/targeted/contexts/files/file_contexts
1...
2/usr/(.*/)?lib(/.*)? system_u:object_r:lib_t:s0
3/opt/(.*/)?man(/.*)? system_u:object_r:man_t:s0
4/dev/(misc/)?agpgart -c system_u:object_r:agp_device_t:s0
5/usr/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0
6/opt/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0
7/etc/(open)?afs(/.*)? system_u:object_r:afs_config_t:s0
8...
要永久更改/www/html
下的index.html文件的上下文,我们必须遵循两个步骤。
- 首先,我们运行
Semanage fcontext
命令。这会将新的上下文写入/etc/selinux/targeted/contexts/files/file_contexts.local
文件。但它不会重新标记文件本身。我们将对这两个目录执行此操作。
1semanage fcontext --add --type httpd_sys_content_t "/www(/.*)?"
2semanage fcontext --add --type httpd_sys_content_t "/www/html(/.*)?"
为了确保这一点,我们可以检查文件上下文数据库(注意,我们使用的是file_contexts.local
文件):
1cat /etc/selinux/targeted/contexts/files/file_contexts.local
您应该看到更新的上下文:
1# This file is auto-generated by libsemanage
2# Do not edit directly.
3
4/www(/.*)? system_u:object_r:httpd_sys_content_t:s0
5/www/html(/.*)? system_u:object_r:httpd_sys_content_t:s0
接下来,我们将运行Restorecon
命令。这将使用上一步中记录的内容重新标记文件或目录:
1restorecon -Rv /www
这将在三个级别上重置上下文:顶级的/www
目录,其下的/www/html
目录和/www/html
下的index.html
文件:
1restorecon reset /www context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
2restorecon reset /www/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
3restorecon reset /www/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
如果我们现在尝试访问网页,它应该工作。
有一个叫做matchpathcon的漂亮工具可以帮助解决与上下文相关的问题。该命令将查看资源的当前上下文,并将其与SELinux上下文数据库下列出的内容进行比较。如果不同,它将建议所需的更改。让我们用/www/html/index.html
文件测试一下。我们将使用-V
标志来验证上下文:
1matchpathcon -V /www/html/index.html
matchpathcon
输出应该显示已经验证了上下文。
1/www/html/index.html verified.
对于一个标签不正确的文件,消息将说明上下文应该是什么:
1/www/html/index.html has context unconfined_u:object_r:default_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
域名转换
到目前为止,我们已经了解了进程如何访问文件系统资源。现在我们将了解进程如何访问其他进程。
Domain transition_是进程将其上下文从一个域更改到另一个域的方法。为了理解它,我们假设有一个名为proc_a的进程在contexta_t的上下文中运行。通过域转换,proc_a可以运行一个名为app_x的应用程序(程序或可执行脚本),该应用程序将_spawn another进程。这个新进程可以称为proc_b,它可以在contextb_t域中运行。因此,实际上,contexta_t通过app_x_transitioning_ to contextb_t。app_x可执行文件作为contextb_t的_entrypoint_工作。流程如下所示:
域转换的情况在SELinux中相当常见。让我们考虑在我们的服务器上运行的vsftpd进程。如果它没有运行,我们可以运行service vsftpd start
命令来启动守护进程。
接下来,我们来考虑一下系统进程。这是所有进程的始祖。这是对system V init进程的替换,并在init_t 的上下文中运行。:
1ps -eZ | grep init
1system_u:system_r:init_t:s0 1 ? 00:00:02 systemd
2system_u:system_r:mdadm_t:s0 773 ? 00:00:00 iprinit
在init_t 域内运行的进程是短暂的:它将调用二进制可执行文件/usr/sbin/vsftpd
,该文件的类型上下文为** ftpd_exec_t** 。当二进制可执行文件启动时,它本身就成为vsftpd守护进程,并在** ftpd_t** 域内运行。
我们可以检查文件和进程的域上下文:
1ls -Z /usr/sbin/vsftpd
向我们展示:
1-rwxr-xr-x. root root system_u:object_r:ftpd_exec_t:s0 /usr/sbin/vsftpd
检查流程:
1ps -eZ | grep vsftpd
向我们展示:
1system_u:system_r:ftpd_t:s0-s0:c0.c1023 7708 ? 00:00:00 vsftpd
因此,在init_t 域中运行的进程正在执行一个** ftpd_exec_t** 类型的二进制文件。该文件在** ftpd_t** 域内启动一个守护进程。
这种转换不是应用程序或用户可以控制的。这在SELinux策略中有规定,该策略在系统引导时加载到内存中。在非SELinux服务器中,用户可以通过切换到更强大的帐户来启动进程(前提是她或他有权这样做)。在SELinux中,这种访问由预先编写的策略控制。这也是SELinux据说要实现强制访问控制的另一个原因。
域转换遵循三个严格的规则:
- 源域的父进程必须拥有位于两个域之间的应用程序的执行权限(这是_entrypoint_)。
- 应用程序的文件上下文必须标识为目标域的_entrypoint_。
- 必须允许原始域转换到目标域。
以上面的vsftpd守护进程为例,让我们使用不同的开关运行sesearch
命令,以查看该守护进程是否符合这三条规则。
首先,源域init_t需要具有对具有ftpd_exec_t上下文的入口点应用程序的执行权限。因此,如果我们运行以下命令:
1sesearch -s init_t -t ftpd_exec_t -c file -p execute -Ad
结果表明,init_t域内的进程可以读取、获取属性、执行和打开ftpd_exec_t上下文的文件:
1Found 1 semantic av rules:
2 allow init_t ftpd_exec_t : file { read getattr execute open } ;
接下来,我们检查二进制文件是否是目标域ftpd_t的入口点:
1sesearch -s ftpd_t -t ftpd_exec_t -c file -p entrypoint -Ad
事实的确如此:
1Found 1 semantic av rules:
2 allow ftpd_t ftpd_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
最后,源域init_t需要有权限才能转换到目标域ftpd_t:
1sesearch -s init_t -t ftpd_t -c process -p transition -Ad
如下所示,源域具有该权限:
1Found 1 semantic av rules:
2 allow init_t ftpd_t : process transition ;
无限制域名
当我们引入域的概念时,我们将其比作流程周围的假设气泡:规定流程可以做什么和不能做什么的东西。这就是限制这一过程的原因。
SELinux还具有在不受限制的域中运行的进程。正如您可以想象的那样,无限制进程将拥有系统中的所有类型的访问权限。即使这样,这种完全访问权限也不是任意的:SELinux策略中也指定了完全访问权限。
无限制进程域的示例为unconfined_t。这与登录的用户在默认情况下运行其进程的域相同。在后续小节中,我们将讨论用户及其对处理域的访问。
结论
今天,我们在这里介绍了一些非常重要的SELinux概念。管理文件和进程上下文是成功实现SELinux的核心。正如我们将在本series](https://andsky.com/tech/tutorials/an-introduction-to-selinux-on-centos-7-part-3-users),的下一个也是[最后一部分]中看到的,还有另一块拼图:SELinux用户。