2.【SELinux学习笔记】概念

时间:2022-11-24 15:32:46
1.强制类型的安全上下文     在SELinux中,访问控制属性叫做安全上上下文。无论主体还是客体都有与之关联的安全上下文,通常安全上下文是由三部分组成:用户:角色:类型。如: $id -Z  joe:user_r:user_t     在SELinux当中,访问控制属性所有的客体或主体都有一个关联上的上下文属性,因为在SELinux基于类型强制策略,因此在安全上下文中的类型标识符决定了访问权。 注!SELinux是基于标注Linux的,也就意味着主体要访问课题时,要同时满足传统Linux的权限控制UGO模型和SELinux类型增强策略。     在安全上下文中,一个进程(主体)的类型通常被称为一个域(domain),那么“域”、“域类型”、“主体类型”和进程类型都是一个意思。相对于客体,用户和角色标识符很少使用,为了方便管理,客体的角色通常被定义为object_r。
2.类型强制访问控制     在SELinux当中,所有访问都必须明确授权,SELinx默认不允许任何访问,完全不考虑当前UGO结构,即不考虑用户/组ID是什么。这也就意味着,在这里没有超级用户了。那么如果主体需要对客体进行访问该如何进行呢?     在SELinux当中,通常是使用allow规则来指定主体类型(即域)对客体类型授予访问权限,也就是allow规则规定了哪些类型的进程可以访问哪些客体。allow规则由四部分组成:
  • 原类型(Source type(s)) 主体类型,即域
  • 目标类型(Target type(s)) 客体类型
  • 客体类别(Object class(es))客体的类别,如文件、目录等
  • 许可(Permission(s)) 主体可以对客体执行哪些操作,我们称之为访问向量
如图: 2.【SELinux学习笔记】概念 2.【SELinux学习笔记】概念
图1 TE allow规则的基础语法示例,如: allow user_t bin_t : file {read execute getattr};//域为user_t的进程可以对客体类型为bin_t的文件具有读权限、可执行权限和可以获得该文件的属性的权限。而获得文件的属性getattr我们可以理解为查看文件的创建日期、更新时间等属性,以及DAC访问模式(rwx)。
3.类型强制策略示例     为了进一步研究类型强制策略,我们以管理密码的程序(passwd)为例来深入了解,在Linux中,passwd程序是可信任的,修改存储经过加密的密码的影子密码文件(/etc/shadow),passwd 程序执行它自己内部的安全策略,允许普通用户修改属于他们自己的密码,同时允许 root 修改所有密码。因此,passwd 程序需要有移动和重新创建shadow 文件的能力,在标准 Linux 中,它当然有这样的权利,因为 passwd 程序可执行文件在执行时被加上了 setuid 位,它作为 root 用户(它能访问所有文件)允许(我们知道,在系统中我们要修改一个用户的密码,root用户和普通用户均可以用/usr/bin/passwd someuser这个命令来修改这个/etc/passwd这个文件,root用户本身拥有对/etc/passwd的写权限,无可厚非;那普通用户呢,这里就用到了setuid,setuid的作用是“让执行该命令的用户以该命令拥有者的权限去执行”,就是普通用户执行passwd时会拥有root的权限,这样就可以修改/etc/passwd这个文件了。)。这就意味着任何程序(当以 root 身份运行时) 都有可能能够修改 shadow 文件。 类型强制使我们能做的事情是确保只有 passwd 程序 (或类似的受信任的程序) 可以访问 shadow 文件, 不管运行程序的用户是谁。     下图为我们描述了SELinux系统中passwd程序使用类型强制策略的流程: 2.【SELinux学习笔记】概念2.【SELinux学习笔记】概念
图2
    上图中定义了passwd的域类型-passwd_t,和shadow密码文件的类型-shadow_t。那么上图中的allow规则的含义为授权域类型为passwd_t的passwd进程的访问文件类型为shadow_t的文件shadow,并且具有移动和创建新的shadow密码文件。     对应的shadow的安全上下文如下:
# ls -Z /etc/shadow -r---- root root system_u:object_r:shadow_t shadow
    那么此时,在当前策略下检查运行密码和程序的进程的安全上下文如下:
# ps -aZ joe:user_r:passwd_t 16532 pts/0 00:00:00 passwd

4.域转换     我们所做的从表面上看起来,仅仅是主体提供对客体访问的许可编写一个TE策略。因为我们不得不考虑下面这个问题,例如在Linux系统中,用户joe登录系统,并且创建了一个shell进程(如bash)。而shell进程的类型是user_t,它表示一个普通的、不受信任的用户进程域类型。那么此时Joe用户如何让shell进程修改密码呢?首先我们来看下图: 2.【SELinux学习笔记】概念 2.【SELinux学习笔记】概念
图3
    当Joe的shell程序运行其他程序时,新进程则会继承user_t的域类型,而user_t又是一个不受信任的域,那么首先我们不应域类型为user_t的进程直接操作shadow密码文件,因为这样会允许其他程序也可以读写这个非常关键的文件。那么此时我们该如何实现呢?也就是说如何实现将一个域为user_t的shell进程转变为域为passwd_t进程。

①setuid     传统Linux中,我们可以通过给passwd赋一个setuid的值,使其具有root权限。在传统Linux系统中,使用下面命令来查看passwd文件信息:
# ls -l /usr/bin/passwd
-r- s xx 1 root root 19336 Sep 7 04:11 /usr/bin/passwd
从上面的信息中我们可以看到,第一个在所有者权限的x位置变成了s,这里的s指的就i时setuid位了,意思是任何执行这个文件的进程,它的uid都将编程文件的所有者。当前我们看到文件的所有者为root用户,那么当Joe用户登陆运行该文件时,实际上此时shell进程的uid就编程了root用户的uid了。如下图: 2.【SELinux学习笔记】概念 2.【SELinux学习笔记】概念
图4     从上图我们可以看到setuid在传统Linux中是一个非常强大的特性,但也同时暴漏出传统Linux的主要弱点,即passwd需要以root身份运行访问shadow文件,然而当以root身份运行时,passwd可以访问所有的系统资源,而我们最初的目的仅仅是需要passwd操作shadow文件而已,这不仅违背了我们的初衷,也违背了最小权限原则。 ②te     从图2中我们知道allow规则可确保passwd_t域的passwd进程可以访问shadow密码文件,那么是如何实现user_t到passwd_t的域转变呢,看下图: 2.【SELinux学习笔记】概念 2.【SELinux学习笔记】概念
图5 从上图中我们可以看到有四个类型分别为:user_t(shell)、shadow_t(shadow)、passwd_t(passwd),passwd_exec_t(passwd)。passwd的安全上下文如下:
# ls -Z /usr/bin/passwd
-r-sxx root root system_u:object_r:passwd_exec_t /usr/bin/passwd
从上面的信息我们可以来创建TE策略规则是passwd_t域运行,首先第一条规则:
allow user_t passwd_exec_t : file {getattrexecute};//允许域为usert_(这里指shell进程),在passwd可执行文件(passwd_exec_t)启动execve()系统调用。实际上也就是说允许shell进程调用execve()来执行passwd。
第二条规则:
allow passwd_t passwd_exec_t : fileentrypoint;//提供passwd_t域的入口访问权,entrypoint许可在SELinxu中是一个许可权限,它的作用就是定义哪个可执行文件(如passwd)可以以某个特定的域(passwd_t)来运行, 这就是所谓的域转变。那么例子中的passwd可执行文件被标识为passwd_exec_t,并且passwd_t类型有entrypoint权限访问passwd_exec_t,那么passwd就具备了在passwd_t域类型中运行的条件。
第三条规则:
allow user_t passwd_t : processtransition;//这条规则中没有提供对客体的访问,因为此时客体是process,意味着此时的客体代表进程。如果系统资源都被封装为客体的话,那么进程也可以理解为系统资源,这里进程作为客体并不矛盾。在这个规则中,许可是transition,这个许可的含义就是允许修改进程的安全上下文中的类型。那么这条规则的含义指的就是:允许user_t域转变为passwd_t域。
那么至此我们了解了域转变的流程,也就是说一次成功的域转变,这三条规则必须保证同时存在,且当这三个许可在一个TE策略中同时通过才能完成域的转变。总结如下:
  1. 进程的新域(passwd_t)对可执行文件(passwd)具有entrypoint许可
  2. 进程当前域(usr_t)具有对入口文件(passwd_exec_t)具有execute许可
  3. 进程当前域(usr_t)对新的域(passwd_t)具有transition许可
5.默认域转变:type_transition指令     通过前面的了解我们已经很清楚了域转变的流程,那么还有一个疑惑就是,用户Joe如何明确它所需要的域转变,通常情况下我们并不需要用户明确的发出这些请求,这就需要一个方法让系统默认启动域转变。     为了支持默认的域转变,这里我们引入一个新的规则,即类型转变规则(type_transition)。这个规则为SELinux策略提供了一个方法指定默认的域转变,具体如下:
type_transition user_t passwd_exec_t : process passwd_t;//将主体user_t域转变为主体passwd_t域
    这个语法规则域allow规则不尽相同,但仍然可以看到熟悉的主体域和客体域(user_t和passwd_exec_t),而且还有客体类别(process),而且还有新的域(passwd_t)。
6.角色     SELinux也提供了一种基于角色的访问控制(RBAC:Role-Based Access Control)。RBAC作为传统访问控制(DAC自主访问,MAC强制访问)的有前景的代替受到广泛的关注。RBAC支持三个著名的安全原则:最小权限原则,责任分离原则和数据抽象原则,SELinux的RBAC特性是依靠TE建立的,因为在SELinux中访问控制主要是通过类型实现的,角色是基于进程安全上下文中的角色标识符限制进程可以转变的类型。那么如何定义角色的限制呢?看下图: 2.【SELinux学习笔记】概念 2.【SELinux学习笔记】概念
图6     从上图我们可以看到,这里增加了角色部分(user_r),定义一个角色的语句如下:
role user_r type passwd_t;//role语句声明角色标识符以及声明的角色有关的类型。这里声明角色user_r以及相关联的类型passwd_t,这个关联意味着passwd_t类型在安全上下文中与角色user_r共存,如果没有此role语句,就无法创建新的安全上下文joe:user_r:passwd_t,且execve()函数调用也会失败,及时TE策略允许Joe的类型(user_t)有所有的访问权。

7.MLS(Multi-Level Security)     MLS对于SELinux来说是可选的,但尽管如此,MLS对部分应用程序还是增强了一定的安全性。那么为了支持MLS,安全上下文被扩展如下,增加了安全级别,如:
user:role:type:sensitivity[:category,...][-sensitivity[:category,...]]
    包含MLS的安全上下文至少有一个安全级别,如果存在两个安全级别,那么这两个安全级别就被叫做低和高,如果高安全级别丢失,那么就会只有低安全级别生效。
8.SELinux特性
①.Permissive(许可)模式     SELinux可以运行在permissive模式,在这个模式中,只存在访问检查但不会拒绝不允许的访问。检查SELinux当前的工作模式最简单的方法就是运行getenforce命令。设置系统SELinux工作模式,可使用setenforce 0设置为permissive模式,使用setenforce 1修改为强制模式,但是如果从permissive模式修改为强制模式需要以root登录后再操作。 ②passwd示例     为了帮助我们更好的理解域转换,我们来通过下面的流程来验证域转换:
  • 启动第一个终端,运行passwd命令:
$ passwd Changing password for user joe. Changing password for joe (current) UNIX password:
  • 启动第二个终端,su到root用户,然后使用下面的怕死命令:
$ su
Password:
Your default context is root:sysadm_r:sysadm_t.
Do you want to choose a different one? [n]
# ps axZ|grep passwd
user_u:user_r:passwd_t 4299 pts/1 S+ 0:00 passwd
此时我们看到passwd进程的域为passwd_t。
③策略分析工具apol     这是一个检查策略内容非常实用的一个工具,由Tresys科技公司开发,随SELinux工具包一起发布,成为SeTools。SeTools软件包包含在大多数SELinux发行包中,运行apol命令确定这个工具是否已经安装到系统中,若没有安装     apol(analyze policy)是一个成熟的SELinux策略分析工具,本系列文章中也会经常使用SELinux策略。如果我们想要使用它来检查策略文件,运行apol然后打开strict策略文件,在Query>Policy Summary下就可以看到策略相关的摘要信息。 2.【SELinux学习笔记】概念
2.【SELinux学习笔记】概念