3.网络网络的基本构成是节点、端口和网卡。1节点nodecon 用来标记一个 IPv4 或 IPv6 节点。nodecon subnet netmask node_context举例nodecon 127.0.0.1 255.255.255.255 system_u:object_r:lo_node_tnodecon ff00:: ff00:: system_u:object_r:multicast_node_tIPv4 本地地址 127.0.0.1 被赋予安全上下文 system_u:object_r:lo_node_t IPv6 广播地址 ff00::ff00::被赋予安全上下文 system_u:object_r:multicast_node_t。2端口portcon 用来标记一个端口。portcon protocol port_number port_context举例portcon tcp 20 system_u:object_r:ftp_data_port_ttcp 端口 20 被赋予安全上下文 system_u:object_r:ftp_data_port_t。3网卡netifcon 被用来标记网卡及通过网卡的网络包的安全上下文。netifcon netif_id netif_context packet_context举例netifcon eth0 system_u:object_r:netif_t system_u:object_r:packet_t规定 eth0 的安全上下文是 system_u:object_r:netif_t通过 eth0 的网络包的安全上下文是system_u:object_r:packet_t。7.3.3 安全上下文转换如果只有初始/缺省安全上下文则安全上下文不能变换那么 SELinux 的世界是静止的 SELinux 的安全作用就很有限。所以 SELinux 的主体和客体的安全上下文一定是可以变换的。因为 SELinux 的机制有三个基于角色的访问控制、类型增强、多级安全下面分机制介绍安全上下文的转换。1.角色的转换SELinux 用户的转换没有对应的策略语句。角色转换的语法allow from_role_id to_role_id;举例allow sysadm_r secadm_r;上述语句表示允许系统管理员转换为安全管理员。角色转换的语法role_transition current_role_id type_id new_role_id;或者role_transition current_role_id type_id : class new_role_id;举例allow unconfined_r msg_filter_r;role_transition unconfined_r sec_serv_exec_t msg_filter_r;上述语句表示当进程执行类型为 sec_serv_exec_t 的文件时进程的角色由 unconfined_r转化为 msg_filter_r。2.类型类型转换略复杂。包含三种语法1 type_transitiontype_transition source_type target_type : class default_type;type_transition 定义了当条件满足时的新类型。这种策略既用于生成主体进程新安全上下文又用于生成客体新安全上下文。下面分别举例。先是主体type_transition initrc_t acct_exec_t:process acct_t;allow initrc_t acct_exec_t:file execute;allow acct_t acct_exec_t:file entrypoint;allow initrc_t acct_t:process transition;上述语句表示类型 initrc_t 的进程执行类型为 acct_exec_t 的文件时执行后进程的类型变为 acct_t。后三条 allow 语句是为了保证执行动作能够发生不会被内核拒绝。再看一个客体的例子type_transition acct_t var_log_t:file wtmp_t;allow acct_t var_log_t:dir { read getattr lock search ioctl add_nameremove_name write };allow acct_t wtmp_t:file { create open getattr setattr read write appendrename link unlink ioctl lock };上述语句表示类型为 acct_t 的进程在类型为 var_log_t 的目录中创建文件时文件的安全上下文的类型为 wtmp_t。第一条 allow 保证了进程可以在类型为 var_log_t 的目录中创建文件第二条 allow 保证进程可以访问类型为 wtmp_t 的文件。2 type_change安全上下文中类型还可以改变改变成什么值由 type_change 策略规定type_change source_type target_type : class change_type;举例type_change auditadm_t sysadm_devpts_t:chr_file auditadm_devpts_t;上述语句表示 类型为 auditadm_t 的进程可以将类型为 sysadm_devpts_t 的字符设备文件的类型改变为 auditadm_devpts_t。type_change 语句用于规定主体和客体的类型可以改变为什么值。 进程在运行过程中可以将进程自身或某一客体的类型改变 改变成什么必须满足 type_change 语句的规定。 type_transition语句作用于两种场景。第一个场景是进程创建新客体时新客体的类型来自 type_transition 的规定。第二个场景是进程执行 execve 系统调用后进程的新类型来自 type_transition 的定义。3 type_membertype_member 的常用场景是在用户登录时登录服务根据用户类型给予用户家目录/home/user不同的类型。语法type_member source_type target_type : class member_type;举例type_member sysadm_t user_home_dir_t:dir adm_home_dir_t;上述语句表示类型为“sysadm_t”的进程的家目录的类型为“adm_home_dir_t”。3.多级安全在叙述多级安全转换策略之前先要描述一下 MLS 的 range 定义。语法low_level或者low_level - high_levelrange_transition 策略的定义如下range_transition source_type target_type new_range;或者range_transition source_type target_type : class new_range;这种命令主要被 init 进程或别的管理进程使用以保证它繁衍的子进程工作的安全上下文中的 MLS 处在正确的范围内。举例range_transition initrc_t auditd_exec_t:process s15:c0.c255;上述语句表示 init 进程生成 audit 服务进程时 audit 进程的安全上下文中的多级安全级别处于系统最高级别。7.3.4 访问控制访问控制是 SELinux 最基本的功能。 SELinux 的客体类别、操作、安全上下文、安全上下文转换都是为访问控制服务的。SELinux 的访问控制策略又叫存取向量规则Access Vector Rules。这类策略在 SELinux策略文件中使用得最为频繁。语法为rule_name source_type target_type : class perm_set;可以看到这类策略定义只和类型相关。所以在 SELinux 的三种机制基于角色的访问控制、类型增强、多级安全中类型增强最重要。访问控制策略中的 rule_name 有以下 4 个值1 allow允许源域source_type对目的域target_type上的类class进行操作perm_set。举例allow initrc_t acct_exec_t:file { getattr read execute }2 dontaudit停止将拒绝访问消息写入审计日志。缺省情况下拒绝访问会被写入审计日志允许访问消息则不会。举例:dontaudit traceroute_t { port_type -port_t }:tcp_socketname_bind;3 auditallow将允许访问消息写入审计日志。举例auditallow kernel self:capability { sys_rawio mknod };4 neverallow指定不能产生什么样的 allow 策略。 neverallow 只在策略编译过程中有效并不在运行中生效。举例neverallow { domain -mmap_low_domain_type } self:memprotect mmap_zero;其中策略文件出现最多的是 allow。 SELinux 是基于“白名单”的像 neverallow 这种黑名单策略只在编译过程中生效用于策略检查。7.3.5 访问控制的限制和条件有了前面介绍的访问控制策略 SELinux 已经可以完成访问控制工作了。但 SELinux 的设计者觉得还不够又引入了限制语句和条件语句。在限制语句和条件语句中四元组中的类型之外的三个成员也可以起作用。1.限制限制Constrain的语法是constrain class perm_set expression;其中 expression 的语法是expression : ( expression )| not expression| expression and expression| expression or expression| u1 op u2| r1 role_op r2| t1 op t2| u1 op names| u2 op names| r1 op names| r2 op names| t1 op names| t2 op names其中 u1、 r1、 t1 指源端主体的 SELinux 用户、角色、类型 u2、 r2、 t2 指目的端客体的 SELinux 用户、角色、类型。 op 包含两个值“”和“!”。 role_op 包含“”和“!”。names 就是一个或多个名字。names : name | { name_list }name_list : name | name_list name举例constrain process transition (u1 u2or( t1 can_change_process_identity and t2 process_user_target )or( t1 cron_source_domain and ( t2 cron_job_domain or u2 system_u ))or( t1 can_system_change and u2 system_u )or( t1 process_uncond_exempt ) );2.条件为了进一步增加灵活性 SELinux 在策略中引入了布尔变量和条件分支。这也增加了复杂性。1 bool语法很简单bool bool_id default_value;举例bool allow_execheap false;2 if通过 if 语句内核可以根据布尔变量关闭或启用部分策略。语法如下if (conditional_expression) { true_list } [ else{ false_list } ]其中 conditional_expression 可以包含布尔常量true 或 false、一个或多个已定义的布尔变量可以使用的布尔运算符包括、 ||、 ^、 !、 、 !。举例bool allow_execmem false;if(allow_execmem) {allow sysadm_t self:process execmem;}3.多级安全限制SELinux 安全上下文四元组中的 SELinux 用户和角色有两条途径为 SELinux 访问控制做贡献。第一条路径是 SELinux 用户映射为角色角色映射为类型第二条路径是在限制策略中起作用。多级安全为访问控制做贡献只有一条路径就是多级安全限制策略。多级安全限制策略语句是 mlsconstrain。 mlsconstrain 和 constrain 类似也是对客体对象施加额外的检查。语法如下mlsconstrain class perm_set expression; 其中 expression 的语法是 expression : ( expression ) | not expression | expression and expression | expression or expression | u1 op u2 | r1 role_mls_op r2 | t1 op t2 | l1 role_mls_op l2 | l1 role_mls_op h2 | h1 role_mls_op l2 | h1 role_mls_op h2 | l1 role_mls_op h1 | l2 role_mls_op h2 | u1 op names | u2 op names | r1 op names | r2 op names | t1 op names | t2 op names其中 u1、 r1、 t1、 l1、 h1 指源端主体安全上下文中的 SELinux 用户、角色、类型、多级安全中的低级别、多级安全中的高级别。 u2、 r2、 t2、 l2、 h2 指目的端客体安全上下文中的 SELinux 用户、角色、类型、多级安全中的低级别、多级安全中的高级别。 op 包含和!。role_mls_op 包含、 !、 eq、 dom、 domby、 incomp。 names 的定义为names : name | { name_list } name_list : name | name_list name 举例: mlsconstrain dir search (( l1 dom l2 ) or (( t1 mlsfilereadtoclr ) and ( h1 dom l2 )) or ( t1 mlsfileread ) or ( t2 mlstrustedobject ));