Landlock 作为 Linux 内核 LSM(Linux Security Module)框架的一部分,自 5.13 版本引入,专为非特权进程设计文件系统沙盒机制。它允许进程主动附加策略,限制自身及子进程对文件系统的访问,而无需 root 权限或 ptrace 跟踪。这种设计类似于 seccomp 的 syscall 过滤,但聚焦于细粒度 FS 操作拦截,通过 LSM 钩子在 VFS 层生效,避免了传统沙盒如 AppArmor/SELinux 的复杂配置。
与其他机制相比,Landlock 的核心优势在于栈式可组合性和不可逆限制。Seccomp 过滤系统调用,无法精确控制 FS 路径权限(如允许读 /home 但禁写 /etc),而 Landlock 使用 path_beneath 规则精确限定子树访问。“Landlock LSM 主要给非特权进程提供安全沙盒的能力,比如你可以对一个普通进程,施加自定义的文件系统访问控制策略。” 它与 seccomp 互补:前者管 FS 路径,后者管 syscall,常在 AI 工具如 Codex 中组合使用,形成双层防护。
附加策略的核心流程依赖三个系统调用:landlock_create_ruleset 创建规则集 FD、landlock_add_rule 添加规则、landlock_restrict_self 绑定到当前线程。一旦 restrict_self,策略不可撤销或扩展,确保最小权限原则。ABI 版本控制兼容性:v1 仅 FS 基本权限(READ_FILE|WRITE_FILE),v4 扩展网络端口控制,但 FS 沙盒优先 v3(添加 MAKE_* 权限)。
规则构建参数与清单
构建高效 ruleset 需关注 handled_access_fs 位掩码与规则优先级。典型 FS 权限位:
| 权限位 | 描述 | 适用场景 |
|---|---|---|
| LANDLOCK_ACCESS_FS_READ_FILE | 读文件 / 目录 | 只读沙盒 |
| LANDLOCK_ACCESS_FS_WRITE_FILE | 写文件 | 工作区编辑 |
| LANDLOCK_ACCESS_FS_EXECUTE | 执行文件 | 脚本运行 |
| LANDLOCK_ACCESS_FS_MAKE_DIR | 创建目录 | 临时目录生成 |
示例 C 代码(兼容内核文档):
#include <linux/landlock.h>
#include <sys/syscall.h>
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_DIR,
};
int ruleset_fd = syscall(__NR_landlock_create_ruleset, &ruleset_attr, sizeof(ruleset_attr), LANDLOCK_ABI_VERSION);
struct landlock_path_beneath_attr path_beneath = {
.parent_fd = open("/workspace", O_PATH | O_CLOEXEC), // 工作区根
.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
};
syscall(__NR_landlock_add_rule, ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0);
syscall(__NR_landlock_restrict_self, ruleset_fd, 0); // 附加到进程,不可逆
Rust 绑定(rust-landlock crate)简化 ABI 处理:
use landlock::{Ruleset, AccessFs, PathBeneath, CompatLevel};
let mut ruleset = Ruleset::default()
.set_compatibility(CompatLevel::Exact)
.handle_access(AccessFs::from_read_write())
.create()
.unwrap()
.add_rule(PathBeneath::new("/workspace"), AccessFs::ReadWrite)
.unwrap();
ruleset.restrict_self().unwrap();
参数优化:
- ABI 版本:用 LANDLOCK_ABI_VERSION 查询内核支持,fallback 到 v1(BestEffort 模式容忍 ABI mismatch)。
- 路径 FD:O_PATH|O_CLOEXEC 打开,避免泄露句柄;多规则按层级添加(根先、子后)。
- 权限最小化:默认 deny-all,仅显式 allow;嵌套规则继承父权限,但子规则可收紧。
- 阈值:规则数 < 100 避免 FD 耗尽;/dev/null 等特殊路径需 RW 以防日志失败。
监控与回滚策略
生产部署需监控 Landlock 生效:
- dmesg/journalctl:grep "landlock: Up and running" 确认模块加载。
- 审计:/proc/PID/status 中 Landlock 域 ID;strace 观察 syscall 返回 - EACCES。
- 指标:暴露拒绝计数(自定义 eBPF 或 fanotify);超时阈值 5s,超限 fork 无沙盒子进程。
回滚清单:
- 预 fork 无沙盒副本测试。
- 渐进规则:先 READ_ONLY,验证通过再加 WRITE。
- 组合 seccomp:deny connect/bind,阈值 network_access=false。
- 失败降级:syscall 失败 fallback 到 chroot+capabilities drop。
风险控制:规则不可逆,设计时模拟测试(sandboxer 工具:LL_FS_RO/LL_FS_RW 环境变量)。内核需 CONFIG_LANDLOCK=y;与 AppArmor 堆叠时,后者优先。
实际落地如 Codex CLI:workspace-write 模式用 Landlock 限 cwd+tmpdir,seccomp 禁网络,平衡安全与开发效率。
资料来源:Linux 内核文档(kernel.org/doc/html/next/userspace-api/landlock.html);Landlock.io;rust-landlock GitHub;LWN 文章 “Landlock Lands In Linux 5.13”。