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 框架下的实现,但解决的是不同层面的安全问题。
浙公网安备 33010602011771号