Linux学习 - SELinux/SEAndroid
一、SELinux/SEAndroid简介
安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。
Android底层是基于linux架构的,SEAndroid是Google在Android 4.4上正式推出的一套以SELinux为基础于核心的系统安全机制。
二、设计目的
最大限度地减小系统中服务进程可访问的资源(最小权限原则)。
三.安全模型介绍
DAC(Discretionary Access Control):自主访问控制。在没有使用 SELinux 的操作系统中,决定一个资源是否能被访问的因素是:某个资源是否拥有对应用户的权限(读、写、执行)。只要访问这个资源的进程符合以上的条件就可以被访问。而最致命问题是,root 用户不受任何管制,系统上任何资源都可以无限制地访问。这种权限管理机制的主体是用户。
MAC(Mandatory Access Control): 强制访问控制。在使用了 SELinux 的操作系统中,决定一个资源是否能被访问的因素除了上述因素之外,还需要判断每一类进程是否拥有对某一类资源的访问权限。这样一来,即使进程是以 root 身份运行的,也需要判断这个进程的类型以及允许访问的资源类型才能决定是否允许访问某个资源。进程的活动空间也可以被压缩到最小。即使是以 root 身份运行的服务进程,一般也只能访问到它所需要的资源。即使程序出了漏洞,影响范围也只有在其允许访问的资源范围内。安全性大大增加。这种权限管理机制的主体是进程。
可以看到,在 DAC 模式下,只要相应目录有相应用户的权限,就可以被访问。而在 MAC 模式下,还要受进程允许访问目录范围的限制。
SELinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制。
四、基本概念
SELinux 是通过 MAC 的方式来控管程序,他控制的主体是程序(进程), 而目标则是该程序能否读取的文件资源。
主体 (Subject):进程
目标 (Object):被访问的资源(可以是文件、目录、端口、设备等)。
政策 (Policy):访问限制条件
- targeted:针对网络服务限制较多,针对本机限制较少,是默认的政策;
- strict:完整的 SELinux 限制,限制方面较为严格。
- 其他策略
一般使用默认的 targeted 政策即可。
安全上下文 (Security Context):
主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。
SELinux验证整体流程:
DAC MAC的验证顺序是:
Linux系统先做DAC检查,如果没有通过直接失败,如果通过了,再做MAC权限检查。
五、SELinux 工作模式
SELinux 有三种工作模式,分别是:
1. enforcing:强制模式。违反 SELinux 规则的行为将被阻止并记录到日志中。
2. permissive:宽容模式。违反 SELinux 规则的行为只会记录到日志中。一般为调试用。
3. disabled:关闭 SELinux。
adb shell getenforce 查看模式。
adb shell setenforce 0|1 分别对应切换 permissve | enforcing 模式
三种工作模式的验证过程:
六、Security Context详解
SELinux中,每种东西都赋予一个安全属性,官方叫:Security Context 直译就是安全上下文。它是一个字符串。
Scontext分为:进程的scontext 和 文件的tcontext。两者匹配时,才会允许进程访问文件,若不匹配时则不被允许。
Security Context用冒号分为四个字段: user : role : type : level
字段 | 说明 |
---|---|
用户(User) | root:表示 root 的帐号身份。 system_u:表示系统程序方面的识别,通常就是程序。 user_u:代表的是一般使用者帐号相关的身份。 或者直接一个 u 表示用户 |
角色(Role) | object_r:代表的是文件或目录等文件资源,这应该是最常见的。system_r/r:代表程序,但一般使用者也会被指定成为 system_r/r 。 |
类型(Type) | type:在文件资源 (Object) 上面称为类型 (Type)。 domain:在主体程序 (Subject) 则称为领域 (domain) 。 domain 需要与 type 搭配,则该程序才能够顺利的读取文件资源 |
级别(Level) | MSL安全级别 |
SEAndroid下举例:
查看文件的tcontext: adb shell ls -Z
dr-xr-xr-x 69 root root u:object_r:cgroup:s0 0 1971-03-14 07:23 acct
查看进程的scontext: adb shell ps -Z
u:r:init:s0 root 1 0 16204 1284 SyS_epoll_ 00004c7df8 S /init
七、安全策略-TE介绍
安全策略是在安全上下文的基础上进行描述的,也就是说,它通过主体和客体的安全上下文,定义主体是否有权限访问客体。SEAndroid安全机制主要是使用对象安全上下文中的类型来定义安全策略,这种安全策略就称Type Enforcement,简称TE。所有以.te为后缀的文件经过编译之后,就会生成一个sepolicy文件。这个sepolicy文件会打包在ROM中,并且保存在设备上。
根据SELinux规范,完整的allow相关的语句格式为:
rule_name source_type target_type : class perm_set
source_type 和 target_type 都是查看进程和文件对应的安全上下文得来的。
具体字段说明如下:
字段 | 描述 |
---|---|
rule_name(访问控制规则) | allow : 允许主体对客体进行操作 neverallow :拒绝主体对客体进行操作 dontaudit : 表示不记录某条违反规则的决策信息 auditallow :记录某项决策信息,通常SElinux只记录失败的信息,应用这条规则后会记录成功的决策信息。 |
source_type(访问者类型) | 进程 ,属性为domain类型,代表主体。 |
target_type(目标类型) | 资源,(文件、目录、端口等)属性为type类型,代表客体,目标类型可以指定多个。 |
class (客体类别) | 允许访问的客体类别,是对目标类型的限制。常见类别: class filesystem class file 普通文件 class dir 目录 class fd 文件描述 class lnk_file 链接文件 class chr_file 字符设备文件 ... |
perm_set(权限) | 指定主体可以对客体进行操作的种类。常见权限操作如下: ioctl、read、write、create、getattr、setattr、lock、relabelfrom、relabelto、append、link、rename、execute、swapon、quotaon、mounton |
另外对SEAndroid app分类稍微做下总结:
platform_app.te(具有android platform签名,没有system权限的app)
system_app.te(具有android platform签名与system权限的app)
untrusted_app.te(第三方app, 不具有android platform签名和system权限)
看看allow语句的例子:
1.允许zygote domain中的进程向init type的进程(Object Class为process)发送sigchld信号
allow zygote init:process sigchld;
2.允许zygote域中的进程search或getattr类型为appdomain的目录。注意,多个perm_set, 可用{}括起来
allow zygote appdomain:dir { getattr search };
当然语法还有很多,这部分可以自行去系统学习,本文只是介绍基本的。
八、实战演习
例如一个需求:在AMS 中写 /d/rtmm/reclaim/objectfile 文件
- 首先要满足DAC验证:首先确认system system是否有objectfile文件的写权限,如果没有,修改.rc文件。具体对应是哪个文件,得去看mk了
假设system没权限,那修改owner 和 group:
on boot
chown system system /d/rtmm/reclaim/objectfile
- 然后走MAC验证:
首先AMS是在system_server进程,看看system_server的安全上下文:
mido:/d/rtmm/reclaim # ps -Z | grep "system_server"
u:r:system_server:s0 system 1533 719 2717140 357292 SyS_epoll_ 7fb57e5540 S system_server
再看看目标文件objectfile的安全上下文:
mido:/d/rtmm/reclaim # ls -Z
-rw-rw---- 1 system system u:object_r:debugfs_rtmm:s0 0 2018-10-25 18:19 objectfile
找到对应的te文件:system_server.te
allow system_server debugfs:file w_file_perms;
w_file_perms 是定义的一个宏,比纯write要好,包括了后续一些写完的收尾处理工作。
九、错误分析和解决
很多情况下,我碰到的问题是通过报错来看缺少什么权限,原则是"缺什么补什么". 看两个案例:
案例一:
audit(0.0:67):avc: denied {write } forpath="/dev/block/vold/93:96" dev="tmpfs" ino=1263scontext=u:r:kernel:s0tcontext=u:object_r:block_device:s0tclass=blk_filepermissive=0
分析过程:
缺少什么权限: { write }权限,
谁缺少权限: scontext=u:r:kernel:s0,
对哪个文件缺少权限:tcontext=u:object_r:block_device
什么类型的文件: tclass=blk_file
解决方法:kernel.te
allow kernel block_device:blk_file write;
案例二:
03-23 10:15:40.290 1422 1422 W Pipe_Write_Hand:type=1400 audit(0.0:79): avc: denied { ioctl } forpath="socket:[19308]" dev="sockfs" ino=19308scontext=u:r:system_app:s0 tcontext=u:r:bluetooth:s0 tclass=unix_stream_socketpermissive=0
03-23 10:15:40.301 1280 1422 W System.err: Java.io.IOException: Permission denie
解决方法:
在system_app.te里添加 bluetooth_domain(system_app)
原因: bluetooth.te中对bluetooth_domain属性赋予了权限
allow bluetoothdomain bluetooth:unix_stream_socket { getopt setopt getattr read write ioctl shutdown};
参考:
https://blog.csdn.net/innost/article/details/19299937#comments
https://blog.csdn.net/ztguang/article/details/62834072?utm_source=blogxgwz0
https://blog.csdn.net/hanmengaidudu/article/details/60766591
http://cn.linux.vbird.org/linux_basic/0440processcontrol_5.php