在容器化环境中,多进程应用的安全隔离往往面临挑战:父进程需要宽松权限启动服务,而子进程则需严格限制文件系统访问,以防漏洞扩散。Landlock LSM(Linux Security Module)作为内核原生沙箱机制,从 Linux 5.13 起提供非特权进程的文件系统访问控制,支持策略继承与分层作用域(hierarchical scoping),正是解决这一痛点的理想方案。它允许进程主动创建规则集(ruleset),定义路径下的细粒度权限(如读/写/执行),并通过不可逆的 restrict_self 操作应用到自身及所有子进程,形成嵌套沙箱。
Landlock 的核心在于规则集的层次化构建与自动继承。每个规则集通过 landlock_create_ruleset 系统调用创建,返回一个文件描述符(fd)。该 fd 可添加多条规则,例如使用 LANDLOCK_RULE_PATH_BENEATH 指定“路径之下”的访问控制:允许 /app 只读,/tmp 可读写,其他路径默认拒绝。关键是,landlock_restrict_self(fd, flags) 一旦执行,整个进程树(当前线程及其 fork/exec 子进程)即受限,且子进程无法放宽,只能创建新规则集进一步叠加限制。这种单向继承机制确保了沙箱的不可逃逸:父进程的宽松规则自动传递给子进程,后者可在其基础上嵌套更严格的作用域。
例如,在一个容器化 Web 服务中,入口进程(Nginx 主进程)可先设置全局规则:仅允许访问 /etc/nginx(读)、/var/log(写)、/usr/bin(执行)。代码示例如下:
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE |
LANDLOCK_ACCESS_FS_EXECUTE;
};
int ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), LANDLOCK_ABI_VERSION);
struct landlock_path_beneath_attr path_beneath = {
.parent_fd = open("/etc/nginx", O_PATH | O_CLOEXEC),
.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE,
};
landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0);
landlock_restrict_self(ruleset_fd, 0);
此后,Nginx worker 子进程继承这些规则,但可额外创建子规则集,仅允许访问 /var/www(读写),实现分层 scoping。随后,worker 中的 CGI/FastCGI 子进程进一步限制为特定脚本目录,形成多级嵌套:全局 → worker → 子服务。这种层次设计天然支持容器多进程场景,如 Docker 中的 supervisor + 多 worker,避免单一进程沙箱的粗粒度问题。
运行时更新是 Landlock 的另一亮点。尽管 restrict_self 不可逆,但进程可在继承规则基础上动态叠加新规则集,支持热更新沙箱。例如,服务启动后检测到高风险请求,可 fork 新子进程并为其添加临时规则(如仅访问 /tmp/upload)。flags 参数 LANDLOCK_RULESET_FLAGS_UPDATE 允许合并现有规则集,实现平滑收紧:新规则优先匹配,旧规则作为后备。这在动态容器环境中尤为实用,如 Kubernetes Pod 内多进程重启时,逐步强化隔离。
实际部署参数与清单如下,确保高效落地:
内核配置检查:
CONFIG_LANDLOCK=y(uname -r ≥5.13)
lsmod | grep landlock 或 dmesg | grep landlock 显示“Up and running”
规则集 ABI 版本: 使用 LANDLOCK_ABI_VERSION(当前 v4,支持网络规则扩展),兼容性通过 handled_access_fs 显式声明。
权限阈值推荐:
| 场景 |
读权限路径 |
写权限路径 |
执行权限路径 |
flags |
| 容器入口 |
/etc, /usr |
/var/run |
/usr/bin |
0 (默认继承) |
| Worker 进程 |
/app |
/var/log, /tmp |
无 |
LANDLOCK_RULESET_FLAGS_INHERIT |
| 高风险子进程 |
/tmp/script |
无 |
/bin/sh |
LANDLOCK_RULESET_FLAGS_UPDATE |
监控要点:
- strace 跟踪 landlock_* 调用,验证规则应用。
- auditd 日志 LSM 拒绝事件:
ausearch -m avc -ts recent | grep landlock。
- 性能:规则匹配 O(log N),N<100 规则时开销<1%;嵌套深度≤5,避免栈溢出。
- 回滚策略:预 fork 测试进程验证规则集,再 exec 主程序;失败时 fallback 无 Landlock 模式。
潜在风险包括规则遗漏导致过度开放(如忘记 MAKE_DIR 权限,子进程无法创建临时文件),或嵌套过深影响性能。限制造约:Landlock 仅文件系统(ABI v4 加网络),不覆盖 ptrace/cap 等,建议与 seccomp 组合。测试中,覆盖 fork/exec/mount 场景,确保子进程无法 mount --bind 逃逸。
在 containerized 多进程应用中,Landlock 的继承与分层 scoping 显著提升了零信任隔离:无需 root 或 eBPF,纯用户态即可工程化沙箱。相比 Firejail 等工具,它内核级、无额外依赖,完美契合云原生。
资料来源:
[1] Linux 内核文档:https://www.kernel.org/doc/html/next/userspace-api/landlock.html “Landlock rules describe an action on an object which the process intends to perform. A set of rules is aggregated in a ruleset, which can then restrict the thread enforcing it, and its future children.”
[2] Landlock 项目:https://landlock.io/ (基本用法与 sandboxer 示例)。