SELinux零知识学习十七、SELinux策略语言之类型强制(2)
接前一篇文章:SELinux零知识学习十六、SELinux策略语言之类型强制(1)
二、SELinux策略语言之类型强制
2. 类型、属性和别名
类型是构成TE规则的最小单位,SELinux主要就是使用类型来确定什么访问是被允许的;属性和别名是为减轻管理和适用类型的策略特性,我们使用属性利用单个标识符来引用一组类型。通常,策略语言允许我们在TE规则中类型的适当位置使用属性,而别名允许我们为类型定义另一个名字,别名标识符和类型标识符做同等地位对待。
(1)类型声明
在使用类型前,必须使用type语句明确地声明一个类型标识符,SELinux没有预定义类型,必须自行声明。例如:假设我们想声明一个类型(httpd_t),并打算将其作为Web服务器的域类型,而另一个类型(http_user_content_t)准备应用于用户数据文件,即Web服务器显示内容的文件,则使用type语句进行声明,如下:
type httpd_t;
type http_user_content_t;
声明了类型后就可以在安全上下文、TE规则和其它策略语句中使用它们了。可以使用type语句声明类型和选项以及关联的别名属性。完整的类型声明语法如下:
type 类型名称 [alias 别名集] [, 属性集];
- 类型名称
类型标识符,长度任意,允许包括ASCII字符、数字、下划线(_)和点(.)。
- 别名集
一个或多个别名标识符。别名标识符与类型标识符的命令限制是一致的。如果指定不止一个别名标识符,要在一对大括号中用空格将各个别名区别开来,如:alias {aliasa_t aliasb_t}。
- 属性集
一个或多个预先声明的属性标识符,如果同时指定多个属性标识符,属性之间使用逗号进行分隔,如:type bin_t, file_type, exec_type;。
类型声明在整个策略以及基础载入模块和非基础载入模块中都是有效的,但在条件语句中无效。
(2)类型和属性
复杂的策略可能包括上万个代表系统上不同资源的类型,例如:Fedora Core 4(FC 4)中的targeted策略相对较小,但也声明了超过800个类型。由于默认的规则是拒绝所有的访问,所以任何一个访问都需要明确地被允许,这就导致了类型注定会很冗长,这时策略语言的属性特性就派上用场了。
属性可以理解为:1)类型的性质或属性,或二者兼得;2)一组类型。在任何一种情况下,原理都是相同的。
假设想让一个备份程序可以访问所有的文件,首先要创建一个备份应用程序的域类型(backup_t),并允许它访问与任何文件关联的类型:
type backup_t;
allow backup_t httpd_user_content_t : file read;
allow backup_t shadow_t : file read;
这里指定了域类型backup_t可以访问两种文件类型:前面声明的http_user_content_t和shadow_t类型(shadow_t指的是/etc/shadow文件的类型)。两者都是备份程序必须可读的磁盘文件。
为了完成这个例子,我们编写了一个用于其它所有文件类型的规则,依赖于声明的类型数量,需要大量的allow规则授予备份程序足够的访问权(每个类型都要一个)。另外,每次向策略中增加一个文件类型时,同时要为backup_t增加一套allow规则,这是一个单调且错误频出的过程,属性使得这种“组访问”更容易指定。通过将所有关联的文件类型定义一个属性,然后授予该属性的访问权(而不是每个类型了)。于是,我们可以使用一条规则授予backup_t必需的访问权。
使用attribute语句进行属性声明,如:
attribute file_type;
这个语句声明一个叫做file_type的属性,类型和属性共享相同的命名空间,因此,类型和属性的名字不能雷同。假设我们将所有适当的类型都与属性file_type进行关联,然后就可以使用一条规则来指定backup_t读取这些文件,如:
allow backup_t file_type : file read;
注意:尽管在所有的类型名称后面附加一个_t很常见,但对于属性名称而言,却没有这样通用的约定,因为类型和属性共享同一个命名空间,这样在编写和检验TE规则就很容易地谁是类型、谁是属性了。
现在我们使用了一条规则替代了上千条allow规则,而授予的访问权却是一样的。当这个策略编译好后,这条规则会自动扩展成上千条规则,分别控制不同文件类型的访问。更重要的是,当我们给文件定义了一个新类型时,需要做的仅仅是将这个新类型与file_type属性进行关联,域类型backup_t将会自动获得读取访问权。
使用attribute语句进行属性声明,完整的属性声明语法如下:
attribute 属性名称;
- 属性名称
属性名称的标识符,它的长度不受限制,可以包括ASCII字符、数字、下划线(_)和点(.)。属性和类型、别名都在同一个命名空间,因此不能与其它类型或别名重名。
属性声明在整个策略、基础载入模块和非基础载入模块中都有效,但在有条件的语句中无效。