1.何为SELinux:
SEAndroid是SELinux in Android的缩写。SELinux全称Security Enhanced Linux,即安全增强版Linux,它并非一个Linux发布版,而是一组可套用在类Unix操作系统(如Linux、BSD等)的修改,主要由美国国家安全局(NSA)开发,已经被集成到2.6版的Linux核心之中,现已有十几年的开发和使用历史,是Linux上最杰出的安全子系统。
标准的UNIX安全模型是“自主访问控制“DAC(Discretionary Access Control),任何程序对其资源享有完全的控制权,这些控制权由用户自己定义。
SELinux的安全模型则是MAC(Mandatory Access Control),即强制访问控制,它的做法是“最小权限原则”,通过定义哪些用户可以访问哪些文件,从而提供了一系列的机制,来限制用户和文件的权限。
2.传统Linux的不足之处:
虽然Linux相比Windows可靠性与稳定性更好,但它也和其他UNIX一样,有以下这些不足之处:
①存在特权用户root
任何人只要得到root权限,对整个系统都可为所欲为。这一点Windows也一样。
②对文件访问权划分不够细
在linux系统里,对文件的操作,只有三类划分:所有者/所有者所属组/其他。
对「其他」这类用户的更细粒度的划分无能为力。
③SUID程序的权限升级
若设置了SUID权限的程序有漏洞的话,很容易被攻击者所利用。
④DAC(Discretionary Access Control)问题
文件目录的所有者可对文件进行所有的操作,这给系统整体的管理带来不便。
对于以上的不足,防火墙,入侵检测系统都是无能为力的。
3.SELinux的优点
SELinux系统相比标准Linux系统,安全性要高的多,它通过最小化用户与进程的权限,使得系统即使受到攻击,进程或者用户权限被夺去,也不会对整个系统造成重大影响。
在标准Linux中,主体的访问控制属性是与内核中的进程真实有效的用户和组ID相关联的,内核利用大量工具保护这些属性,比如登陆和setuid程序,对于文件,文件的inode包括一套访问模式位、文件用户和组ID。
以前的访问控制基于三个控制位:读/写/执行,文件所有者/文件所有者所属组/其他 各一套。
在SELinux中,访问控制属性总是安全上下文三人组形式,所有文件和主体都有一个关联的安全上下文,标准Linux使用进程用户/组ID,文件的访问模式,
文件用户/组ID要么可以访问要么被拒绝,SELinux使用进程和客体的安全上下文,因为SELinux的主要访问控制特性是类型强制,安全上下文中的类型标识符决定了访问权。
若要访问文件,必须同时具备普通访问权限和SELinux访问权限。因此即使以超级用户身份root运行进程,如果不满足进程以及文件或资源的SELinux安全性上下文条件,
也会拒绝访问文件或资源。
4.SELinux工作模式:
有disabled、permissive、enforcing 三种模式:
disabled:禁用SELinux。
permissive:SELinux开启状态,但不做任何策略的拦截。即使违反某策略,SELinux在permissive模式下仍然会允许继续操作,但会把操作的违反行为记录下来。
Enforcing:相比permissive模式,在enforcing模式下,若违反了某策略,SELinux就会进行拦截,导致无法继续操作。
获取当前工作模式:adb shell getenforce
adb shell setenforce 1
设置为enforce模式
adb shell setenforce 0
设置为permissive模式
Default Deny (Principle of Least Privilege)
from external/sepolicy/netd.te
下面这条SELinux语句表示允许(allow)demo域(domain)中的进程读写(rw_file_perms)类型为chr_file的设备类型demo_device:
假设该设备类型与某个设备关联:
/dev/demo u:object_r:demo_device:s0
allow demo demo_device:chr_file rw_file_perms;
若没有在demo.te中使用上例中的权限配置allow语句,则即使demo具有root权限,也无法往读写类型为demo_device的设备。显然,MAC比DAC在权限管理这一块要复杂严格细致得多。
Linux系统先做DAC检查。如果没有通过DAC权限检查,则操作直接失败。通过DAC检查之后,再做MAC检查。
在SELinux中,安全策略文件是最重要的,学习SELinux的终极目标应该是:
①看懂现有的安全策略文件。
②编写符合特定需求的安全策略文件。
前面也曾提到,SELinux有一套自己的规则来编写安全策略文件,这套规则被称之为SELinux Policy语言。它是掌握SELinux的重点。
5.TE
MAC基本管理单位是TEAC(Type Enforcement Accesc Control),然后是高一级别的Role Based Accesc Control。RBAC是基于TE的,而TE也是SELinux中最主要的部分。
例如:
allow netd proc:file write
这条语句的语法为:
① allow:TE的allow语句,表示授权。除了allow之外,还有allowaudit、dontaudit、neverallow等。
② netd:source type。也叫subject,domain。
③ proc:target type。它代表其后的file所对应的Type。
④ file:代表object class。它代表能够给subject的一类操作。例如File、Dir、socket等。在Android系统中,Binder为其他Linux系统所没有的object class。
⑤ write:在该类object class中所定义的操作。
根据SELinux规范,完整的allow语句格式为:
rule_name source_type target_type:object_clas perm_set
#实例1:SEAndroid中的安全策略文件policy.conf
#允许zygote域中的进程向init type的进程(Object Class为process)发送sigchld信号
allow zygote init:process sigchld;
#允许zygote域中的进程search或getattr类型为appdomain的目录,多个perm_set可用{}括起来
allow zygote appdomain:dir { getattr search };
#实例2
allow unconfineddomain {fs_type dev_type file_type}:{ chr_file file } ~{entrypoint relabelto};
#source_type为unconfineddomain
#target_type为一组type,由{ fs_type dev_type file_type }构成
#object_class包含两个为{ chr_file file }
#perm_set前面有一个~号。它表示除{entrypoint relabelto}之外,{chr_file file}这两个object_class所拥有的其他操作
#特殊符号除了~外,还有-号和*号,其中:
# 1):-号表示去除某项内容。
# 2):*号表示所有内容。
neverallow { appdomain -unconfineddomain } self:capability2 *;
#上面这条语句,source_type为属于appdomain,但不属于unconfinedomain的进程。
#而 *表示所有和capability2相关的权限
#neverallow:表示绝不允许。
特别注意,权限必须显示声明,没有声明默认为没有权限。那neverallow语句就没必要存在了。因为”无权限“是不需要声明的。
确实如此,neverallow语句的作用只是在生成安全策略文件时进行检查,判断是否有违反neverallow语句的allow语句。
比如若给untrusted_app allow 访问dev_type:blk_file read write时就会发生编译错误。