Selinux-1
来源:互联网 发布:js中的深拷贝和浅拷贝 编辑:程序博客网 时间:2024/05/21 05:40
SELinux 即Security-Enhanced Linux, 由美国国家安全局(NSA)发起, Secure Computing Corporation (SCC) 和 MITRE 直接参与开发, 以及很多研究机构(如犹他大学)一起参与的强制性安全审查机制, 该系统最初是作为一款通用访问软件,发布于 2000 年 12 月(代码采用 GPL 许可发布)。并在Linux Kernel 2.6 版本后, 有直接整合进入SELinux, 搭建在Linux Security Module(LSM)基础上, 目前已经成为最受欢迎,使用最广泛的安全方案.
2. SELinux 基本架构与原理.
SELinux 是典型的MAC-Mandatory Access Controls 实现, 对系统中每个对象都生成一个安全上下文(Security Context), 每一个对象访问系统的资源都要进行安全上下文审查。审查的规则包括类型强制检测(type enforcement), 多层安全审查(Multi-Level Security), 以及基于角色的访问控制(RBAC: Role Based Access Control).
SELinux 搭建在Linux Security Module(LSM)基础上, 关于 LSM 架构的详细描述请参见文章 “Linux Security Modules: General Security Support for the Linux Kernel”, 该文章在 2002 年的 USENIX Security 会议上发表。有完整的实现LSM 的所有hook function.
SELinux 的整体结构如下图所示:
P-1-1-1: 整体流程图
SELinux 包含五个基本组成:
* 集成Linux Security Modules 的hooks sets.
* Security Policy Database.
* Security Label 验证模块.
* Access Vector Cache (AVC), 访问向量缓存,以便提高验证速度.
基本的访问流程如下图所示:
P-1-1-2: 访问流程图
流程如下:
* 进程通过系统调用(System Call) 访问某个资源, 进入Kernel 后, 先会做基本的检测, 如果异常则直接返回.
* Linux Kernel DAC 审查, 如果异常则直接返回.
* 调用Linux Kernel Modules 的相关hooks, 对接到SELinux 的hooks, 进而进行MAC 验证, 如果异常则直接返回.
* 访问真正的系统资源.
* 返回用户态, 将结构反馈.
2.SELinux and SEAndroid
Android 是建立在标准的Linux Kernel 基础上, 自然也可以开启SELinux, 通常在通用移动平台上, 很少开启这样的安全服务, Google 为了进一步增强Android 的安全性, 经过长期的准备,目前已经在Android 5.0(L) 上有完整的开启SELinux, 并对SELinux 进行深入整合形成了SEAndroid.
2. SELinux 在Android 上的更新历史
如下图所描述:
P-1-2-1 SELinux 在Android 的更新过程
* KK 4.4 针对netd, installd, zygote, vold 四个原本具有root 权限的process, 以及它们fork 出的子进程启用Enforce 模式.
* L 版本普遍性开启SELinux Enforce mode.
* Permissive 模式,只打印audit 异常LOG,不拒绝请求, Enforce 模式,即打印audit 异常LOG, 也拒绝请求
估计后续版本Google 都会要求强制性开启SELinux, 以保证手机安全.
* 严格限制了ROOT 权限, 以往ROOT “无法无天” 的情况将得到极大的改善.
* 通过SELinux 保护, 降低系统关键进程受攻击的风险, 普通进程将没有权限直接连接到系统关键进程.
* 进一步强化APP 的沙箱机制, 确保APP 难以做出异常行为或者攻击行为.
* 将改变APP 一旦安装, 权限就已经顶死的历史, APP 权限动态调整将成为可能.
SELinux and SEAndroid
3.SELinux Mode
1. SELinux Mode.
SELinux 分成两种模式, 即Permissve Mode(宽容模式), 和 Enfocing mode(强制模式).
Permissive Mode 只通过Audit System 记录LOG, 但不真正拦截访问.
Enforcing Mode 在打印LOG 的同时,还会真正的拦截访问.
通常在调试时,我们会启用Permissive Mode, 以便尽可能的发现多的问题, 然后一次修正. 在真正量产时使用Enforcing mode, 来保护系统.
SELinux Basic Theory
4.DAC and MAC
1. DAC and MAC
DAC 即 Discretionary Access control, 自主访问控制, 即系统只提供基本的验证, 完整的访问控制由开发者自己控制。
MAC 即 Mandatory Access control, 强制性访问控制, 即系统针对每一项访问都进行严格的限制, 具体的限制策略由开发者给出.
2. Linux DAC
Linux DAC 采用了一种非常简单的策略, 将资源访问者分成三类, 分别是Owner, Group, Other; 资源针对这三类访问者设置不同的访问权限. 而访问权限又分成 read, write, execute.
访问者通常是进程有自己的uid/gid, 通过uid/gid 和 文件权限匹配, 来确定是否可以访问.
将Root 权限根据不同的应用场景划分成许多的Root Capabilities, 其中如果有CAP_DAC_OVERRIDE 这项的话, 可以直接绕过Linux DAC 限制.
Linux DAC 有明显的不足, 其中一个重要点就是, Root 权限 “无法无天”, 几乎可以做任意事情, 一旦入侵者拿到root 权限, 即已经完全掌控了系统. 另外每一个进程默认都拿到对应这个用户的所有权限, 可以改动/删除这个用户的所有文件资源, 明显这个难以防止恶意软件.
3. Linux MAC
Linux MAC 针对DAC 的不足, 要求系统对每一项访问, 每访问一个文件资源都需要进行针对性的验证. 而这个针对性的验证是根据已经定义好了的策略进行. 在Linux Kernel, 所有的MAC 机制都是搭建在Linux Security Modules (LSM) 基础上, 包括有: SELinux、Apparmor、Smack 和 TOMOYO Linux等。目前SELinux 已经成了事实上的行业标准.
针对Linux DAC, MAC 可以明显弥补DAC 的缺陷, 一方面限制Root 权限, 即使你有root 权限, 如果无法通过MAC 验证, 那么一样的无法真正执行相关的操作. 另外对每一项权限进行了更加完整的细化, 可限制用户对资源的访问行为.
5.Core SELinux Components and Security Context
SELinux 的核心组件可以参考下面的图:
P-2-1-1 SELinux 核心组件
* Subject 通常是指触发访问行为的对象, 在Linux 里面通常是一个进程(Process).
* Object Manager 即是对象访问管理器, 即可以知道Subject 需要访问哪些资源,并且触发验证机制
* Security Server 即安全服务器, 用来验证某个Subject 是否可以真正的访问某个Object, 而这个验证机制是基于定义好的Security Policy.
* Security Policy 是一种描述SELinux Policy 的语言.
* Access Vector Cache (AVC) 是访问缓存, 用来记录以往的访问验证情况, 以便提供效率,快速处理.
2. Security Context
SELinux 给Linux 的所有对象都分配一个安全上下文(Security Context), 描述成一个标准的字符串。
两种类型
* Subject 主体, linux通常以进程为单位
* Object 访问对象, linux 通常以文件为单位
user:role:type[:range]
* User: 用户, 非Linux UID。
* Role: 角色,一个user可以属于多个role,不同的role具有不同的权限。它是SELinux中一种比较高层次,更方便的权限管理思路,即Role Based Access Control(基于角色的访问控制,简称为RBAC, SELinux 不推荐使用)。
* Type: Subject或者Object的类型。 MAC的基础管理思路其实不是针对上面的RBAC,而是所谓的Type Enforcement Access Control(简称TEAC,一般用TE表示)。对进程来说,Type就是Domain。
* Range: Multi-Level Security(MLS)的级别。MLS将系统的进程和文件进行了分级,不同级别的资源需要对应级别的进程才能访问。
P-2-2-2 对象类型和权限项关系.
每一个对象都有一个Class, 比如一支文件, 它是File Class 类型, 每个Class 类型都会根据实际情况定义权限类型项, 如: read, write, exec, ioctl, append 等等.
Subject 即前面提到的主体,它能够产生访问行为, Linux 里面通常是一个process, 但process 本身也可能是一个Object, 比如另外一个进程对它发送Signal, 比如去对它进行Ptrace 操作.
3. 查看Security Context
* 查看进程的Security Context 用: ps -Z 或者cat proc/PID/attr/current, 查看当前进程可用id, 如:
P-2-2-3 ps 查询进程Security Context
6.Type Enforcement Access Control
* Type Enforcement (TE)
顾名思义, Type Enforcement 是根据Security Label 中的 type 进行权限审查, 审查 subject type 对 object type 的某个class 类型中某种permission 是否具有访问权限,是目前使用最为广泛的MAC 审查机制, 简单易用。
多层安全机制, 是基于Bell-La Padula (BLP) 模型, 将Subject 和 Object 定义成多层次的安全等级, 不同安全等级之间有相关的访问约束, 常见的访问约束是 "no write down" 和 "no read up". 它是根据Security Label 里面的最后一个字段label 进行确认的.
目前在Android 中,重点启用了Type Enforcement 机制, Multi-Level Security (MLS) 虽然有定义, 但没有真实的投入使用, 这里暂时略过。
2. Type Enforcement Access Control
rule_name source_type target_type : class perm_set
* rule: 控制类型, 分成两方面 allow 以及 audit
* source_type:也叫subject,通常是domain。
* Target_type: 代表请求的资源的类型
* class perm_set: 代表对资源访问的操作
3. Rule of Type Enforcement
如下表所示:
P-2-3-1 TEAC-Rule
* allow:赋予某项权限。
* auditallow:audit含义就是记录某项操作。默认SELinux只记录那些权限检查失败的操作。 auditallow则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使用allow语句。
* dontaudit:对那些权限检查失败的操作不做记录。
* neverallow:前面讲过,用来检查安全策略文件中是否有违反该项规则的allow语句
下面一段是截取的init.te 中的一部分
# Create /data/property and files within it.
allow init property_data_file:dir create_dir_perms;
allow init property_data_file:file create_file_perms;
allow init property_type:property_service set;
allow init self:udp_socket { create ioctl };
# set scheduling parameters for a kernel domain task.
allow init kernel:process setsched;
# never via an exec-based transition.
neverallow { domain -kernel} init:process dyntransition;
neverallow domain init:process transition;
neverallow init { file_type fs_type }:file entrypoint;
7.Domain and Object Transitions
在SELinux 中, 我们通常称一个进程是一个domain, 一个进程fork 另外一个进程并执行(exec) 一个执行档时, 我们往往会涉及到domain 的切换. 比如init 进程, SELinux 给予了它很大的权限, 而它拉起的服务, 我们要限制这个服务的权限,于是就涉及到从一个domain 切换到另外一个domain, 不然默认就使用init 进程的domain.
在SELinux 里面有专门的一条语法:
type_transition statement.
*. The source domain has permission to transition into the target domain.
源domain 必须有权限切换到这个目标domain.
*. The application binary file needs to be executable in the source domain.
源doamin 必须要有执行这个执行档的权限.
*. The application binary file needs an entry point into the target domain.
这个执行档必须是目标domain 的入口(Entry Point)
allow init_t apache_exec_t : file {read getattr execute};
allow init_t apache_t : process transition;
allow apache_t apache_exec_t : file entrypoint;
type_transition init_t apache_exec_t : process apache_t;
2. Object Transitions
一个进程创建在一个目录下创建文件时, 默认是沿用父目录的Security Context, 如果要设置成特定的Label, 就必须进行Object Transitions.
type_transition statement.
对应的必须有两个前提条件:
* The source domain needs permission to add file entries into the directory
这个process 必须有在这个目录下添加文件的权限.
* The source domain needs permission to create file entries
这个process 必须有在这个目录下创建以这个Security Context 为Label 的文件权限.
下面是一个demo, ext_gateway_t 这个domain 在类型为in_queue_t 的目录下,创建类型为 in_file_t 的文件.
#首先,你得让ext_gateway_t 对in_queue_t 目录具备访问权限
allow ext_gateway_t in_queue_t : dir { write search add_name };
allow ext_gateway_t in_file_t : file { write create getattr };
type_transition ext_gateway_t in_queue_t : file in_file_t;
P-2-4-1 对象domain 切换结果
Domain and Object Transitions
8.SEAndroid API
SELinux 在Kernel 中实现, 统一对外的接口都集中在SELinux File System 当中, 即通过读写相关文件的方式来达成。
SELinux File System 在比较新的Linux Kernel 中被mount 在/sys/fs/selinux. 老的版本就直接是/selinuxfs
具体每一只文件的说明, 请参考:
The SELinux Notebook: 2.19.2.3 SELinux Filesystem
2. SELinux Lib
所有SELinux Lib 几乎都是对selinuxfs 的封装, 具体的API 可以参考:
The SELinux Notebook: 9. APPENDIX B - LIBSELINUX LIBRARY FUNCTIONS
在android 上, Google 有进一步对这些API 进行封装, 具体都在/external/libselinux 下面, 下面对一些重要的API 进行说明. (参考: http://selinuxproject.org/page/NB_SEforAndroid_1)
selinux_android_setcontext
It is called by frameworks/base/core/jni/com_android_internal_os_Zygote.cpp when forking a new process and the system/core/run-as/run-as.c utility.
The function is used by the package installer within frameworks/native/cmds/installd/commands.c via the package install() and make_user_data() functions.
- Selinux-1
- SELinux详解(1)
- Centos7.1 SELinux
- SElinux 1 背景,框架
- Android7.1 Selinux使用
- selinux
- SELinux
- SELinux
- SELinux
- SELinux
- SELinux
- selinux
- SELinux
- SElinux
- Selinux
- SELinux
- SElinux
- selinux
- 第五周上机项目2 对象作为数据成员
- 预处理器,编译器,汇编器和链接器
- 统计语言模型学习笔记
- Android教程-从零开始一步一步接入SDK
- 用xcode发布cocos2d-x游戏相关 第二讲
- Selinux-1
- what is maven?
- MFC常用数据类型:
- C++中,内联函数和宏定义的区别是什么?
- SQL基本语句
- 1142 NOJ 最大连续和
- git- 利用分支进行开发的工作流程
- 1162 Eddy's picture
- OpenLayer基础学习