Операционная система Linux унаследовала систему безопасности Unix, разработанную еще в 70-х годах, передовую на момент создания, но на сегодняшний день уже явно недостаточную. Каждый пользователь имеет полную свободу действий в пределах своих полномочий по принципу «все или ничего». Это приводит к тому, что для выполнения некоторых задач пользователю часто предоставляется гораздо больше прав, чем это реально необходимо. Поэтому пользователь, получивший доступ с правами системной учетной записи, может добиться практически полного контроля над системой.
Что имеем?
В процессе работы любого приложения могут возникать различные отклонения, приводящие в итоге к его аномальному выполнению. Это могут быть как системные сбои, ошибки в программировании, так и искусственно вызванные ситуации. И последнее далеко не редкость. Хакер, обнаружив, что при определенных условиях можно повлиять на выполнение программы, естественно, попытается этим воспользоваться.
Предсказать поведение программы во внештатном режиме практически нереально. Примером тому являются антивирусы, которые все время работают в «догоняющем» ритме, не обеспечивая защиту от 0-day атак. А вот нормальное поведение программы можно описать с помощью относительно простых правил. В результате появилось несколько проектов, реализующих концепцию упреждающей защиты. Среди них LIDS, GRSecurity, AppArmor и SELinux. Но большей известностью пользуются последние два.
SELinux (Security Enhanced Linux) появился в недрах U.S. National Security Agency (NSA) и стал доступен общественности под лицензией GPL в 2000 году. В нем использован ролевой контроль доступа (Role-based Access Control, RBAC), многоуровневая безопасность и принудительное присвоение типов (type enforcement). Код SELinux включен в ядро версии 2.6 (начиная с 2.6.0-test), для версий 2.4 и 2.2 имеются патчи. Кроме того, SELinux портирован под BSD и Darwin, а код оптимизирован для компьютеров, имеющих 32 и более процессора. Каждому файлу назначается контекст безопасности, который и определяет, какие процессы (пользователи) могут с ним работать. Несмотря на очень высокий уровень защиты и поддержку в дистрибутивах RedHat, эта система так и не смогла приобрести широкую популярность из-за очень сложной процедуры настройки. Разработчики AppArmor резонно считают, что безопасность не должна идти в ущерб простоте, ведь чем сложнее система, тем больше вероятность, что она будет неверно настроена.
Проект AppArmor
Изначально AppArmor был разработан компанией Immunix, которая выпускала одноименный «иммунизированный» дистрибутив Linux и специализировалась в области защиты ОС и ее приложений от различных атак. После ее приобретения компанией Novell в мае 2005 года (кстати, вместе с основателем Криспином Коуэном) инструмент был открыт под лицензией GPL и включен в состав дистрибутива OpenSUSE под именем AppArmor. Постепенно он был адаптирован для некоторых других дистрибутивов: PLD, Pardus Linux, Annvix, RHEL 5, Slackware 10.2 и Ubuntu.
В AppArmor для определения того, к каким системным ресурсам и с какими привилегиями может получить доступ то или иное приложение, используются политики безопасности, именуемые профилями (profiles). С их помощью к стандартной Unix-модели безопасности DAC (Discretionary Access Control) добавляется более мощная – MAC (Mandatory Access Control). В отличие от SELinux и LIDS, в которых настройки глобальны для всей системы, профили в AppArmor разрабатываются индивидуально под каждое приложение (в SELinux также потихоньку начинают использовать такой подход).
Для упрощения настроек в AppArmor уже включен набор стандартных профилей, запускаемых после установки. Отдельно доступны профили для многих популярных программ и серверов. Если же готового профиля найти не удалось, в его создании помогут специальные инструменты (genprof и logprof). Для пользователей OpenSUSE имеется графический интерфейс к этим утилитам, реализованный в Yast2. Таким образом, вся философия работы с AppArmor сводится к правильному выбору приложений, нуждающихся в ограничении привилегий, и созданию/редактированию профилей безопасности.
Установка AppArmor в Ubuntu
Начиная с версии 7.04 AppArmor официально включен в репозитарий Ubuntu, и проблем с его установкой нет:
$ sudo apt-get install apparmor apparmor-docs apparmor-modules-source apparmor-profiles apparmor-utils
После этого скрипт будет ругаться, что не может закончить настройку по причине отсутствия необходимых модулей ядра. Поэтому сначала вводим команду подготовки к сборке, так мы проверим наличие всех необходимых пакетов и загрузим недостающие:
$ sudo m-a -v -t prepare
Вообще говоря, почти вся ее работа сводится к стандартным sudo apt-get install build-essential. Теперь собираем модуль:
$ sudo m-a -v -t -f build apparmor-modules
$ sudo m-a -v -t -f install apparmor-modules
После сборки советую вручную загрузить модуль ядра, контролирующего установленные политики, чтобы проверить корректность работы:
$ sudo modprobe apparmor
FATAL: Error inserting apparmor (/lib/modules/2.6.20-15-generic/apparmor/apparmor.ko): Resource temporarily unavailable
Упс, не грузится… Судя по сообщениям на различных форумах, такая ошибка возникла не только у меня. На форумах OpenSUSE удалось найти подсказку. AppArmor несовместим с selinux и capabilities. Если они встроены в само ядро, то ядро придется пересобрать, установив следующие параметры в .config.
$ sudo mcedit /usr/src/linux/.config
CONFIG_SECURITY_SELINUX=n
CONFIG_SECURITY_CAPABILITIES=m
Иначе добавляем два параметра, передаваемые ядру при загрузке: «capability.disable = 1» и «selinux = 0». Правда, в моем случае первый параметр почему-то был проигнорирован:
$ dmesg | grep capability
[19.543828] Unknown boot option `capability.disable = 1′: ignoring
Поэтому просто выгружаем модуль ядра:
$ sudo rmmod capability
И пробуем еще раз:
$ sudo modprobe apparmor
$ lsmod | grep apparmor
apparmor 55836 0
aamatch_pcre 16896 1 apparmor
commoncap 8192 1 apparmor
Кроме этого, модуль apparmor может не дружить с Dazuko, который обычно используется при on-access сканировании файлов антивирусом Clamav. Теперь запускаем всю систему:
$ sudo /etc/init.d/apparmor start
mounting securityfs on /sys/kernel/security: done.
Loading AppArmor profiles: done.
Если все нормально, на этом установку AppArmor можно считать законченной. Следующий шаг – настройка профилей.
Профили AppArmor
После запуска демон загружает все профили, лежащие в каталоге /etc/apparmor.d. Для контроля режима работы используется файловая система securityfs, с ее помощью можно получить информацию о загруженных профилях:
$ sudo mount -tsecurityfs securityfs /sys/kernel/security
$ sudo cat /sys/kernel/security/apparmor/profiles
/usr/sbin/traceroute (enforce)
/usr/sbin/ntpd (enforce)
/usr/sbin/nscd (enforce)
/usr/sbin/named (enforce)
/usr/sbin/mdnsd (enforce)
/usr/sbin/identd (enforce)
/usr/sbin/dovecot (complain)
/sbin/syslogd (enforce)
/sbin/syslog-ng (enforce)
/sbin/klogd (enforce)
/bin/ping (enforce)
AppArmor может обрабатывать профили в двух режимах:
1. enforce – принудительный режим, сервис работает исключительно в пределах профиля, все попытки нарушить правила регистрируются в syslog;
2. complain – щадящий режим (обучения), в этом случае работа сервиса просто контролируется, при нарушении профиля создается запись. Этот режим удобен при создании новых профилей и настройки профиля на конкретной системе.
Для изменения режима достаточно открыть файл профиля и напротив исполняемого файла добавить строку «flags=(complain)»:
/bin/ls flags=(complain)
Глобально все профили перевести в режим complain можно командой:
$ sudo echo 1 > /sys/kernel/security/apparmor/control/complain
После обучения отдельное приложение без перезагрузки всех профилей можно перевести в жесткий режим с помощью специальной утилиты enforce:
$ enforce dovecot
Setting /usr/sbin/dovecot to enforce mode.
Остальные профили лежат в каталоге /usr/share/doc/apparmor-profiles/extras. Каждый профиль имеет имя, которое состоит из полного пути к исполняемому файлу, только вместо слеша используется точка. Например, usr.lib.firefox.firefox.sh. Типичное описание профиля выглядит так:
$ cat /usr/share/doc/apparmor-profiles/extras/usr.lib.firefox.firefox.sh
#include <tunables/global>
/usr/lib/firefox/firefox.sh {
…
/bin/basename mixr,
/usr/bin/aoss Ux,
/usr/lib/firefox/* r,
/usr/lib/firefox/firefox-bin px,
…
}
Профиль состоит из файлов, каталогов, с указанием полных путей к ним (возможно применение регулярных выражений), и прав доступа к этим объектам. При этом r – разрешение на чтение (для всех вызовов), w – запись (за исключением создания и удаления файлов), ix – исполнение и наследование текущего профиля, px – исполнение под специфическим профилем, Px – защищенное выполнение, ux – неограниченное исполнение, Ux – защищенное неограниченное исполнение, m – присвоение участку памяти атрибута «исполняемый», l – жесткая ссылка.
Чтобы подключить готовый профиль к AppArmor, достаточно его скопировать в каталог /etc/apparmor.d. Например, для Postfix производим следующие действия:
$ cd /etc/apparmor/profiles/extras
$ sudo mv *postfix* usr.sbin.post* /etc/apparmor.d
$ mv usr.bin.procmail usr.sbin.sendmail /etc/apparmor.d
И на первое время запускаем в режиме обучения:
$ complain /etc/apparmor.d/*postfix*
$ complain /etc/apparmor.d/usr.sbin.post*
$ complain /etc/apparmor.d/usr.bin.procmail
$ complain /etc/apparmor.d/usr.sbin.sendmail
Далее используем Postfix, как обычно, уточняем политики с помощью утилиты logprof и переводим в принудительный режим. Для этого в предыдущем примере меняем все complain на enforce. Как вариант – можно вместо профиля сразу указать сам исполняемый файл, тогда соответствующие ему политики будут подхвачены автоматически.
Создание профиля
Теперь попробуем создать новый профиль и проверим работу AppArmor. Для тестирования выберем всеми любимую программу для создания паролей /usr/bin/passwd. Для создания нового профиля используется утилита genprof (кстати, все утилиты AppArmor имеют псевдонимы, начинающиеся на «aa-»):
$ sudo genprof /usr/bin/passwd
Записывается обновленный профиль /usr/bin/passwd. Настройка /usr/bin/passwd происходит в щадящем режиме. Запускаем приложение, для которого создается профиль. В нашем случае можно создать/удалить пользователя, изменить его пароль:
$ sudo adduser sergej
Adding user `sergej’ …
Adding new group `sergej’ (1001) …
Adding new user `sergej’ (1001) with group `sergej’ …
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for sergej
Спустя промежуток времени нажимаем на клавиатуре клавишу <S>. При этом будут считаны все сообщения аудита из файла /var/log/messages и обновлены соответствующие профили в /etc/apparmor.d. Вот некоторые события, попадающие в журнал:
$ grep audit /var/log/messages
Jun 18 22:23:32 grinder kernel: [ 1970.732000] audit(1182194612.389:4): PERMITTING r access to /etc/nsswitch.conf (dovecot(7161) profile /usr/sbin/dovecot active /usr/sbin/dovecot)
Jun 18 22:23:32 grinder kernel: [ 1970.732000] audit(1182194612.389:5): PERMITTING r access to /lib/tls/i686/cmov/libnss_compat-2.5.so (dovecot(7161) profile /usr/sbin/dovecot active /usr/sbin/dovecot)
Через некоторое время нажимаем клавишу <F>. Смотрим новый профиль:
$ cat /etc/apparmor.d/usr.bin.passwd
# vim:syntax=apparmor
# Last Modified: Tue Jun 19 11:13:26 2007
#include <tunables/global>
/usr/bin/passwd {
#include <abstractions/base>
/lib/tls/i686/cmov/libc-*.so mr,
/lib/tls/i686/cmov/libcrypt-*.so mr,
/lib/tls/i686/cmov/libdl-*.so mr,
/usr/bin/passwd mr,
}
Теперь в профиле утилиты passwd убираем флаг ‘m’. На лету это можно сделать с помощью утилиты apparmor_parser:
$ sudo echo “/usr/bin/passwd { /usr/bin/passwd r, }” | apparmor_parser –ad
И опять пробуем добавить нового пользователя:
$ sudo adduser sergej
Adding user `sergej’ …
Adding new group `sergej’ (1001) …
Adding new user `sergej’ (1001) with group `sergej’ …
passwd: Cannot determine your user name.
Permission denied
Try again? [Y/n] y
Проверяем результат:
$ grep sergej /etc/passwd
sergej:x:1001:1001:,,,:/home/sergej:/bin/bash
Утилита не смогла создать пароль для нового пользователя.
Но это еще не все. Вновь созданный профиль продолжает работать в щадящем режиме. Через некоторое время следует повторно проанализировать /var/log/messages и уточнить настройки профилей. Для этого используется утилита logprof:
$ sudo logprof
Далее будут показываться найденные нарушения профилей с указанием названия профиля, программы и действия. Все вопросы разбиты на блоки. В первом задается управление дочерними процессами, контролируемыми профилем.
Профиль: /usr/sbin/dovecot
Программа: dovecot
Выполнить: /usr/lib/dovecot/imap
Строгость: неизвестно
[(I)nherit] / (P)rofile / (U)nconfined / (D)eny / Abo(r)t / (F)inish
Нажатие на <r> (Abort) приведет к выходу из genprof с отклонением всех изменений, а <F> (Finish) делает то же, но только все данные сохраняются. Эти параметры означают:
1. Inherit – потомок запускается с тем же профилем, что и родитель.
2. Profile – потомок имеет свой профиль
3. Unconfined – потомок запускается без профиля.
4. Deny – запрет на запуск дочерних процессов.
Далее следует запрос о доступе к функциям POSIX:
Профиль: /usr/sbin/dovecot
Возможность: chown
Строгость: 9
[(A)llow] / (D)eny / Abo(r)t / (F)inish
Здесь несколько проще. Нажатием клавиши <А> или <D> мы разрешаем или запрещаем вызов (в нашем примере вызов chown) соответственно. И третьим блоком идут запросы о пути:
Профиль: /usr/sbin/dovecot
Путь: /
Режим: r
Строгость: неизвестно
[(A)llow] / (D)eny / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t / (F)inish
Кроме знакомых параметров, здесь можно нажать <N> и ввести новый путь, который будет записан в профиль. Очень полезной является возможность глобализации путей, то есть вместо /var/www/index.html в правиле можно указать /var/www/*. Для этого достаточно нажать кнопку <G>, и путь сократится на один уровень. Каждое следующее нажатие будет сокращать его еще на один уровень. Если нужно сохранить расширение файлов, нажимаем <E> (Glob w/(E)xt), и тогда появится запись вроде /var/www/*.html. По окончании работы logprof опять запросит просканировать журнал, для выхода выбираем <F>.
Но это еще не все секреты AppArmor. Для того чтобы определить наличие защищающего профиля, а также соответствие прослушиваемых сетевых TCP/UDP-портов запущенным сервисам, используй утилиту unconfined:
$ sudo aa-unconfined
5194 /usr/sbin/avahi-daemon не ограничен
5266 /usr/sbin/cupsd не ограничен
5290 /usr/sbin/hpiod не ограничен
5293 /usr/bin/python2.5 не ограничен
5391 /usr/sbin/mysqld не ограничен
5621 /usr/lib/postfix/master ограничен
5750 /usr/sbin/dovecot не ограничен
5890 /usr/sbin/apache2 не ограничен
Таким образом создается программный черный список, и администратор может заранее определить потенциально опасные приложения и закрыть дыры.
Итак, пора делать вывод. Система, предлагаемая Novell, обладает высоким уровнем защиты и гораздо легче в настройке, чем SELinux. А относительно простая в реализации возможность самостоятельного создания профиля только добавляет плюсы этой системе.