Що таке мандатний контроль доступу і навіщо він потрібен на сервері
Мандатний контроль доступу (MAC) — додатковий рівень захисту поверх звичайних прав доступу Linux. Навіть процес від root не вийде за межі дозволених політикою дій. Зламаний веб-процес на nginx чи php-fpm без MAC отримує доступ до всієї файлової системи, а з SELinux або AppArmor — лише до файлів свого профілю.
На RHEL, CentOS і AlmaLinux за це відповідає SELinux, на Ubuntu і Debian — AppArmor. Обидва увімкнені за замовчуванням, але адміністратори часто вимикають їх при першій помилці доступу — це позбавляє сервер важливого бар'єру захисту.
Чим відрізняється SELinux від AppArmor
SELinux працює за моделлю міток: файлу, процесу, порту і сокету присвоюється контекст вигляду user:role:type:level, а політика описує, яким процесам дозволено взаємодіяти з якими об'єктами. Це гнучкий, але складний у налагодженні контроль.
AppArmor простіший: правила прив'язані не до міток, а до шляхів, і профіль — текстовий файл у /etc/apparmor.d/, наприклад /etc/apparmor.d/usr.sbin.nginx. Поріг входу нижчий, та захист менш деталізований: шлях можна обійти симлінком або bind-mount при недбалому профілі.
| Параметр | SELinux | AppArmor |
|---|---|---|
| Дистрибутиви | RHEL, CentOS, AlmaLinux, Fedora | Ubuntu, Debian |
| Модель | Мітки на об'єктах | Шляхи у профілі |
| Формат правил | Бінарна політика, булеві прапорці | Текстовий профіль |
| Режими | enforcing, permissive, disabled | enforce, complain |
| Утиліта аналізу | audit2allow | aa-logprof |
Як перевірити статус і перемкнути режим роботи
Поточний режим SELinux показує getenforce, деталі — sestatus. Налаштування зберігається у файлі /etc/selinux/config, параметр SELINUX= приймає enforcing, permissive або disabled. Тимчасово перемкнути режим до перезавантаження:
sestatus
setenforce 0 # тимчасово перевести у permissive
setenforce 1 # повернути enforcing
В AppArmor статус профілів показує aa-status: видно, чи профіль працює у режимі enforce, чи complain. Переведення одного профілю у тестовий режим complain не вимикає захист повністю, а лише послаблює його для одного процесу:
aa-status
aa-complain /etc/apparmor.d/usr.sbin.nginx
aa-enforce /etc/apparmor.d/usr.sbin.nginx
Як налаштувати контексти SELinux і профілі AppArmor для nginx і php-fpm
Важливі правильні типи контексту на файлах і параметри-перемикачі (booleans). Каталог із сайтом — тип httpd_sys_content_t, а каталоги для запису (кеш, завантаження, сесії) — тип httpd_sys_rw_content_t. Для мережевих звернень вмикають відповідний boolean:
semanage fcontext -a -t httpd_sys_content_t "/var/www/site(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/site/uploads(/.*)?"
restorecon -Rv /var/www/site
setsebool -P httpd_can_network_connect 1
В AppArmor профілі для nginx і php-fpm зазвичай вже є в пакеті, але шляхи сайту потрібно явно вказати у профілі, інакше доступ заборонено. Після редагування профіль перечитують:
vim /etc/apparmor.d/usr.sbin.nginx
apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
systemctl reload apparmor
Принцип один: дозволяти доступ точково, під конкретний каталог чи порт. Базові права файлів описані у статті про права доступу Linux, а кроки захисту веб-сервера — у статті про посилення безпеки nginx.
Як діагностувати блокування через audit2allow і aa-logprof
Коли SELinux блокує легітимну дію, запис потрапляє у /var/log/audit/audit.log. Щоб згенерувати точкове правило замість вимкнення захисту повністю, використовують зв'язку ausearch і audit2allow:
ausearch -m avc -ts recent
audit2allow -a -M nginx_uploads
semodule -i nginx_uploads.pp
Модуль nginx_uploads.pp додає лише реально запитаний дозвіл — це безпечніше за переведення системи в permissive. Перед застосуванням варто відкрити .te-файл і перевірити, що правило не надає зайвих прав, наприклад доступу до shadow_t.
В AppArmor схожу роль відіграє aa-logprof: він читає журнал ядра, знаходить записи DENIED для профілів у режимі complain і пропонує додати правило до профілю:
aa-complain /etc/apparmor.d/usr.sbin.php-fpm
# відтворити проблемну дію на сайті
aa-logprof
aa-genprof застосовують для побудови профілю з нуля, а моніторинг звернень процесу доповнюють інвентаризацією сервера через osquery або логами у Wazuh SIEM.
Що робити під час перенесення сайту, щоб не зламати його неправильним контекстом
Поширена помилка після перенесення сайту чи відновлення з резервної копії — файли копіюються через rsync, tar або FTP і отримують контекст батьківського каталогу замість httpd_sys_content_t. Nginx і php-fpm повертають 403 Forbidden, хоча права chmod і chown виглядають коректними — читати файл не дає контекст SELinux, а не Unix-права.
Виправляється це відновленням контексту за політикою, а не ручним призначенням типу на кожен файл:
restorecon -Rv /var/www/site
ls -Z /var/www/site/index.php
В AppArmor такої проблеми немає, та після перенесення сайту на новий шлях (наприклад, з /var/www/html на /var/www/site) профіль потрібно оновити вручну — інакше процес не побачить нові файли або отримає DENIED.
Чек-лист щодо SELinux і AppArmor на продакшн-сервері
- Режим enforcing (SELinux) або enforce (AppArmor) увімкнено на бойовому сервері, а не лише на етапі тестів.
- Після перенесення сайту виконано
restorecon -Rvдля каталогу з сайтом. - Каталоги для завантажень і кешу мають тип
httpd_sys_rw_content_t, а не загальний read-only тип. - Нові заборони розбираються через
audit2allowчиaa-logprof, а не вирішуються командоюsetenforce 0назавжди. - Згенеровані модулі та профілі перевірено вручну перед застосуванням на проді.
- Захист MAC не замінює базову конфігурацію сервера — файлові права, firewall і SSH налаштовані окремо, як описано в загальному чек-листі безпеки сервера.