# seccomp - фильтр системных вызовов _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** seccomp - kernel-level фильтр syscall'ов. Процесс декларирует «можно только эти», и kernel отсекает остальные. Основа sandbox'а Docker и Chrome. ## Зачем [capabilities](/kb/capabilities.md) делят root-привилегии. Но даже простой пользовательский процесс может вызвать ~350 разных syscall'ов, и в любом потенциально есть бага → уязвимость. Лучшая защита - отнять у процесса возможность делать syscall'ы, которые ему не нужны. Например, web-сервер не должен звать `mount()`, `reboot()`, `kexec_load()`, `ptrace()`. Если их можно ОТКЛЮЧИТЬ - целая поверхность атак отрезана. ## Два режима - **SECCOMP_MODE_STRICT** (старый, 2005) - оставляет только `read`, `write`, `_exit`, `sigreturn`. Слишком жёстко, никем не используется. - **SECCOMP_MODE_FILTER** (BPF, 2012) - программа на BPF фильтрует syscall'ы по номеру и аргументам. **Это и есть «seccomp» сегодня.** Программа BPF получает на вход номер syscall'а и аргументы, возвращает одно из: | Action | Что делает | |---|---| | `SECCOMP_RET_ALLOW` | пропустить | | `SECCOMP_RET_ERRNO(n)` | заблокировать с возвратом ошибки `n` (типично EPERM) | | `SECCOMP_RET_KILL_PROCESS` | убить процесс целиком | | `SECCOMP_RET_KILL_THREAD` | убить только этот thread | | `SECCOMP_RET_TRAP` | SIGSYS → можно обработать | | `SECCOMP_RET_LOG` | пропустить + записать в audit | | `SECCOMP_RET_USER_NOTIF` | передать в userspace для решения (новое; для контейнеров) | ## Как программа включает seccomp Через системный вызов `prctl()` или `seccomp()`. Обычно используют библиотеку `libseccomp` чтобы не писать BPF руками: ```c scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ERRNO(EPERM)); // default = блок seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); seccomp_load(ctx); // теперь любой syscall кроме разрешённых = EPERM ``` Filter - необратимый: можно только сужать, нельзя расширять. ## Docker default profile Docker применяет [seccomp profile](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) по умолчанию. Заблокирован ~50 syscall'ов: `clone3` (CVE-mitigation, раньше), `kexec_load`, `keyctl`, `reboot`, `mount` (требует CAP_SYS_ADMIN отдельно), часть `ptrace`-вариантов и т.д. ```bash docker run --security-opt seccomp=unconfined ubuntu # ВЫКЛЮЧИТЬ - для дебага docker run --security-opt seccomp=/path/profile.json # свой профиль ``` В Kubernetes: ```yaml securityContext: seccompProfile: type: RuntimeDefault # docker-style профиль # или type: Localhost localhostProfile: profiles/audit.json ``` ## Связь с другими механизмами - **AppArmor / SELinux** - фильтр на уровне MAC (file/path/network) - **capabilities** - что разрешено root-привилегий - **seccomp** - что разрешено по syscall'ам Это разные слои; на проде стоит включать **все три** + namespace-изоляцию. Это и есть подход «defense in depth». ## Дебаг seccomp-нарушений Когда процесс падает с EPERM «непонятно от чего», подозрение на seccomp: ```bash # 1. Посмотреть фильтры процесса cat /proc//status | grep ^Seccomp # Seccomp: 2 ← 0=disabled, 1=strict, 2=filter # 2. strace - увидим запрещённый syscall strace -p # error: Operation not permitted на конкретном syscall # 3. dmesg - если профиль настроен на LOG sudo dmesg | grep audit ``` Для разработки своего профиля Docker запускают приложение с режимом `RET_LOG` (всё пропускать но логировать), собирают список реально использованных syscall'ов, потом строят минимальный whitelist. ## Системные тулзы - `scmp_sys_resolver ` - расшифровать номер syscall'а в имя - `seccomp-tools` (третья сторона) - дамп BPF из работающего процесса - `falco` - observability + audit с seccomp ## Команды ```bash cat /proc//status | grep ^Seccomp ``` Состояние seccomp у процесса (0/1/2) ```bash docker run --security-opt seccomp=unconfined ubuntu ``` Выключить seccomp для дебага - только локально, не на проде ```bash docker run --security-opt seccomp=profile.json myimg ``` Применить кастомный профиль из JSON ```bash scmp_sys_resolver_x86_64 41 ``` Расшифровать номер syscall'а в имя (41 = socket) ```bash strace -e seccomp ./app ``` Увидеть в strace когда программа сама применяет seccomp-фильтр ## См. также - [Процесс и PID](/kb/process-and-pid.md) - [Linux capabilities - биты привилегий](/kb/capabilities.md) - [Linux namespaces](/kb/namespaces.md) - [eBPF - программируемый kernel](/kb/ebpf-basics.md)