LSM一瞥

本文涉及的产品
访问控制,不限时长
简介: LSM一瞥
  • LSM是什么?
  • 主、次、独占LSM模块
  • SELINUX – 安全增强的Linux
  • SMACK – 简化的强制访问控制
  • APPARMOR
  • TOMOYO
  • LOADPIN
  • YAMA
  • SAFESETID
  • LOCKDOWN LSM
  • 结论


我猜,你读这篇文章,说明你已经对Linux安全模块(LSM)有所了解。如果你使用过SELinuxAppArmor,其实就已经用过LSM了。甚至,在你使用的Linux发行版本或Android系统之上,也使用了LSM

内核5.4版本内,有8个LSM模块:SELinuxSMACKAppArmorTOMOYOYamaLoadPinSafeSetIDLockdown。还有一些LSM模块在开发中,比如SARAKRSI,也许不久就会合入Linux内核源码中。如果你是关注安全的系统或软件工程师,理解为什么有这么多的LSM模块是非常值得的。它们有一些是解决通用问题,有一些则是解决特定问题。意识到它们的差异,才能更好地理解Linux的安全特性。


LSM是什么?


一个LSM模块是直接编译Linux内核的代码,利用LSM框架,它可以拒绝某个进程访问重要的内核对象。这些对象包括:文件、inode、任务控制块、凭证和进程间通信对象。通过指定允许的交互,安全管理员可以让攻击者很难利用程序的缺陷从而攻击系统的其它部分。

LSM框架的第一个,也是最流行的使用场景是强制访问控制(MAC)策略。毫无疑问,在内核中实现MAC策略的方法有多种。2001年,美国国家安全局的Peter LoscoccoLinux 2.5 内核峰会上展示了首个实现。Linux Weekly NewsJonathan Corbet后来指出:

经过这么多年的发展,这些标准接口已经形成了LSM框架。截止到5.4内核,该框架已经包含224hook点,这些hook点包含一个注册函数的API和为LSM模块保留受保护内核对象所使用的内存的API。到Linux 2.6版本,LSM框架和SELinux合并到了内核主线中(使用LSM框架,而不是直接在内核代码中修改)。尽管LSM框架的实现,随着时间的不断推移而发生变化,但是它实现对重要内核对象的细粒度访问控制的基本目标没有改变。

目前的LSM框架已经允许用户将多个LSM模块编译进内核,存储在内核的堆栈空间中,并同时使用它们。下图展示了一个文件打开(open())操作的简略调用流程图(假设为3个LSM模块注册了hook钩子函数。

  1. 用户态进程调用open(),打开一个文件;
  2. 调度系统调用,使用文件路径作为获取内核文件对象的参数。如果参数非法,返回错误。
  3. 正常的自由访问控制(Discretionary Access Control)文件访问权限检查。如果没有权限,系统调用终止,返回给用户错误。
  4. 如果满足DAC控制,则LSM框架为每个使能的LSM模块调用file_opne钩子函数。任何一个LSM钩子函数返回错误,则系统调用终止,并返回给用户错误。
  5. 如果所有的安全检查通过,则为该进程打开该文件,并返回给用户态进程一个新的文件描述符fd

640.jpg


主、次、独占LSM模块


LSM有了初认识之后,我们再来看各个LSM模块能做什么。首先,我们先看看早期的主LSM模块:SELinuxSMACKAppArmorTOMOYO,它们都是MAC访问控制策略的实现,从用户空间加载配置策略。他们都以自己的方式解决相同的问题。

早期的LSM框架一次只能允许加载一个LSM模块。所有的主LSM模块都假设自己独占内核保护对象的指针或标识符。因此,所以一次只能使用一个主LSM模块。可以在编译内核时选择编译进镜像,如下图所示;也可以通过内核命令行参数传递。


640.png


LSM框架不断优化,已经消除了主、次LSM模块之间的区别。现在区分主、次LSM模块的优选方法是使用LSM_FLAG_EXCLUSIVE独占标志。一个用户可以配置多个LSM,只要给其中的一个设置LSM_FLAG_EXCLUSIVE标志即可。

LSM是将大部分策略直接编码到内核代码中。通常情况下,次LSM模块只有enable/disable选项,而不是将策略文件在系统启动时从用户空间加载。


SELINUX – 安全增强的Linux


SELinux最早是在Linux2.6版本合入内核的,RedHat发布的Linux发行版将其作为默认的MAC强制访问策略。它以功能强大和复杂著称。

SELinux基于属性实现,将文件的安全属性存储在文件系统的扩展文件属性中。比如,使用ls -Z /bin/bash文件的安全属性,如下所示。我们可以看到有四个:冒号分割的属性,分别代表user:role:type:level

$ ls -Z /bin/bash
-rwxr-xr-x. root root system_u:object_r:shell_exec_t:s0 /bin/bash

SELinux的常用方法是指定主体(在此也就是指user)对某种类型的对象采取什么动作。再看上面的ls的输出,自由访问控制(DAC)权限表示所有的用户都允许读、执行bash,但使用 SELinux,安全管理员可以进一步指定允许执行或读取策略文件中的shell_exec_t类型文件的主体。比如说,安全工程师不许web服务器执行shell,因为web服务器易受远程攻击。

SELinux使用扩展属性实现的副作用是,对于那些不支持扩展属性的文件系统中对象无法保护,比如挂载NFSv4版本的NFS文件系统。

由于SELinux的复杂性和强大功能,可以参考Red Hat’s SELinux User’s and Administrator’s Guide获取更多信息。


SMACK – 简化的强制访问控制


SELinux一样,SMACK也是基于文件扩展属性的MAC实现,是开发者合并到Linux内核中的第二个LSM模块(2.6.24)。但是与SELinux不一样的是,SMACK是专为嵌入式系统设计的,对于系统管理员来说更简单。SMACK是车级LinuxAGL)和Tizen操作系统的默认MAC实现。


APPARMOR


AppArmor是另一种MAC实现,最初由Immunix开发,2.6.36版本合入内核。AppArmor是基于 Debian的系统的主要MAC实现。

除了减少了工具数量和复杂性之外,AppArmorSELinux最大的不同就是,它是基于Path而不是基于属性。

基于Path的实现有利有弊。积极的一面是,基于Path的策略可以保护任何文件系统的文件,因为存储安全信息不需要扩展属性。甚至可以为不存在的文件指定安全规则,因为这种方式下,可以将Path存储在配置文件中而无需标注任何实际的文件或目录。另一方面,最常被提及的负面影响是,因为能够创建硬链接,对于同一个物理文件可能存在多个Path。那么,单个文件的安全策略可能会因为不同的Path而不同,这可能会导致安全漏洞。


TOMOYO


AppArmor一样,TOMOYO是另一个基于PathMAC实现,Linux 2.6.30版本首次合入。TOMOYO是专为嵌入式系统设计的,允许安全管理员在测试时记录所有的用户进程交互,从而根据开发、测试期间互相看见的进程才能够交互。如果使用了TOMOYO策略的系统,落入不可信的用户或敌对环境中,用户态进程仅执行那些之前允许的交互,简化了策略生成。


LOADPIN


LoadPin,是一个次LSM模块,Linux4.7版本合入,用以保证加载内核的所有文件(内核模块、固件等)来自相同的文件系统,并期望这样的文件系统是由只读的设备提供。这旨在简化从只读设备启动的嵌入式系统,让其无需对内核模块进行签名或检查。

因为简单易用,LoadPin能够简化某些类型的嵌入式系统的内核免受恶意代码攻击的过程。


YAMA


YamaLinux 3.4合入内核的LSM模块,旨在收集主内核没有处理的系统内的DAC安全限制。目前,它支持缩小ptrace()系统调用的范围,阻止通过已经攻击成功的用户进程作为跳板,从相同用户的其它进程中抽取敏感数据信息。


SAFESETID


SafeSetID是在Linux 5.1版本合入的一个LSM模块,用来限制将UID/GID转换成白名单中允许的那些UID/GID

我认为Linux内核中对SafeSetID使用场景的描述是非常准确的:

This can be used to allow a non-root program to transition to other untrusted uids without full blown CAP_SETUID capabilities. The non-root program would still need CAP_SETUID to do any kind of transition, but the additional restrictions imposed by this LSM would mean it is a “safer” version of CAP_SETUID since the non-root program cannot take advantage of CAP_SETUID to do any unapproved actions (e.g. setuid to uid 0 or create/enter new user namespace). The higher level goal is to allow for uid-based sandboxing of system services without having to give out CAP_SETUID all over the place just so that non-root programs can drop to even-lesser-privileged uids. This is especially relevant when one non-root daemon on the system should be allowed to spawn other processes as different uids, but its undesirable to give the daemon a basically-root-equivalent CAP_SETUID.

通俗的说就是,如果非特权程序想要生成具有不同uid的进程时,无需赋予其CAP_SETUID能力,而是通过SafeSetID就可以修改uid

— Documentation/admin-guide/LSM/SafeSetID.rst


LOCKDOWN LSM


lockdown是Linux 5.4版本合入内核的,实现对kernel锁定。启用了lockdown功能后,就可以通过内核命令行参数锁定kernel,以便保护其完整性和机密性。当设置lockdown为保护完整性,它的特性就不允许用户空间修改kernel。这些特性包括:未签名的内核模块加载,访问/dev/{mem,kmem,port},访问/dev/efi_test,未签名镜像的执行,休眠,直接PCI访问,原始IO端口访问,原始MSR访问,修改ACPI表,直接PCMCIA CIS存储,串行端口的重新配置,不安全的内核模块参数,不安全的MMIO内存,以及debugfs访问。当设置lockdown为保护机密性时,所有的完整性保护都被启用,另外还要禁止的功能有:用户空间从正在运行的内核中提取潜在的机密信息,例如/proc/kcore访问,使用kprobebpf读取内核RAMperf 的不安全使用以及tracefs的使用。

lockdown可以通过SELinuxAppArmorSMACK、或TOMOYO策略文件实现,这种基于静态策略的独立LSM策略文件的实现方式,意味着它可以跨平台运行,而无关于具体的MAC实现机制。


结论


LSM并不是专门设计用来阻止对进程攻击的工具。良好的编程实践,配置管理和内存安全的编程语言才是实现阻止攻击的工具。但是,当系统中运行的程序存在漏洞时,LSM确实能够阻止利用漏洞攻击系统的其它组件。所以说,LSMLinux系统纵深防御的重要一层,通过理解它们能够提供什么保护,可以增加对保护系统的哪些部分以及如何实现这些保护有一个更好的理解。

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
云安全基础课 - 访问控制概述
课程大纲 课程目标和内容介绍视频时长 访问控制概述视频时长 身份标识和认证技术视频时长 授权机制视频时长 访问控制的常见攻击视频时长
相关文章
|
3月前
|
存储 关系型数据库 MySQL
"揭秘!MySQL为何独宠B+树?跳表再牛,也敌不过这性能王者的N重诱惑!"
【8月更文挑战第11天】MySQL作为主流关系型数据库,优选B+树而非跳表作为索引结构,基于其对范围查询的支持、低磁盘I/O开销及事务处理能力。B+树叶节点构成有序链表,利于范围查询;较矮的树形结构减少了磁盘访问次数;支持多版本并发控制,保障事务ACID特性。而跳表在线性扫描范围查询时效率低,难以高效实现事务管理,且额外指针增加空间消耗。示例代码展示了B+树节点分裂过程,突显其内部机制。综上,B+树为MySQL提供了高性能、可靠的数据存储与检索能力。
121 4
|
5月前
|
存储 NoSQL 大数据
【大数据】LSM树,专为海量数据读写而生的数据结构
【大数据】LSM树,专为海量数据读写而生的数据结构
102 0
|
6月前
|
存储 并行计算 算法
列式存储的另一面
列存是常见的数据存储技术,说到列存常常就意味着高性能,现代分析型数据库基本都会把列存作为标配, 列存的基本原理是减少硬盘的读取量。一个数据表有多个列,但运算可能只会用到其中少数几列,采用列存时,用不着的列就不必读出来了,而采用行式存储时,则要把所有列都扫描一遍。当取用列只占总列数的小部分时,列存的 IO 时间优势会非常大,就会显得计算速度快了很多。 不过,列存也有另一面,并不是在任何场景下都有优势。
|
存储 缓存 程序员
【深度长文】还是没忍住,聊聊神奇的无锁队列吧!
【深度长文】还是没忍住,聊聊神奇的无锁队列吧!
827 0
|
存储 分布式数据库 数据库
海量数据超快查询的秘密-跳表思想 by彭文华
海量数据超快查询的秘密-跳表思想 by彭文华
|
SQL 存储 分布式数据库
如何同时兼顾多维分析和快速查询的需求?Kudu来帮忙!彭文华
如何同时兼顾多维分析和快速查询的需求?Kudu来帮忙!彭文华
|
存储 小程序 编译器
”神仙修炼“之C的数据存储
char //字符型,所占存储空间为1字节int //基本整形,所占存储空间为4字节unsigned int //无符号整型,所占存储空间为4字节long (int) //长整型,所占存储空间为4/8字节unsigned long //无符号长整型,所占存储空间为4/8字节long long (int) //长长整型,所占存储空间为8字节short (int) //短整型,所占存储空间为2字节unsigned short //无符号短整型,所占存储空间为2字节。
99 0
|
存储 SQL 缓存
如何基于LSM-tree架构实现一写多读
PolarDB是阿里巴巴自研的新一代云原生关系型数据库,在存储计算分离架构下,利用了软硬件结合的优势,为用户提供具备极致弹性、海量存储、高性能、低成本的数据库服务。X-Engine是阿里巴巴自研的新一代存储引擎,作为AliSQL的核心引擎之一已广泛用于阿里巴巴集团核心业务,包括交易历史库,钉钉历史库,图片空间等。PolarDB历史库是基于LSM-tree架构实现一写多读的新产品,在存储分离技术的加成下,利用X-Engine的高压缩特性,为用户带来极致的低成本体验。
702 1
如何基于LSM-tree架构实现一写多读
好大一棵树,新春的祝福(一):n级分类的数据结构
目录           1、n级分类的数据结构           2、我的树的数据结构和页面展现           3、在权限方面的应用          快过年了,先给大家拜个早年,祝大家新的一年里多多发财,呵呵。
1134 0