Hotdry.
systems-engineering

Landlock:非特权进程的文件系统沙盒策略附加

利用Landlock LSM钩子,为进程附加细粒度FS访问控制策略,实现无root沙盒化,与seccomp互补的落地参数与监控要点。

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 无沙盒子进程。

回滚清单:

  1. 预 fork 无沙盒副本测试。
  2. 渐进规则:先 READ_ONLY,验证通过再加 WRITE。
  3. 组合 seccomp:deny connect/bind,阈值 network_access=false。
  4. 失败降级: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”。

查看归档