Права в Linux відповідають на питання «кому можна прочитати цей файл». AppArmor відповідає на інше: «що цій програмі взагалі дозволено робити». Різниця проявляється під час зламу. Вебшелл працює від користувача вебсервера й успадковує всі його права — а це доступ на читання доброї половини системи. Профіль AppArmor обмежує процес переліком того, що потрібно йому для роботи, і спроба прочитати /etc/shadow чи запустити /bin/bash закінчується відмовою незалежно від прав користувача.

Що вже ввімкнено

sudo aa-status

Вивід відповідає на три питання: скільки профілів завантажено, скільки з них у режимі enforce і скільки в complain, і які процеси працюють узагалі без профілю. На типовій Ubuntu профілів буде кілька десятків, але майже всі вони — для допоміжних програм на кшталт man і tcpdump. Ключові служби — nginx, Apache, PHP-FPM — у списку обмежених зазвичай відсутні.

Три режими варто розрізняти:

  • enforce — правила застосовуються, усе зайве забороняється;
  • complain — порушення лише записуються в журнал, нічого не блокується. Режим для налаштування;
  • unconfined — профілю немає, програма працює без обмежень.

Найкорисніша частина виводу aa-status — остання: процеси, які слухають мережу й нічим не обмежені. Саме з цього списку й починають.

Інструменти

sudo apt install apparmor-utils

Без цього пакета команд aa-complain, aa-enforce і aa-logprof у системі немає, хоча сам AppArmor працює.

Як увімкнути профіль, не зупинивши службу

Порядок тут принциповий. Профіль, переведений одразу в enforce, з великою ймовірністю заборонить службі щось потрібне, і вона перестане працювати — зазвичай не одразу, а на якійсь рідкісній операції на кшталт завантаження файла чи надсилання пошти.

Правильна послідовність:

sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

Тиждень роботи в цьому режимі з охопленням усіх нетипових сценаріїв: зняття резервної копії, оновлення, завантаження великих файлів. Потім пройдіться по тому, що назбиралося:

sudo aa-logprof

Команда проходить по записаних порушеннях і по кожному питає, чи дозволяти. Тут потрібна уважність: дозволяйте те, що справді належить до роботи служби, а не все підряд — інакше вийде профіль, який дозволяє все, і сенс буде втрачено.

І лише потім:

sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

Де дивитися відмови

Усі порушення потрапляють у журнал ядра:

sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log

Другий файл існує, якщо встановлено auditd, — і з ним записи помітно докладніші. Запис відмови показує назву профілю, запитану операцію і шлях, до якого зверталися; цього досить, щоб зрозуміти, чи треба виправляти профіль, чи радіти, що він спрацював.

Один симптом варто запам’ятати: служба поводиться дивно — не читає конфігурацію, не пише в каталог, не відкриває сокет, — а в її власних журналах помилка «permission denied» з правами, які явно правильні. Це майже завжди AppArmor, і перше, що треба зробити, — заглянути в журнал ядра.

Практичний захід, а не теоретичний

Профіль для PHP-FPM чи nginx окупається цілком конкретно. Коли процес обмежений, вебшелл, що дістався до сайту, не може ні прочитати системні файли, ні запустити оболонку, ні записати щось поза дозволеними каталогами. Зламаний сайт лишається зламаним сайтом, а не перетворюється на доступ до всієї машини — і саме цей перехід дає основну частину збитків.

Розумний порядок упровадження: спершу профіль для того, що дивиться в інтернет (вебсервер, PHP-FPM), потім для баз даних, далі за потребою. Вмикати все одразу не треба, і універсального готового набору не існує: профіль залежить від того, де лежать ваші файли.

Що перевіряти регулярно

Профілі скочуються в unconfined частіше, ніж здається: оновлення пакета може замінити файл профілю, ручне налагодження лишає службу в complain, а нова служба приходить узагалі без профілю. Корисні дві цифри: скільки профілів у enforce і скільки звернених до мережі процесів у unconfined. Зміну будь-якої з них варто знати. Який вигляд це має зібраним на одній сторінці, показує демо нижче.