# Linux capabilities - биты привилегий _Процессы и ресурсы · LinuxLab Knowledge Base_ **TL;DR:** Capabilities дробят привилегии root'а на 40+ независимых битов: NET_ADMIN, SYS_PTRACE, и т.д. Можно дать процессу часть, не делая его полным root'ом. ## Зачем Исторически: root всемогущий, юзер ничего не может. Это всё-или-ничего. Хотел бы пинговать → нужен raw socket → нужен root → но тогда программа может ВСЁ. Capabilities делят это «всемогущество» на ~40 битов, каждый - конкретное право. Программе нужен только `CAP_NET_RAW` (создать ICMP-сокет), а не все остальные 39 бит. На контейнерах это критично - `--cap-drop=ALL` + `--cap-add=NET_BIND_SERVICE` даёт практически безопасный root. ## Самые ходовые capabilities | CAP | Что разрешает | |---|---| | **NET_ADMIN** | `ip`, `tc`, `iptables`, `nft`, sysctl сети | | **NET_RAW** | raw sockets (ping, tcpdump) | | **NET_BIND_SERVICE** | bind на порты <1024 (80, 443, 22) | | **SYS_ADMIN** | mount, umount, swapon, и куча всего - почти как root | | **SYS_PTRACE** | `ptrace` чужие процессы (gdb, strace других юзеров) | | **SYS_TIME** | менять системное время | | **SYS_NICE** | priority, real-time scheduling | | **SYS_RESOURCE** | поднимать `ulimit`-ы | | **CHOWN** | менять владельца файлов | | **DAC_OVERRIDE** | обходить [file-permissions](/kb/file-permissions.md) чтения/записи | | **DAC_READ_SEARCH** | то же только для чтения | | **SETUID** / **SETGID** | менять UID/GID процесса | | **KILL** | посылать [signals](/kb/signals.md) любому процессу | | **MKNOD** | создавать device-nodes | | **AUDIT_WRITE** | писать в audit log (нужен для login) | | **BPF** | загружать eBPF-программы (новее) | | **PERFMON** | `perf` без root (с CONFIG_BPF) | Полный список - `man 7 capabilities` или `capsh --print`. ## Где capabilities у процесса Процесс держит **5 наборов** capabilities (через bitmasks в task_struct): - **Permitted (P)** - что МОЖНО получить - **Effective (E)** - что АКТИВНО прямо сейчас - **Inheritable (I)** - что унаследует exec'нутая программа - **Bounding (B)** - потолок: за этот set не выйти даже эскалацией - **Ambient (A)** - наследуется при exec без setuid (новее, для не-root юзеров) ```bash cat /proc/self/status | grep ^Cap # CapInh: 0000000000000000 # CapPrm: 0000003fffffffff ← все 40 бит = root # CapEff: 0000003fffffffff # CapBnd: 0000003fffffffff # CapAmb: 0000000000000000 capsh --print # читаемый формат capsh --decode=0000003fffffffff ``` Обычный юзер: все нули. Root: все единицы. Контейнер с `--cap-drop=ALL` плюс несколько `--cap-add`: видишь конкретный bitmask с включёнными. ## File capabilities Бинарь может иметь capabilities **в xattr** - тогда при exec он их получает, без setuid: ```bash # Дать /usr/bin/ping право CAP_NET_RAW (так в современных дистро) sudo setcap cap_net_raw+ep /usr/bin/ping getcap /usr/bin/ping # /usr/bin/ping = cap_net_raw+ep # Удалить sudo setcap -r /usr/bin/ping ``` Это **безопаснее SUID-root**: бинарь получает только нужный бит, а не полные root-привилегии. ## В Docker / containers Docker по умолчанию даёт ограниченный default-set caps: ``` CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETFCAP, CAP_SETGID, CAP_SETPCAP, CAP_SETUID, CAP_SYS_CHROOT ``` Управление: ```bash docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx # минимум docker run --cap-add=NET_ADMIN ubuntu # для tc/iptables docker run --cap-add=SYS_PTRACE ubuntu # для strace docker run --privileged ubuntu # ВСЕ caps + ещё всякое (НЕ безопасно) ``` В Kubernetes - `securityContext.capabilities`: ```yaml securityContext: capabilities: drop: ["ALL"] add: ["NET_BIND_SERVICE"] ``` ## Дебаг «Operation not permitted» Когда программа падает с EPERM: 1. `cat /proc//status | grep ^CapEff` - что есть у процесса 2. `capsh --decode=<значение>` - расшифровать 3. Сравнить с тем что нужно для операции (`man 7 capabilities`) 4. Если внутри контейнера - добавить через `--cap-add` ## CAP_SYS_ADMIN - «новый root» Из-за legacy-причин, очень многие операции требуют именно SYS_ADMIN (mount, namespaces, BPF, MAC labels). Это де-факто = root. Контейнер с `CAP_SYS_ADMIN` - почти небезопасный по дизайну. Это известная проблема, поэтому и появился `CAP_BPF`, `CAP_PERFMON` - выпиливают конкретные права из `SYS_ADMIN` в свои биты. ## Команды ```bash cat /proc/self/status | grep ^Cap ``` Текущие capabilities в hex - Permitted/Effective/Bounding/Ambient/Inherited ```bash capsh --print ``` Читаемый дамп capabilities текущего процесса ```bash sudo getcap -r / 2>/dev/null ``` Все бинари в системе с file capabilities - security audit ```bash sudo setcap cap_net_bind_service+ep /usr/local/bin/myapp ``` Дать своему бинарю право слушать <1024 порт без root ```bash docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx ``` Принцип least-privilege: только то что нужно ## См. также - [Процесс и PID](/kb/process-and-pid.md) - [Linux namespaces](/kb/namespaces.md) - [File permissions: rwx и chmod](/kb/file-permissions.md) - [Extended attributes (xattr) - произвольные метаданные файла](/kb/extended-attributes.md)