Android 系统的安全策略是保护用户的隐私和数据不受侵害的重要保证,一个相对安全的计算环境对于确保移动设备的安全至关重要。随着新的威胁不断出现,Android 的安全策略也在不断发展和完善,以应对新的挑战。
一、概念介绍
1、SELinux
SELinux(Security-Enhanced Linux)是一种基于强制访问控制 MAC 的安全增强模块,最初由美国国家安全局(NSA)开发,用于提高 Linux 操作系统的安全性。
它基于 FLASK(Flux Advanced Security Kernel)模型,这是一个由美国国防部门开发的安全内核模型。SELinux 通过 LSM 接口集成到 Linux 内核中,提供了比传统的自主访问控制 DAC 更强的安全性和灵活性。SELinux 的安全策略定义了系统中的所有对象(如文件、目录、网络端口等)和主体(如进程)之间的访问关系,确保只有经过授权的操作才能被执行。
DAC
DAC 即 Discretionary Access control,⾃主访问控制,即系统只提供基本的验证,特定资源的所有者 可以控制与该资源关联的访问权限。这种系统通常⽐较粗放,并且容易出现⽆意中提权的问题。
- Linux DAC 采⽤了⼀种⾮常简单的策略,将资源访问者分成三类,分别是Owner、Group 和 Other,资源针对这三类访问者设置不同的访问权限。⽽访问权限⼜分成 read、write 和 execute。
- 访问者通常是进程,有⾃⼰的 uid/gid,通过 uid/gid 和⽂件权限匹配,来确定是否可以访问。将 root 权限根据不同的应⽤场景划分成许多的 Root Capabilities,其中如果CAP_DAC_OVERRIDE 这项的话,可以直接绕过 Linux DAC 限制。
- Linux DAC 有明显的不⾜,其中⼀个重要点就是 root 权限“⽆法⽆天”,⼏乎可以做任意情,⼀旦⼊侵者拿到 root 权限,即已经完全掌控了系统。另外,每⼀个进程默认都拿到对应这个⽤⼾的所有权限,可以改动/删除这个⽤⼾的所有⽂件资源,很明显,这个难以防⽌恶意软件。
MAC
MAC 即 Mandatory Access control,强制性访问控制, 即系统针对每⼀项访问都进⾏严格限制,每次收到访问请求时都先咨询核⼼机构,再做出决定。
- Linux MAC 针对 DAC 的不⾜,要求系统对每⼀项访问进⾏检查,每访问⼀个⽂件资源都需要进⾏对性的验证。⽽这个针对性的验证是根据已经定义好了的策略进⾏的。在 Linux Kernel,所有 MAC 机制都是搭建在 Linux Security Modules(LSM)基础上,包括有:SELinuxApparmor、Smack 和 TOMOYO Linux 等。 ⽬前 SELinux 已经成了事实上的⾏业标准。
- 针对 Linux DAC,MAC 可以明显弥补 DAC 的缺陷,⼀⽅⾯限制 root 权限,即使你有 root 权限,如果⽆法通过 MAC 验证,那么⼀样的⽆法真正执⾏相关的操作。另外对每⼀项权限进⾏了更加整的细化,可限制⽤⼾ 对资源的访问⾏为。
2、SEAndroid
SEAndroid (Security-Enhanced Android) 是 SELinux 在 Android 系统上的应用,它是在 Android 4.4 版本中正式引入的。
SEAndroid 为 Android 提供了一种基于 SELinux 的强制访问控制系统,增强了移动设备的安全性。它同样使用了 SELinux 的 MAC 模型来限制应用程序和服务的权限,从而防止恶意软件或误操作导致的数据泄露或其他安全问题。SEAndroid 的实现允许 Android 系统中的每个应用程序运行在一个受限的安全环境中,这样即使某个应用程序被攻破,攻击者也难以访问其他应用程序或系统数据。
演变过程
SELinux 在 Android 平台上的演变经历了多个阶段,逐步加强了系统的安全性。以下是各个版本的主要变化:
- 低于 Android 4.3:默认不支持 SELinux。在 Android 4.3 之前的版本中,默认情况下不启用 SELinux。SELinux 可能作为一个可选组件存在,但大多数设备并未启用。
- Android 4.3:宽容模式(Permissive Mode)。在 Android 4.3 中,SELinux 被引入并默认处于宽容模式。在宽容模式下,SELinux 会记录所有违反安全策略的行为,但不会阻止这些行为。这主要是为了让开发者和系统管理员逐渐适应 SELinux,并检查现有系统是否存在潜在的安全问题。
- Android 4.4:部分强制模式(Partial Enforcing Mode)。在 Android 4.4 中,SELinux 默认仍然是宽容模式,但在某些设备上开始尝试部分强制模式。在部分强制模式下,SELinux 对某些关键系统组件和资源进行强制访问控制。大多数设备依然处于宽容模式,但部分设备开始逐步过渡到强制模式。
- Android 5.1:默认强制模式(Enforcing Mode)。在 Android 5.1 中,SELinux 默认启用强制模式。在强制模式下,SELinux 会严格地执行安全策略,阻止所有未授权的访问。这标志着 SELinux 在 Android 平台上全面启用,并成为默认的安全机制。
- Android 8.0:强制模式且 Sepolicy 规则被分成多个部分。在 Android 8.0 中,SELinux 继续强化其安全性,并对 Sepolicy(安全策略)进行了改进。Sepolicy 规则被分成多个部分,以更好地组织和管理复杂的策略。这种拆分有助于提高策略的可读性和可维护性,同时也便于开发者和系统管理员进行更细粒度的控制。
通过这些演变,SELinux 在 Android 平台上逐步成为了重要的安全机制,显著提升了系统的安全性。
3、二者区别
- 应用场景:SELinux 主要应用于桌面和服务器环境的 Linux 系统,而 SEAndroid 是 SELinux 在移动操作系统 Android 上的具体实现。
- 定制化:SEAndroid 针对移动设备的特点进行了定制,例如,它考虑了移动设备特有的硬件组件和服务,如相机、GPS、Wi-Fi 等,以及移动应用生态系统的需求。
- 策略配置:虽然两者都基于 SELinux 的 MAC 模型,但是 SEAndroid 的安全策略可能更侧重于移动设备的安全需求,包括应用程序隔离、用户数据保护等方面。
- 兼容性:SEAndroid 在设计时考虑到了与 Android 系统的兼容性,确保在不影响用户体验的情况下提供安全增强功能。
总的来说,SEAndroid 是 SELinux 在 Android 平台上的特定实现,它继承了 SELinux 的许多特性,同时针对移动设备进行了优化和调整。
命名习惯
在 Android 平台上,尽管技术基础是 SELinux,但我们通常听到的是 SELinux 而不是 SEAndroid,这是因为:
- 命名习惯:SELinux 已经是一个广为人知的品牌和技术名词,在技术社区中有很高的知名度。因此,即使是 Android 中使用的版本,也倾向于沿用这个名称,以便于理解和沟通。
- 技术一致性:SEAndroid 实际上就是 SELinux 在 Android 系统中的一个实例化应用。它的架构和机制与 SELinux 完全相同,只是针对 Android 系统进行了一些必要的调整和适配,以适应移动设备的特殊需求。
- 品牌统一:Google 在推广 Android 安全性时,可能会选择使用更为人熟知的 SELinux 名称,而不是创造一个新的品牌 SEAndroid。这样可以利用 SELinux 的声誉来增强用户对 Android 安全性的信任。
- 文档和资料:由于 SELinux 的文档和资料非常丰富,使用 SELinux 这个术语也有助于开发者更容易地找到相关的文档和支持资料。
尽管如此,在某些场合下,特别是在讨论 Android 安全特性的具体实现时,SEAndroid 这个术语仍然会被提及,以强调这是 SELinux 在 Android 上的应用。然而,在日常交流中,SELinux 这个术语更加通用。
二、SELinux架构
1、SELinux作⽤
提⾼ Android 安全性。⾮法操作会被阻⽌,并且尝试进⾏的所有违规⾏为都会被内核记录到 dmesg 和 logcat 中。
SELinux 使⽤类型强制来改进强制访问控制。所有的主体(程序进程)对客体(⽂件/socket等资源)的访问都有⼀条 TE 规则来许可。当程序访问⼀个资源的时候,系统会搜索所有的 TE 规则集,并根据结果进⾏处理。这个规则集是由访问向量规则(AV, Access Vector)来描述的。
内核向外部暴露允许访问的资源权限,由 TE 来描述主体拥有什么样的访问权。
- TE:即 Type Enforcement,它是根据 Security Label 中的 type 进⾏权限审查,审查 subject type 对 object type 的某个 class 类型中某种 permission 是否具有访问权限,是⽬前使⽤最为⼴泛的 MAC 审查机制,简单易⽤。
- AVC:即Access Vector Cache,它是访问缓存,⽤来记录以往的访问验证情况,以便提⾼效率,快速处理。
2、SELinux架构
SELinux 是典型的 MAC - Mandatory Access Controls 实现,对系统中每个对象都⽣成⼀个安全上下⽂ (Security Context),每⼀个对象访问系统的资源都要进⾏安全上下⽂审查。审查的规则包括类型强制检测(type enforcement),多层安全审查(Multi-Level Security),以及基于⻆⾊的访问控制(RBAC: Role Based Access Control)。
整体结构
SELinux 包含五个基本组成:
- Security Policy Database:这是 SELinux 安全策略的核心部分,包含了所有的安全策略规则。这些规则定义了系统中不同安全标签(security labels)之间的访问权限。策略数据库决定了哪些主体(如进程)可以访问哪些客体(如文件),并且规定了访问的方式。
- selinuxfs:⽤于处理⽂件系统的辅助模块。它是一个虚拟文件系统,它允许 SELinux 存储和检索有关系统状态的信息,比如当前的策略设置、上下文信息等。开发者和系统管理员可以通过访问 selinuxfs 来获取或修改 SELinux 的状态和配置。
- Access Vector Cache (AVC):访问向量缓存。AVC 是一种缓存机制,用于存储最近的访问决策结果,以加速未来的访问控制决策过程。当一个访问请求首次发生时,SELinux 会根据策略数据库做出决策并将结果缓存起来。如果同样的请求再次发生,SELinux 可以直接从 AVC 中获取结果,从而提高性能。
- Policy enforcement server:⽤于验证 security context。这个组件负责实际执行安全策略,当一个进程尝试访问一个资源时,它会检查该进程的安全上下文(security context)是否允许它进行访问。如果访问请求违反了安全策略,policy enforcement server 将拒绝访问,并且可能记录 AVC 日志条目。
- 集成 Linux Security Modules 的 hooks sets:SELinux 作为 LSM(Linux Security Module)框架的一部分,使用了一系列的 hook 函数,这些函数在关键的系统调用点被调用。这些 hook 函数允许 SELinux 在适当的时候介入并实施其安全策略,从而确保所有的访问请求都符合定义的安全规则。
访问流程
访问流程如下,展示了进程通过系统调用访问某个资源时,SELinux 的验证过程:
- 进程发起系统调用:进程通过系统调用(System Call)尝试访问某个资源。
- 内核基本检测:进入内核后,首先进行一些基本的检测(如参数合法性检查等)。如果发现异常,则直接返回错误给用户空间。
- Linux Kernel DAC 审查:内核会对请求进行自主访问控制 DAC 审查。如果 DAC 检查失败,则直接返回错误给用户空间。
- 调用 LSM hooks:如果 DAC 审查通过,内核会调用 LSM 的相关 hooks。这些 hooks 允许不同的安全模块介入访问控制流程。
- SELinux hooks 进行 MAC 验证:SELinux 通过 LSM hooks 接收到访问请求,并进行强制访问控制 MAC 验证。SELinux 会检查请求的安全上下文(security context)是否允许访问目标资源。如果 MAC 验证失败,则直接返回错误给用户空间。
- 访问真正的系统资源:如果所有检查都通过,内核将继续执行系统调用,并访问真正的系统资源。
- 返回用户态,将结果反馈:内核将访问结果返回给用户态进程。
这个流程确保了 SELinux 在整个访问过程中能够有效地进行安全控制。