AIGC标识 SELinux、AppArmor、landlock 技术

一、SELinux、AppArmor、Landlock 与 LSM 的关系

三者都是 LSM(Linux Security Module)框架下的实现。

但它们的设计目标、使用场景、权限模型差异很大。


二、LSM 框架:一个"插槽"

LSM 本身不是一个安全策略,而是一个框架(框架 = 一组钩子接口)

⚠️注意:安全是横切关注点,linux安全机制散布在内核不同层次,Linux 中很多安全机制并不都是 LSM:

  • seccomp:系统调用入口过滤;
  • LSM:内核对象访问控制钩子;
  • capabilities:进程权限位,部分由 commoncap LSM 实现;
  • namespaces:资源视图隔离,如 PID、mount、network;
  • cgroups:资源限制与分组;
  • audit:安全审计;
  • Landlock:可堆叠 LSM,限制文件、网络、IPC 访问。

所以不能简单说“安全 = LSM”。LSM 只是安全访问控制的一种框架

┌─────────────────────────────────────────────────┐
│              LSM 框架 (security/)                │
│                                                 │
│   提供钩子(Hooks):                            │
│   - security_file_open()                        │
│   - security_inode_permission()                 │
│   - security_socket_connect()                   │
│   - security_bprm_creds_for_exec()              │
│   - ... (200+ 个钩子)                           │
│                                                 │
│   安全模块注册回调函数到这些钩子上:              │
│                                                 │
│   ┌──────────┐ ┌──────────┐ ┌──────────┐       │
│   │ SELinux  │ │ AppArmor │ │ Landlock │ ...   │
│   └──────────┘ └──────────┘ └──────────┘       │
│                                                 │
└─────────────────────────────────────────────────┘

当内核执行到某个关键操作时(如打开文件),会调用对应的 LSM 钩子,所有注册到该钩子的安全模块都会依次执行检查。


三、三者详细对比

维度 SELinux AppArmor Landlock
是 LSM? ✅ 是 ✅ 是 ✅ 是
安全模型 基于标签(Label-based) 基于路径(Path-based) 基于路径(Path-based)
配置方式 系统管理员编写策略 系统管理员编写 Profile 进程自己通过系统调用配置
需要 root? ✅ 需要 ✅ 需要 不需要
作用范围 系统全局 系统全局(按程序) 单个进程及其子进程
典型用户 RHEL/CentOS/Fedora Ubuntu/SUSE/Debian 应用程序开发者
引入版本 Linux 2.6 (2003) Linux 2.6.36 (2010) Linux 5.13 (2021)
源码目录 security/selinux/ security/apparmor/ security/landlock/

四、核心区别:谁来配置?控制谁?

1. SELinux / AppArmor(系统管理员控制)

系统管理员 (root)
    │
    │  编写安全策略
    ▼
┌─────────────────────────────────────┐
│  安全策略数据库                      │
│  "httpd 只能读 /var/www/"           │
│  "sshd 不能写 /etc/"                │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  LSM 钩子拦截所有进程的操作          │
│  根据策略判断:允许 / 拒绝           │
└─────────────────────────────────────┘
  • 管理员制定规则,所有进程必须遵守
  • 进程自己无法修改自己的权限
  • 属于强制访问控制(MAC)

2. Landlock(进程自己控制自己)

应用程序开发者
    │
    │  在代码中调用 Landlock 系统调用
    ▼
┌─────────────────────────────────────┐
│  进程启动时:                        │
│  1. landlock_create_ruleset()       │
│  2. landlock_add_rule()             │
│     "我只需要读 /tmp/mydata/"       │
│  3. landlock_restrict_self()        │
│     "从现在起,限制我自己的权限"      │
└─────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  该进程及其子进程被沙箱化            │
│  无法访问规则之外的文件              │
│  即使进程被攻破,攻击者也无法逃逸     │
└─────────────────────────────────────┘
  • 进程自己限制自己(类似 seccomp 的思路)
  • 不需要 root 权限
  • 属于应用级沙箱

代码示例(Landlock)

#include <linux/landlock.h>
#include <sys/syscall.h>
#include <sys/prctl.h>

int main() {
    // 1. 创建规则集
    struct landlock_ruleset_attr ruleset_attr = {
        .handled_access_fs =
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_WRITE_FILE |
            LANDLOCK_ACCESS_FS_REMOVE_FILE |
            // ... 其他权限
    };

    int ruleset_fd = syscall(SYS_landlock_create_ruleset,
                             &ruleset_attr, sizeof(ruleset_attr), 0);

    // 2. 添加规则:允许读写 /tmp/mydata/
    struct landlock_path_beneath_attr path_beneath = {
        .allowed_access =
            LANDLOCK_ACCESS_FS_READ_FILE |
            LANDLOCK_ACCESS_FS_WRITE_FILE,
        .parent_fd = open("/tmp/mydata/", O_PATH | O_DIRECTORY),
    };

    syscall(SYS_landlock_add_rule, ruleset_fd,
            LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0);

    // 3. 禁止后续提权
    prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);

    // 4. 应用限制(不可逆!)
    syscall(SYS_landlock_restrict_self, ruleset_fd, 0);

    // 从现在起,这个进程只能访问 /tmp/mydata/
    // 即使进程被攻破,攻击者也无法读取 /etc/passwd
    
    // ... 进程的正常逻辑 ...
}

五、在内核中的共存关系

现代内核支持多个 LSM 同时加载

┌─────────────────────────────────────────────────────────┐
│                    LSM 框架                              │
│                                                         │
│  主要模块(通常只能选一个):                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │ SELinux  │  │ AppArmor │  │  Smack   │              │
│  └──────────┘  └──────────┘  └──────────┘              │
│                                                         │
│  次要模块(可以叠加多个):                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐              │
│  │ Landlock │  │   Yama   │  │ BPF-LSM  │              │
│  └──────────┘  └──────────┘  └──────────┘              │
│  ┌──────────┐  ┌──────────┐                             │
│  │ LoadPin  │  │SafeSetID │                             │
│  └──────────┘  └──────────┘                             │
│                                                         │
└─────────────────────────────────────────────────────────┘

“主”LSM(或称“排他性”LSM):SELinux、AppArmor 都属于“主”LSM。它们的设计和标签机制存在冲突,因此通常互斥,不能同时激活。
“次”LSM:Landlock(非特权沙箱)是典型的“次”LSM。它们可以与任何一个“主”LSM共存,提供额外的防护层

典型组合

目前LSM的堆叠(Stacking)机制遵循一个核心规则:同一时间只能有一个“主”LSM(Major LSM)处于活动状态,但可以同时存在任意数量的“次”LSM(Minor LSM)

发行版 主要 LSM 次要 LSM
RHEL / CentOS / Fedora SELinux Yama, BPF-LSM
Ubuntu / Debian AppArmor Yama, Landlock
SUSE AppArmor Yama
Android SELinux -

注意:SELinux 和 AppArmor 通常不能同时启用(策略模型冲突),但 Landlock 可以和任何一个共存。
可以通过 cat /sys/kernel/security/lsm 命令查看当前系统激活的LSM列表


六、与 seccomp子系统 的关系(回顾)

用户态进程
    │
    ▼
┌─────────────────────────────────────────────┐
│  seccomp(系统调用过滤)                     │  ← 第一道关卡
│  "是否允许调用 open()?"                     │     (最外层)
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│  LSM 钩子(安全模块检查)                    │  ← 第二道关卡
│                                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐    │
│  │ SELinux  │ │ AppArmor │ │ Landlock │    │
│  │ 或       │ │ 或       │ │ (叠加)   │    │
│  └──────────┘ └──────────┘ └──────────┘    │
│                                             │
│  "进程有没有权限打开这个文件?"               │     (子系统内部)
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│  DAC(传统权限检查)                         │  ← 第三道关卡
│  "文件权限位:rwx, 所有者/组"               │     (最内层)
└─────────────────────────────────────────────┘

七、总结

问题 答案
SELinux 是 LSM 吗? ✅ 是,基于标签的系统级 MAC
AppArmor 是 LSM 吗? ✅ 是,基于路径的系统级 MAC
Landlock 是 LSM 吗? ✅ 是,但是进程自沙箱,不需要 root
它们能同时工作吗? SELinux/AppArmor 二选一,Landlock 可叠加
和 seccomp 的关系? seccomp 在 LSM 之前执行,两者互补

一句话总结

SELinux 和 AppArmor 是管理员配置的系统级安全策略,Landlock 是开发者配置的应用级沙箱,三者都是 LSM 框架下的实现,但解决的是不同层面的安全问题。

posted @ 2026-09-22 14:00  悠哉大斌  阅读(5)  评论(0)    收藏  举报