SELinux访问控制机制和策略语言的详细内容非常广泛,将在后面的章节中进行描述。但SELinux的基本概念和目标是相当简单的,在这一章 中,我们将学习SELinux的安全概念,并在这些概念后进行练习。要有效使用和应用SELinux访问控制,理解其概念是非常必要的,这一章主要集中介 绍SELinux的访问控制特性和类型强制(TE),同时我们也简要地介绍了一下非强制的多层安全机制。
1.类型强制的安全上下文
所有操作系统访问控制都是以关联的客体和主体的某种类型的访问控制属性为基础的。在SELinux中,访问控制属性叫做安全上下文。所有客体(文 件、进程间通讯通道、套接字、网络主机等)和主体(进程)都有与其关联的安全上下文,一个安全上下文由三部分组成:用户、角色和类型标识符。常常用下面的 格式指定或显示安全上下文:
用户:角色:类型user:role:type
这个字符串标识符中的每个元素使用SELinux策略语言进行定义,后面我们会对策略语言进行详细的描述,现在只需要理解一个有效的安全上下文必须 要有一个有效的用户、角色和类型标识符,通过策略编写器定义标识符,每一个标识符的命名空间正交的,因此,用户、角色和类型的标识符可能相同,但不合理, 也不建议这么定义。
安全上下文示例
SELinux对系统中的许多命令做了修改,通过添加一个-Z选项显示客体和主体的安全上下文,例如:ls -Z显示文件系统客体的安全上下文,ps -Z显示进程的安全上下文,另一个有用的命令是id,它显示了你的shell的安全上下文(即你当前的用户、角色和类型),下面的例子显示了一个运行 SELinux的shell安全上下文:
$id -Z joe:user_r:user_t
你可以使用本章中我们列出的这些命令研究你自己的SELinux系统。
2 对比SELinux和标准Linux
至此,比较标准Linux和SELinux之间的访问控制属性显得非常有用,为了使表述简化,我们只固定讨论文件系统客体如文件和目录。在标准 Linux中,主体的访问控制属性是与进程通过在内核中的进程结构关联的真实有效的用户和组ID,这些属性通过内核利用大量工具进行保护,包括登陆进程和 setuid程序,对于客体(如文件),文件的inode包括一套访问模式位、文件用户和组ID。以前的访问控制基于读/写/执行这三个控制位,文件所有 者、文件所有者所属组、其他人各一套。
在SELinux中,访问控制属性总是安全上下文三人组形式,所有客体和主体都有一个关联的安全上下文,标准Linux使用进程用户/组ID,文件 的访问模式,文件用户/组ID要么可以访问要么被拒绝,SELinux使用进程和客体的安全上下文,需要特别指出的是,因为SELinux的主要访问控制 特性是类型强制,安全上下文中的类型标识符决定了访问权。
注意:SELinux在标准Linux基础上增加了类型强制,这就意味着标准Linux和SELinux访问控制都必须满足先要能访问一个客体,例如:如果我们对某个文件有SELinux写入权限,但我们没有该文件的w许可,那么我们也不能写该文件。
表2-1.标准Linux和SELinux访问控制比较
标准Linux SELinux 进程安全属性 真实有效的用户和组ID 安全上下文 客体安全属性 访问模式和文件用户和组ID 安全上下文 访问控制基础 进程用户/组ID和文件基于文件的用户/组ID的访问模式 在进程类型和文件类型之间允许的许可
3 安全上下文
安全上下文是一个简单的、一致的访问控制属性,在SELinux中,类型标识符安全上下文的主要组成部分,由于历史原因,一个进程的类型通常被称为 一个域(domain),”域”和”域类型”意思都是一个,我们不必苛刻地去区分或避免使用术语域,通常,我们认为域、域类型、主体类型和进程类型都是同 义的。
安全上下文中的用户和角色标识符除了对强制有一点约束之外对类型强制访问控制策略没什么影响,我们将在第7章”约束”中讨论,对于进程,用户和角色 标识符显得更有意义,因为它们用于控制类型和用户标识符的联合体,这样就会Linux用户账号关联起来;然而,对于客体,用户和角色标识符几乎很少使用, 为了规范管理,客体的角色常常是object_r,客体的用户常常是创建客体的进程的用户标识符,它们在访问控制上没什么作用。
最后,一定要清楚标准Linux安全中的用户ID和安全上下文中的用户标识符之间的区别,就技术而论,它们是正交标识符,分别用于标准的和安全增强 的访问控制机制,这两者之间的任一相互关联都是通过登陆进程按照规范严格规定的,而不是通过SELinux策略直接强制实施的。
4 类型强制访问控制
在SELinux中,所有访问都必须明确授权,SELinux默认不允许任何访问,不管Linux用户/组ID是什么。这就意味着在SELinux 中,没有默认的超级用户了,与标准Linux中的root不一样,通过指定主体类型(即域)和客体类型使用allow规则授予访问权限,allow规则由 四部分组成:
源类型(Source type(s) ) 通常是尝试访问的进程的域类型
目标类型(Target type(s) ) 被进程访问的客体的类型
客体类别(Object class(es)) 指定允许访问的客体的类型
许可(Permission(s)) 象征目标类型允许源类型访问客体类型的访问种类
举一个例子进行说明,如:
allow user_t bin_t : file {read execute getattr};
这个例子显示了TE allow规则的基础语法,这个规则包含了两个类型标识符:源类型(或主体类型或域)user_t,目标类型(或客体类型)bin_t。标识符file是 定义在策略中的客体类别名称(在这里,表示一个普通的文件),大括号中包括的许可是文件客体类别有效许可的一个子集,这个规则解释如下:
拥有域类型user_t的进程可以读/执行或获取具有bin_t类型的文件客体的属性。
正如我稍后会讨论的,SELinux中的许可相对标准Linux而言要更细一些,在标准Linux中只有三种(rwx)。在这里,read和 execute是十分常见的,getattr明显要少得多,实质上,文件的getattr许可只不过允许调用者查看(不修改)如日期、时间等属性,以及任 意访问控制(DAC)访问模式。在一个标准Linux系统中,调用者只有搜索文件所在目录的权限,但也可能看到关于文件的信息,因为他可以通过搜索目录来 看到文件的某些信息,即使他没有该文件的访问权限。
假设user_t是一个普通的、无特权的用户进程如一个登陆shell进程域类型,bin_t是与用户运行的执行文件(如/bin/bash)关联的类型,策略中的规则可能允许用户执行shell程序如bash shell。
注意:在类型标识符名字中的_t没有意义,只不过是在大多数SELinux策略中惯用的约定,策略编写器可以通过策略语言语法允许的任何合适的规范定义类型标识符。
在这一章中,我们使用符号圆圈代表进程,方框代表客体,箭头代表允许的访问来描绘允许的访问,例如:如2-1描绘了前面的allow规则允许的访问。
5 .类型强制示例
SELinux allow规则如之前的例子在SELinux中实际上都是授予访问权的,真正的挑战是如何保证数以万计的访问正确授权,只授予必须的权限,实现尽可能的安全。
为了进一步研究类型强制,我们以管理密码的程序(即passwd)为例进行说明,在Linux中,passwd程序是可信任的,修改存储经过加密的 密码的影子密码文件(/etc/shadow),passwd程序执行它自己内部的安全策略,允许普通用户修改属于他们自己的密码,同时允许root修改 所有密码。为了执行这个受信任的作业,passwd程序需要有移动和重新创建shadow文件的能力,在标准Linux中,它有这个特权,因为 passwd程序可执行文件在执行时被加上了setuid位,它作为root用户(它能访问所有文件)允许,然而,许多程序都可以作为root允许(实际 上,所有程序都有可能作为root允许)。这就意味着任何程序(当以root身份运行时)都有可能能够修改shadow文件。类型强制使我们能做的事情是 确保只有passwd程序(或类似的受信任的程序)可以访问shadow文件,不管运行程序的用户是谁。
下图描绘了在SELinux系统中passwd程序如何使用类型强制进行工作的
在这个例子中,我们定义了两个类型,passwd_t类型代表密码程序使用的域类型,shadow_t类型代表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
现在,你可以忽略安全上下文的用户和角色元素,只需注意类型就行了。
检查图2-2中的allow规则,这个规则的目的是授予passwd进程的域类型(passwd_t)访问shadow的文件类型 (shadow_t),需要允许进程移动并创建一个新的shadow密码文件。重新回到图2-2中,我们看到描绘运行密码程序(passwd)的进程能够 成功管理shadow密码文件,因为它有一个有效的root用户ID(标准Linux访问控制),同时因为TE allow规则允许它访问shadow密码文件的类型(SELinux访问控制),两者都是必须的,但都不充分。
6 域转变的问题
如果我们所做的所有事情是为进程提供对客体如文件的许可访问,编写一个TE策略应该是直截了当的事情。然而,我们不得不找出用正确的域类型安全正确 地运行一个程序的方法。例如:我们不想程序由于某种原因在一个进程中用passwd_t域类型不受信任地访问shadow文件,这可能是灾难性的,这个问 题带来了域转变的问题。
为了说清楚这个问题,下图中,我们扩展了前面的密码程序示例,在一个普通的系统中,用户(如Joe)登陆进系统,通过登陆进程会创建一个 shell进程(如运行bash)。在标准Linux安全中,真实有效的用户ID(即Joe)是相同的[1],在我们的SELinux策略示例中,我们看 到进程类型是user_t,它表示一个普通的、不受信任的用户进程域类型。当Joe的shell程序运行其他程序时,新进程的类型将会保留user_t域 类型,除非做了其他操作,那么Joe如何修改密码呢?
[1]正确地说,Joe不是用户ID,Joe只不过是在密码文件(/etc/passwd)中表示用户的字符串而已,为了使解释更浅显易懂,我跳过了中间的步骤,在我们的例子中只使用字符串标识符。
我们不应该让Joe的不受信任的域类型user_t能够直接读写shadow密码文件,因为这样将会允许任何程序(包括Joe的shell)看到并 修改这个关键文件的内容。正如前面讨论的,我们只想密码程序有这个访问权,然后只以passwd_t域类型运行它。那么,问题是如何提供一个安全可靠的并 且比较隐蔽的方法将Joe的以user_t类型运行的shell转变为一个以passwd_t类型运行密码程序的进程。
7标准Linux安全中的setuid程序
在我们讨论如何处理域转变的问题之前,首先看一下类似的问题在标准Linux中是如何处理的,即Joe想安全地修改现有的密码问题,Linux解决 这个问题的方法是通过给passwd赋一个setuid值,使其执行时具有root权限,如果你在一个普通Linux系统上列出密码文件,你看到的会是:
# ls -l /usr/bin/passwd -r-sxx 1 root root 19336 Sep 7 04:11 /usr/bin/passwd
这 里注意两件事,第一个是在所有者权限的x位置被设置为s了,这就是所谓的setuid位,意思是任何执行这个文件的进程,它的有效UID(即用户ID)将 会被改为文件所有者。这里,root是文件所有者,因此当执行密码程序时实际上将会以root用户的ID运行,图2-4显示了这些步骤。
图.标准Linux中密码程序安全(setuid)
当Joe运行密码程序时真正会发生的是他的shell将会产生一个fork()系统调用创建一个它自身的副本,这个复制进程仍然有真实有效的用户 ID(joe),并且仍然运行有shell程序(bash)。然而,在调用完fork指令后,新的进程将会产生一个execve()系统调用来执行密码程 序。标准Linux安全需要调用的用户ID(仍然是joe)有x权限,这里确实就是这样,因为所有人都有x权限。成功执行execve()调用将会发生两 件非常关键的事情,第一件是运行在新进程中的shell程序将会被passwd程序替换,第二,因为setuid位是为所有者设的,真正的用户ID将从进 程的原始ID改为文件所有者的ID(这里是root),因为root可以访问所有文件,那么密码程序也就可以访问shadow密码文件了,也就可以处理 Joe修改密码的需求了。
setuid位的使用在类Unix操作系统中非常普遍,这是它们的一个简单但强大的特性,然而,它也成为标准Linux安全的主要弱点,密码程序需 要以root身份运行访问shadow文件,然而,当以root身份运行时,密码程序可以访问所有的系统资源,这就违背了中心安全工程的最小权限原则,结 果,我们必须信任密码程序,对于信任的安全应用程序,密码程序需要一个扩展的代码审核来确保它不会滥用它的特权,而且,当遇到无法预见的错误时,会影响到 密码程序,这样就可能会将缺陷引入,即使密码程序相当简单且是高度受信任的,想象一下其他程序(包括登陆shell)可能以root身份运行将会是多么可 怕的。
我们真正要做的事情应该是确保为密码程序设置最小权限,我们认为密码程序应该只能访问shadow文件和其他与密码有关的文件,再加上那些必须的最 小系统资源,同时我们还应该确保除了密码程序能访问shadow文件外,其他程序都不能访问这个文件,这样说来,我们就只需要关心密码程序它自身的角色就 行了,不用管用户账号了。
这就是马上会描述的类型强制。
8.域转变
在前面的图中,allow规则确保passwd进程域类型(passwd_t)可以访问shadow密码文件,然而,我们仍然有前面已经提到 的域转变问题,提供一个安全的域转变与setuid程序的原理非常类似,但强化了类型强制,为了解释清楚一点,下面我们以在setuid的例子中增加类型 强制为例进行说明(如下图)。
图.SELinux中的密码程序安全(域转变)
现在,我们的例子变得更复杂了,让我们一起来详细看看这张图。首先,注意我们在前面的基础上增加了三个类型,即Joe的shell域 (user_t),密码程序的域类型(passwd_t)和shadow密码文件的类型(shadow_t)。此外,我们为passwd可执行文件增加了 文件类型(passwd_exec_t)。例如:列出密码程序的安全上下文时,将会看到:
# ls -Z /usr/bin/passwd -r-sxx root root system_u:object_r:passwd_exec_t /usr/bin/passwd
现在我们有足够的信息来创建TE策略规则允许密码程序(大概只有密码程序)以passwd_t域类型运行,让我们来看一看图2-5中的规则,第一条规则是:
allow user_t passwd_exec_t : file {getattr execute};
这条规则所做的事情是允许Joe的shell(user_t)在passwd可执行文件 (passwd_exec_t)上启动execve()系统调用,SELinux execute文件权限实际上与标准Linux中的x访问权限是一样的,尝试执行之前shell先”统计”文件,因此需要getattr权限,回想一下我 们在前面描述的shell程序实际上是如何工作的,首先它派生出自身的一个副本,包括相同的安全属性,这个副本仍然保留了Joe的shell原始域类型 (user_t),因此,必须给原始域(即shell的域类型)赋予执行权限,那就是为什么user_t是这个规则的源类型的原因了。
下面让我们来看看图2-5中的第二个规则:
allow passwd_t passwd_exec_t : file entrypoint;
这条规则提供了对passwd_t域的入口访问权,entrypoint许可在SELinux中是一个相当有用的许可权限,这个权限所做的事情是定 义哪个可执行文件(程序)可以”进入”某个特定的域,对于域转变,新的或将要进入的域(这里是passwd_t)必须具有访问可执行文件的 entrypoint许可权,以转变到新的域类型,在这个例子中,假设只有passwd可执行文件被标识为passwd_exec_t,并且只有 passwd_t类型有entrypoint权限访问passwd_exec_t,这样我们就具备了只有密码程序才能运行在passwd_t域类型中的条 件,这是一个强大的安全控制。
警告:entrypoint许可权限的概念是相当重要的,如果你没有完全理解前面的示例,在开始行动前,请重新阅读一次。
让我们在看一看最后的规则:
allow user_t passwd_t : process transition;
这是我们第一次看到的allow规则没有提供对文件客体的访问,在这个例子中,客体类别是process,意味着客体类别代表进程,回想一下前面的 内容,所有的系统资源都被封装为客体类别,这个概念也包括进程,在这最后一个规则中,许可是TRansition 访问,在允许修改进程的安全上下文的类型时,需要这个许可,原始的类型(user_t)到新的类型(passwd_t)进行域转变必须有 TRansition 许可才允许进行。
这三条规则一起提供了域转变发生时必须的访问权,对于一个成功的域转变,这三条规则都是必须的,任何单独一个都是不够充分的,因此,域转变只有在同时满足下面的三个条件时才允许进行:
1、进程的新域类型对可执行文件类型有enTRypoint 访问权
2、进程的当前(或旧的)域类型对入口文件类型有execute 访问权
3、进程当前的域类型对新的域类型有transition 访问权
当这三个许可在一个TE策略中都被通过后,才可能发生域转变,而且,在可执行文件上使用entrypoint 许可,我们有能力严格控制哪个程序可以用给定的域类型运行,execve()系统调用是修改域类型的唯一方法[2],使得策略编写器可以很好地控制任何一 个程序的访问特权,而不管调用程序的用户。
[2]更精确地说,为SELinux最近对进程的修改提供了一个方法,赋予必须的特权,修改它的安全上下文,而不使用execve()调用,通常,这个机制将会在第5章”类型强制”中描述,它没有一个强健的理由,我们不应该使用它,因为它大大地削弱了类型强制的强健性。
现在的问题是Joe如何指出他想要的域转变,上面的规则只允许域转变,他们不需要它,程序员或用户 有多种方法明确请求一个域转变(如果允许),但通常情况下,我们不想让用户明确地发出这些请求,Joe想做的是允许密码程序,它希望系统确保他能完成这个 任务,我们需要一个方法让系统默认启动域转变。
9.默认域转变:type_transition指令
为了支持默认的域转变,我们需要引入一个新的规则,类型转变规则(type_transition),这个规则为SELinux策略提供一个方法指 定默认应该尝试的转变,在没有明确指出需要的转变时,让我们在allow规则后面添加一个type_transition规则:
type_transition user_t passwd_exec_t : process passwd_t;
这个规则的语法与allow规则有点不一样了,但仍然有源和目标类型(分别是user_t和passwd_exec_t),也有客体类别(process),然而,许可相反了,我们有了第三个类型,默认类型(passwd_t)。
type_transition规则用于多中不同的与修改默认类型相关的目的,现在,我们关心将process作为它的客体类别的 type_transition规则,这个规则引发默认的域转变尝试,type_transition规则默认代表一个execve()系统调用,如果调 用的进程域类型是user_t,并且可执行文件的类型是passwd_exec_t(如图2-5中的示例),将会尝试到一个新域类型(passwd_t) 的域转变。
type_transition规则允许策略编写器引发默认的域转变,而不需要明确的用户输入,这使得类型强制减少了用户的强制闯入,在我们的例子 中,Joe不想知道任何关于访问控制或类型的事情,他只想修改它的密码,系统和策略设计人员可以使用type_transition规则使这些转变对于用 户而言是透明的。
注意:记住type_transition规则引发一个默认的域转变,但它不允许它执行,你还是必须为域转变成功发生提供三个需要的访问类型,无论是默认启动还是通过用户的明确请求启动。
10 角色
SELinux也提供了一种基于角色的访问控制(RBAC),SELinux的RBAC特性是依靠类型强制建立的,SELinux中的访问控制主要 是通过类型实现的,角色基于进程安全上下文中的角色标识符限制进程可以转变的类型,如此,策略编写器可以创建一个角色,允许它转变为一套域类型(假设类型 强制规则允许转变),从而定义角色的限制,以我们在图2-5中所举的密码程序为例,按照类型强制规则,密码程序可以通过user_t域类型执行,然后转到 新的passwd_t域,Joe的角色必须允许与新的域类型建立关联以便进行域转变,为了同图进行说明,我们在图2-6中扩展了密码程序示例。
图.域转变中的角色
在进程描述安全上下文内容中我们增加了角色部分(user_r),同时还增加了一个新的角色,在role语句中明确地指出:
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)有所有的访问权。
策略编写器可以定义更多约束的角色,然后将这些角色与用户关联起来,例如:设想一下,在我们的策略中,创建了一个角色叫做 restricted_user_r,除了它与passwd_t类型没有关联之外,与user_r一样,因此,如果Joe的角色是 restricted_user_r而不是user_r,Joe就不能通过认证运行密码程序,即使TE规则允许它的域类型访问。
11 SELinux中的多层安全
类型强制无疑是SELinux引入的最重要的强制访问控制(MAC)机制,然而,在某些情况下,主要是保密控制应用程序的一个子集,传统的多层安全 (MLS)MAC与类型强制一起使用显得更有价值,在这些情况下,SELinux总是包括某种格式的MLS功能,MLS特性是可选的,在SELinux的 两个MAC机制中,它通常不是最重要的那个,对大多数安全应用程序而言,包括许多非保密数据应用程序,类型强制是最适合的安全增强的机制,尽管如 此,MLS对部分应用程序还是增强了安全性。
MLS的基本概念在第1章”背景”中已经介绍过了,真实实施MLS更佳复杂,MLS系统使用的安全级别是层次敏感的,是一个(包括空集)非层次范畴 的集合。这些敏感度和范畴用于映射真实的机密信息或用户许可,在大多数SELinux策略中,敏感度(s0,s1,…)和范畴(c0,c1,…)使用 通配名,将它留给用户空间程序和程序库,以指定有意义的用户名。(例如:s0可能与UNCLASSIFIED 关联,s1可能与SECRET关联)
为了支持MLS,安全上下文被扩展了,包括了安全级别,如:
user:role:type:sensitivity[:category,...] [-sensitivity[:category,...]]
注意MLS安全上下文至少必须有一个安全级别(它由单个敏感度和0个或多个范畴组成),但可以包括两个安全级别,这两个安全级别分别被叫做 低(或进程趋势)和高(或进程间隙),如果高安全级别丢失,它会被认为与低安全级别的值是相同的(最常见的情况),实际上,对于客体和进程而言,低和高安 全级别通常都是相同的,通常用于进程的级别范围被认为是受信任的主体(即进程信任降级信息)或多层客体,如一个目录,它又包括了不同安全级别的客体。为了 使描述简单,假设所有的进程和客体都只有一个安全级别。
访问客体的MLS规则与第1章中描述的非常相似,除了安全级别是无层次的之外,但又提供了一个控制关系进行管理,不像等式那样,级别要么比另一个要 高,或相等,要么就比它低,在控制关系中,有一个叫做无可比的第四种状态(也叫做非可比的,查看下面列表中的incomp),安全级别通过控制关系而不是 范畴关联,它没有层次关系,有四个控制操作符可以将两个MLS安全级别关联起来,如:
dom:如果SL1的敏感度大于或等于SL2的敏感度,则SL1 dom(优于) SL2,SL1的范畴就是SL2范畴的一个超集。
domby:如果SL1的敏感度小于或等于SL2的敏感度,则SL1 domby SL2,SL1的范畴是SL2的子集。
eq:如果SL1的敏感度等于SL2的敏感度,则SL1 eq SL2,SL1和SL2的范畴也是相同的。
incomp:如果SL1的范畴和SL2的范畴不能进行对比(即既不是子集也不是超集或其他),那么SL1 incomp(不可对比)SL2。
提供了域关系,在SELinux中实现了多种Bell-La Padula模型,如果进程当前的安全级别优于客体的安全级别,进程则可以”读取”客体。如果低于客体的安全级别,则可以”写入”客体,因此,同时读写客体只要这两个安全级别相等就可以了。
SELinux中MLS的约束是附加在TE规则中的,如果启用了MLS,要授予访问权两个检查都必须通过,第8章”多层安全”将会讨论SELinux可选的MLS特性。
12 .精通SELinux特性
此时,花点时间摆弄一下SELinux系统是值得的,在我们的例子中,我们使用带strict(严格)策略的Fedora Core 4(FC 4)发行版,这些例子大部分都能工作在Red Hat Enterprise Linux 4(RHEL 4)或Fedora Core 5(FC 5),也可能能够工作在其他发行版上,即使它们之间有许多不同之处。附录A”获得SELinux示例策略”描述了如何获取策略文件和其他我们在这本书的示 例中使用到的资源,以及如何使用这些资源来配置你的系统。
运行在Permissive (许可)模式
SELinux可以运行在Permissive 模式,这个模式只存在访问检查,但不会拒绝不允许的访问,它只是简单地进行一个审核操作,这个模式在初次接触SELinux学习时非常有用,你可能想在这 个模式下研究系统,当然,如果你想增强SELinux的访问安全,不应该在正式的系统上使用Permissive 模式,注意/usr/sbin下的某些工具不是使用的常见用户路径。
检查SELinux当前的工作模式最简单的方法是运行getenforce命令,要将系统设置为Permissive 模式,运行setenforce 0,你必须要以root用户在system_t域登陆修改系统为Permissive 模式,要将其修改强制模式,运行setenforce 1,因为你在Permissive 模式,所以只需要以root登陆,将系统修改为强制模式即可。
前面我们已经说过在某些系统命令上添加了-Z选项,如ls和ps分别显示文件和进程的安全上下文,请做一个练习,运行ps xZ和ls -Z /bin命令,检查运行中的进程和可执行文件的安全上下文。
12 重游passwd示例
在这一章中,我们都使用shadow密码文件和密码程序作为例子,如果检查过这两个文件的安全上下文,它们的类型分别应该是shadow_t和 passwd_exec_t,正如前面讨论的,passwd_exec_t是passwd_t域的入口类型,为了证明进程是如何进行域转变的,按照下面的 命令集合进行操作,你需要两个终端窗口或虚拟控制台。
在第一窗口中,运行passwd命令:
$ passwd Changing password for user joe. Changing password for joe (current) UNIX password:
启动密码程序,提示输入用户当前的密码,不要输入密码,此时转入第二个终端窗口,在第二个窗口中,su到root用户,然后运行ps命令:
$ 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_t,与前面例子中描述的规则一样。
注意:在strict策略中,普通用户(即在user_t域中运行shell的用户)无权读取大多数/proc/pid条目,因此在ps axZ命令的输出中就看不到passwd程序,这就是为什么我们要su到root的原因了。
你好,关于selinux域转换,有一点疑惑想要请教:
在android的hosted.te文件中有这么语句
type_transition hostapd wifi_data_file:dir wap_socket “sockets”;
一直很疑惑后面加个引号“sockets”是做什么用处,对规则有什么影响?望指点一二。
type_transition的语法为:type_transition source_type target_type : class default_type object_name;
而object_name是可选的。官方解释为:For the ‘name transition’ rule this is matched against the objects name (i.e. the last component of a path). If object_name exactly matches the object name, then use default_type for the type.
例子如下:
# type_transition to allow using the last path component as
# part of the information in making labeling decisions for
# new objects. An example rule:
#
type_transition unconfined_t etc_t : file system_conf_t eric;
# This rule says if unconfined_t creates a file in a directory
# labeled etc_t and the last path component is “eric” (must be
# an exact strcmp) it should be labeled system_conf_t.
参照链接地址:http://selinuxproject.org/page/TypeStatements