linux 安全系列目录 - seccomp安全模块问题排查
linux系列目录
linux 安全系列目录 - seccomp
涉及seccomp安全模块问题时,可以参照本文档案例进行扩展分析,可以多访问文中的链接,很有用。
一、Seccomp沙箱安全机制
通过使用libseccomp,开发人员可以定义一组允许的系统调用规则,从而限制应用程序的系统调用(system call)集合,阻止对潜在危险的系统调用的调用。它最初被用于 cpushare 这个项目,让人们可以出租自己空闲的 cpu cycle 来执行未受信任代码(untrusted code)。这个 feature 本身并不是一个沙盒 (sandbox),它只是一种减少 Linux 内核暴露的机制,是构建一个安全的沙盒的重要组成部分。其中,沙箱bwrap也会使用它。
安全计算模式 seccomp(Secure Computing Mode)是自 Linux 2.6.10 之后引入到 kernel 的特性。一切都在内核中完成,不需要额外的上下文切换,所以不会造成性能问题。目前 在 Docker 和 Chrome 中广泛使用。使用 seccomp,可以定义系统调用白名单和黑名单,可以 定义出现非法系统调用时候的动作,比如结束进程或者使进程调用失败。
seccomp机制用于限制应用程序可以使用的系统调用,增加系统的安全性。
在/proc/${pid}/status文件中的Seccomp字段可以看到进程的Seccomp。
二、安装依赖包
sudo apt install libseccomp-dev libseccomp2 seccomp
三、Seccomp Strict Mode
使用prctl来设置程序的seccomp为strict模式,仅允许read、write、_exit和sigreturn四个系统调用。当调用未在seccomp白名单中的系统调用后,应用程序会被kill。
#include <stdio.h> /* printf */
#include <sys/prctl.h> /* prctl */
#include <linux/seccomp.h> /* seccomp's constants */
#include <unistd.h> /* dup2: just for test */
int main() {
printf("step 1: unrestricted\n");
// Enable filtering
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
printf("step 2: only 'read', 'write', '_exit' and 'sigreturn' syscalls\n");
// Redirect stderr to stdout
dup2(1, 2);
printf("step 3: !! YOU SHOULD NOT SEE ME !!\n");
// Success (well, not so in this case...)
return 0;
}
四、Seccomp Filter Mode (Seccomp-BPF) - 推荐
基于prctl系统调用的seccomp机制不够灵活,在linux 3.5之后引入了基于BPF的可定制的系统调用过滤功能。
#include <stdio.h> /* printf */
#include <unistd.h> /* dup2: just for test */
#include <seccomp.h> /* libseccomp */
int main() {
printf("step 1: unrestricted\n");
// Init the filter
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_KILL); // default action: kill
// setup basic whitelist
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
// setup our rule
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 2,
SCMP_A0(SCMP_CMP_EQ, 1),
SCMP_A1(SCMP_CMP_EQ, 2));
// build and load the filter
seccomp_load(ctx);
printf("step 2: only 'write' and dup2(1, 2) syscalls\n");
// Redirect stderr to stdout
dup2(1, 2);
printf("step 3: stderr redirected to stdout\n");
// Duplicate stderr to arbitrary fd
dup2(2, 42);
printf("step 4: !! YOU SHOULD NOT SEE ME !!\n");
// Success (well, not so in this case...)
return 0;
}
五、有用资源
- libseccomp forum
- BPF linux syscall filter
- systemd seccomp
- seccomp default json
- linux-user-chroot的src/setup-seccomp.c
- Flatpak的common/flatpak-run.c
- sandstorm的src/sandstorm/supervisor.c++
六、总结
seccomp是一种Linux内核特性,允许限制进程可以执行的系统调用,以增加应用程序的安全性。总的来说,libseccomp是一个强大的工具,可用于在Linux系统上实施安全策略,并限制应用程序的系统调用。在很多的应用中都有体现,如 flatpak, docker, google, systemd,linux-user-chroot。