SELinux срещу AppArmor 2026: пълно сравнение и кога кое да използвате
SELinux срещу AppArmor през 2026: label-based срещу path-based MAC, режими на прилагане, конфигурация в RHEL 9/10 и Ubuntu 24.04, LSM stacking, контейнери и чести грешки.
SELinux и AppArmor са двата основни Linux Security Modules (LSM) за задължителен контрол на достъпа (MAC). SELinux използва етикети (labels) върху всеки файл, процес и порт и предлага фина, но сложна политика; това е стандартът в RHEL, Fedora, Rocky и AlmaLinux. AppArmor пък работи с профили, базирани на пътища, което е значително по-лесно за писане и разбиране, и идва по подразбиране в Ubuntu, Debian, openSUSE и SUSE. През 2026 г. и двата модула са активно поддържани в ядрото 6.x и вече дори могат да работят паралелно чрез LSM stacking. В тази статия ще проследя реален атакуващ сценарий стъпка по стъпка и ще покажа как всеки от двата LSM спира конкретните техники. (Спойлер: и двата вършат работа, но по различен начин.)
SELinux е label-based MAC система с три режима (enforcing, permissive, disabled) и стандарт в семейството Red Hat. AppArmor е path-based и стандарт в Ubuntu/Debian/openSUSE.
AppArmor профилите се пишат за 30 минути с aa-genprof. SELinux политиките изискват дни работа с audit2allow, но пък предлагат защита срещу hard-link атаки, които AppArmor пропуска.
От ядро 5.1+ LSM stacking позволява SELinux и AppArmor да работят едновременно на една система, което е полезно при контейнерни хостове.
За RHEL 9/10 задължително използвайте semanage и SELinux booleans, вместо да пишете нови политики от нула. 90% от нуждите се покриват с вградените профили.
AppArmor complain mode и SELinux permissive mode са неоценими при разработка на политики, защото генерират audit записи, без да блокират процеса.
Изключването на SELinux/AppArmor „за да проработи нещо" е грешката, която пентестерите обичат. Почти винаги има правилно решение с boolean, tag или profile правило.
Какво е задължителен контрол на достъпа (MAC) и защо ви трябва
Стандартният UNIX модел за права, Discretionary Access Control (DAC), оставя решенията в ръцете на собственика на файла. Ако процесът работи като root или собственикът реши да chmod 777 нещо, никой не пита. При пробив през уязвимо web приложение атакуващият наследява правата на процеса и може да чете /etc/shadow, ако процесът е root, или всеки файл на потребителя, ако не е.
Mandatory Access Control (MAC) добавя втори слой над DAC: ядрото само проверява политика, която дори root не може да заобиколи по време на изпълнение. Всеки syscall (open(), execve(), connect(), ptrace()) минава през LSM hook, който сравнява текущия контекст на процеса срещу разрешените действия. SELinux и AppArmor са двете основни имплементации, вградени в mainline ядрото. Разликата е в модела. SELinux работи с етикети (contexts) върху всеки обект, докато AppArmor работи с абсолютни пътища. И двата подхода имат смисъл, изборът зависи от мисленето на екипа ви.
Ако още се питате защо ви е MAC, след като имате firewall и SSH keys, погледнете статистиката от CVE базата за 2025 г. Според доклад на Red Hat, 43% от Linux privilege escalation експлойтите бяха неутрализирани от SELinux в enforcing mode още преди да достигнат payload фазата. Това е защита в дълбочина, не заместител на другите слоеве.
Атакуващ сценарий: пробив в web сървър без MAC
Ето реален сценарий, който съм възпроизвеждал десетки пъти в engagement-и (веднъж дори случайно, докато настройвах staging среда, но това е друга история). Целта е Nginx + PHP-FPM сървър без активен MAC. Работният поток на атакуващия:
Първоначален достъп: уязвимост в PHP приложение (deserialization в стар Laravel) позволява execute на команда като www-data.
Разузнаване:cat /etc/passwd, четивен по DAC. Атакуващият вижда всички потребители, включително сервизни акаунти.
Латерално движение:find / -perm -4000 2>/dev/null търси SUID бинарни файлове. Намира стар pkexec, уязвим на CVE-2021-4034 (Pwnkit).
Privilege escalation: изпълнява Pwnkit exploit и получава root shell.
Persistence: пише SSH ключ в /root/.ssh/authorized_keys и добавя cron job в /etc/cron.d/.
Сега да видим как SELinux и AppArmor прекъсват тази верига. Всеки от следващите два раздела показва как конкретните стъпки биват блокирани.
SELinux архитектура: label-based enforcement
SELinux бе разработен от NSA и добавен в mainline ядрото през 2003 г. Всеки обект в системата има security context във формат user:role:type:level, например system_u:object_r:httpd_sys_content_t:s0. Политиката дефинира кои типове могат да взаимодействат: httpd_t процесът може да чете httpd_sys_content_t, но не и shadow_t.
Обратно към нашия сценарий. PHP-FPM работи под контекст httpd_t. Когато exploit-ът се опита да прочете /etc/shadow (тип shadow_t), SELinux hook отхвърля syscall с EACCES. Audit log записва AVC (Access Vector Cache) denial, което SIEM-ът ви трябва да алармира моментално. Първия път, когато настройвах Splunk да следи type=AVC записи, ми беше странно колко тихо е, докато не се появи първият alert. Тогава осъзнах, че всичко работи, както трябва.
Компонентите на политиката:
Type Enforcement (TE): основната защита, кой тип процес може да прави какво с кой тип обект.
Role-Based Access Control (RBAC): ограничава кои роли може да заеме потребител.
Multi-Level Security (MLS): класификационни нива (Bell-LaPadula), рядко използвани извън правителствени среди.
SELinux Booleans: runtime превключватели за политиката, например httpd_can_network_connect, които обхващат 90% от типичните нужди без писане на нова политика.
За задълбочен преглед на официалните политики препоръчвам Red Hat SELinux документация за RHEL 9. Тя обхваща targeted policy, която идва по подразбиране и покрива всички стандартни сервизи.
AppArmor архитектура: path-based профили
AppArmor е разработен от Immunix (по-късно закупен от Novell) и станал част от mainline ядрото през 2010 г. Вместо да етикетира обекти, AppArmor работи с профили за пътища. Ето един profile за нашия PHP-FPM:
Обратно към сценария: exploit-ът достига до shell като www-data, но всяко open("/etc/shadow", ...) връща EACCES заради явното deny. Дори execve() на pkexec е блокиран, защото /usr/bin/pkexec не е в профила. AppArmor работи по whitelist принцип, което понякога е болезнено при първоначална настройка, но накрая си заслужава.
Основните инструменти:
aa-status: показва заредените профили и в кой режим са.
aa-genprof: интерактивно генерира профил, докато вие изпълнявате приложението.
aa-logprof: обновява съществуващ профил спрямо denied записите в audit log.
aa-complain / aa-enforce: превключва между режимите.
Активна (Canonical води), новости в profile compression
Контейнерна интеграция
Отлична (Podman използва container_t)
Отлична (Docker default profile, snap)
Overhead на производителност
2 до 5% на I/O-heavy workloads
1 до 3% на I/O-heavy workloads
Конфигуриране на SELinux в RHEL 9/10
Проверка на текущото състояние. Ето първата команда, която пиша при audit:
# Показва режима и заредената политика
sestatus
# Показва настоящия режим (enforcing/permissive)
getenforce
# Временно превключване (не преживява reboot)
setenforce 0 # permissive
setenforce 1 # enforcing
Постоянното превключване става в /etc/selinux/config. Никога не задавайте SELINUX=disabled на production. Това изисква пълен file system relabel при обратно включване и оставя системата без защита в междинния период. Ако наистина ви трябва временен bypass, използвайте permissive mode.
Диагностициране на denial при инсталация на ново приложение:
# Показва последните AVC denials
ausearch -m AVC -ts recent
# Генерира препоръка за политика от denials
ausearch -m AVC -ts recent | audit2allow -m myapp
# Пише готов модул и го зарежда (само след ръчен преглед!)
ausearch -m AVC -ts recent | audit2allow -M myapp
semodule -i myapp.pp
За стандартни задачи почти винаги има boolean:
# Списък на всички booleans за httpd
getsebool -a | grep httpd
# Разрешава Apache/Nginx да прави outbound HTTP заявки
setsebool -P httpd_can_network_connect on
# Разрешава четене от NFS mount за web root
setsebool -P httpd_use_nfs on
Промяна на етикет на файл или директория:
# Добавя постоянно правило за път
semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
# Прилага правилото към файловата система
restorecon -Rv /srv/www
Ubuntu 24.04 идва с AppArmor 4.0 (release 2025 г.), който въведе profile compression и по-бързо зареждане. Инициалната проверка:
# Показва броя заредени профили и техните режими
sudo aa-status
# Списък на всички профили с път към файла
ls /etc/apparmor.d/
Генериране на нов профил за custom бинарен файл:
# Стартира интерактивния генератор
sudo aa-genprof /usr/local/bin/myapp
# В отделен терминал пуснете приложението и упражнете
# всичките му функции. aa-genprof улавя всеки system call
# и ви пита дали да го разреши.
# След финализиране проверете профила
cat /etc/apparmor.d/usr.local.bin.myapp
# Стартирайте в complain mode за няколко дни
sudo aa-complain /usr/local/bin/myapp
# Прегледайте audit log за пропуснати правила
sudo aa-logprof
# Активирайте enforcement
sudo aa-enforce /usr/local/bin/myapp
Полезни ръчни редакции на профил, забрана на достъп до чувствителни пътища:
# Презарежда всички профили
sudo systemctl reload apparmor
# Или конкретен профил
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.myapp
LSM stacking: SELinux и AppArmor заедно
От ядро 5.1 (2019 г.) Linux поддържа LSM stacking, тоест възможността няколко „major" LSM да работят едновременно. През 2026 г. combined стек SELinux + AppArmor е стабилен и се използва в специфични сценарии като multi-tenant Kubernetes хостове.
Активирането става чрез kernel command line параметър в GRUB:
Едно от практичните приложения: хост с SELinux политика на ниво OS, но AppArmor профили за конкретни контейнери, доставени с приложението. Kubernetes seccomp/AppArmor annotations работят независимо от SELinux контекста на хоста. Според официалната LSM документация на kernel.org, стекът трябва да включи capability винаги първи, следван от minor LSM-и и накрая major-ите. Подробности за kernel API-то могат да се проверят и в security директорията на Linux kernel source-а.
SELinux и AppArmor за контейнери (Docker, Podman, Kubernetes)
Контейнерите са namespace + cgroup, а не sandbox. Без MAC един compromise на контейнер може да достигне до други контейнери или до хоста. Двата LSM подхождат по различен начин.
SELinux + Podman: Podman по подразбиране прилага уникален MCS етикет (s0:c123,c456) за всеки контейнер. Дори при escape от контейнера процесът не може да чете файлове от друг контейнер, защото категориите не съвпадат. Тества се лесно:
podman run --rm -it --name test1 alpine sh
# В контейнера:
ps -eZ | head
# system_u:system_r:container_t:s0:c247,c891
AppArmor + Docker: Docker зарежда docker-default профил за всеки контейнер, освен ако не подадете --security-opt apparmor=unconfined. За production използвайте custom профил, специфичен за вашето приложение:
docker run --security-opt apparmor=nginx-strict nginx:1.27
Ето топ 5 фейлове, които виждам в почти всеки engagement:
SELINUX=disabled в /etc/selinux/config. Обикновено защото някой Ansible playbook „не работеше". Резултат: цялата защита отсъства, exploit chain-ите протичат безпрепятствено. Правилно: използвайте permissive mode за диагностика, после boolean или fcontext.
AppArmor профил в complain mode на production. Complain генерира audit записи, но не блокира. Атакуващият вижда какво генерира deny, но продължава напред. Правилно: enforce mode винаги в prod.
Docker контейнери с --privileged флаг. Изключва почти всички MAC защити наведнъж. Правилно: използвайте фини capabilities с --cap-add, а не глобален privileged.
Липса на мониторинг на AVC denials. SELinux ви казва точно кога някой се опитва да направи нещо забранено, но само ако някой чете audit log. Правилно: препращайте type=AVC записи към SIEM. Комбинация с Lynis и OpenSCAP автоматизиран audit дава пълна картина.
Custom SELinux модули без preservation. Ръчно генерирани .pp модули изчезват при основен upgrade. Правилно: съхранявайте source .te файловете в git, редеплойвайте с Ansible.
Често задавани въпроси
Каква е разликата между SELinux и AppArmor?
SELinux използва етикети (labels) върху всеки файл и процес и предлага много фина политика с type enforcement, RBAC и MLS. AppArmor работи с профили, базирани на пътища на файловата система, което го прави значително по-лесен за писане и разбиране, но го оставя уязвим на определени hard link атаки. SELinux е стандарт в RHEL/Fedora, а AppArmor в Ubuntu/Debian/openSUSE.
Кое е по-добро, SELinux или AppArmor?
Няма универсален отговор, зависи от контекста. За enterprise среда с изисквания за фина гранулярност и compliance (FIPS, Common Criteria) изберете SELinux. За екипи, които искат бърз старт и лесно поддържане на custom профили, AppArmor е по-подходящ. И двата спират 90%+ от типичните privilege escalation атаки, когато са в enforcing/enforce mode.
Могат ли SELinux и AppArmor да работят заедно?
Да, от ядро 5.1 нататък чрез LSM stacking. Активирайте чрез kernel параметър lsm=capability,yama,apparmor,selinux в GRUB конфигурацията. Обичайно се използва при multi-tenant Kubernetes хостове, където хостът има една политика, а контейнерите носят собствени профили.
Как да изключа временно SELinux без reboot?
Изпълнете sudo setenforce 0, което поставя SELinux в permissive mode. Той продължава да пише AVC denials, но не блокира syscalls. Върнете обратно с sudo setenforce 1. Никога не задавайте SELINUX=disabled в /etc/selinux/config на production система, защото това изисква пълен relabel при обратно включване.
Как да напиша AppArmor профил за custom приложение?
Стартирайте sudo aa-genprof /path/to/binary, после в друг терминал пуснете приложението и упражнете всичките му функции. Генераторът улавя всеки достъп и пита дали да го разреши. След финализиране пуснете в complain mode за няколко дни, обработете пропуснати правила с aa-logprof и включете enforce mode с aa-enforce.
Кои дистрибуции използват SELinux и кои AppArmor през 2026?
SELinux по подразбиране: RHEL 9/10, Fedora 40+, Rocky Linux 9, AlmaLinux 9, CentOS Stream 9/10, Oracle Linux. AppArmor по подразбиране: Ubuntu 24.04 LTS и всички деривати, Debian 12, openSUSE Leap 15.6, SUSE Linux Enterprise Server 15. Arch и Gentoo не задават нищо по подразбиране, потребителят избира.
systemd sandboxing позволява да превърнете всеки systemd unit в изолиран процес с минимален blast radius. Разглеждам директивите ProtectSystem, PrivateTmp, NoNewPrivileges, CapabilityBoundingSet, SystemCallFilter и DynamicUser, оценката с systemd-analyze security и практически hardening на nginx.service.
KSPP-съвместими sysctl настройки, Lockdown Mode, подписване на модули и IMA/EVM интегритет: пълен наръчник за укрепване на Linux ядрото през 2026 с Ansible role и тестове с LKDTM.