LXF108:DrBraun3

Материал из Linuxformat.

Перейти к: навигация, поиск

AppArmor

Посадите свои приложения на карантин – для их же блага и чтобы защитить систему.
Другие дистрибутивы

Я запускал свой пример на Ubuntu 8.04, но профили и команды AppArmor должны выглядеть почти так же в любом другом дистрибутиве. В SUSE добавлен ряд графических оболочек вокруг утилит AppArmor, работающих из командной строки; они доступны через YaST. Ниже показан экранный снимок YaST из OpenSUSE 10.3, идентичный описанному здесь диалогу Genprof.

Один из проектов, основанных на черновиках Posix – это AppArmor. Изначально разработанный Immunix и купленный Novell в 2005 г., он был включен в SUSE Linux, а также поддерживается в Ubuntu и Mandriva (Red Hat вместо этого выбрал SELinux). По сути, AppArmor – это профиль на базе ядра, закрывающий программе доступ к не относящимся к ней ресурсам и указывающий, какие возможности POSIX ей требуются для нормальной работы. Профили хранятся в текстовых файлах в каталоге /etc/apparmor.d. Имя профиля совпадает с именем исполняемого файла, к которому он относится, но слэши заменены точками. Например, профиль для /usr/sbin/traceroute (сетевой утилиты, выводящей путь, по которому проходит пакет, чтобы достичь заданного адреса в Интернете) находится в файле /etc/apparmor.d/usr.sbin.traceroute. Давайте заглянем в него:

 1. #include <tunables/global>
 2. /usr/sbin/traceroute flags=(complain) {
 3. #include <abstractions/base>
 4. #include <abstractions/consoles>
 5. #include <abstractions/nameservice>
 6. capability net_raw,
 7. /usr/sbin/traceroute rmix,
 8. @{PROC}/net/route r,
 10. }

Строка 2 говорит, что данный профиль принадлежит программе /usr/sbin/traceroute, и что при загрузке его в ядро он будет работать в неактивном режиме complain [англ. «жалоба»]. Другими словами, AppArmor не будет принуждать к выполнению политики, но занесет в файл журнала все ее нарушения. Это также называется режимом обучения – почему, узнаем чуть позже. В строках 3, 4 и 5 подключаются правила из трех других файлов в каталоге abstractions. Будь мы «в объектно-ориентированном настроении», мы сказали бы, что профиль traceroute наследуется от этих трех базовых классов. AppArmor охотно подключает файлы, чтобы «вынести за скобку» общие наборы ресурсов; например, в файле abstractions/nameservice содержатся правила для разрешения DNS, LDAP, NIS, SMB, поиска реквизитов пользователей и групп в парольных файлах, которые являются общими для многих программ.

Самое сердце профиля traceroute – строки 6 и 7. Шестая строка говорит, что программа может использовать возможность net_raw. Это одна из тех возможностей POSIX, о которых мы говорили выше; там она называется CAP_NET_RAW. Данная возможность разрешает программе использовать raw-сокеты, то есть собирать собственные IP-датаграммы. (Ей это необходимо: при работе traceroute корректирует поле TTL – «время жизни» – заголовка IP-пакета.) Строка 7 сообщает, что программе нужен доступ к файлу /usr/bin/traceroute – rmix' определяет требуемое сочетание режимов доступа и по существу выдает программе права на чтение и выполнение этого файла. Строка 8 говорит, что программе нужен доступ на чтение к /proc/net/route. (Обозначение @{PROC} ссылается на переменную, определенную в <tunables/global> и задающую точку монтирования файловой системы procfs. В любом Linux это почти наверняка /proc.)

В каждую мелочь можно не вникать, но общая идея понятна: профиль определяет, к каким ресурсам программа должна иметь доступ. Подчеркнем, что профили AppArmor не заменяют и не обходят основной механизм управления правами в Linux. Например, включение net_raw в профиль traceroute не предоставит программе данной привилегии, если ей уже отказано в этом. Но ИСКЛЮЧЕНИЕ возможности net_raw из профиля ОТКЛЮЧИТ эту возможность, даже если она имелась ранее (например, программа была запущена пользователем root).

Для активации профиля нужно принудительно загрузить его в ядро. Сделайте это с помощью команды enforce:

  $ enforce traceroute
  Setting /etc/apparmor.d/usr.sbin.traceroute to enforce mode.

Обычно это происходит во время старта в init-скриптах. Обратно в режим complain профиль переключается командой complain:

  $ complain traceroute
  Setting /etc/apparmor.d/usr.sbin.traceroute to complain mode.

Чтобы увидеть, какие профили сейчас загружены, выполните скрипт запуска apparmor с аргументом “status”. Вот несколько строк из этого примера:

  $ sudo /etc/init.d/apparmor status
  apparmor module is loaded.
  14 profiles are loaded.
  4 profiles are in enforce mode.
  /home/chris/kilroy
  /bin/date
  /usr/sbin/traceroute
  /usr/sbin/avahi-daemon
  10 profiles are in complain mode.
  /usr/sbin/ntpd
  /usr/sbin/identd
  /usr/sbin/nmbd
  ... СТРОКИ ОПУЩЕНЫ ...

Откуда берутся профили?

Да, откуда же они берутся? Ну, можно усесться за исходный код программы, обмотав голову мокрым полотенцем, определить, какие ресурсы требуются и создать профиль «вручную»: ведь это всего лишь текстовый файл. А можно поискать готовый вариант среди включенных в ваш дистрибутив Linux. Например, в Ubuntu в пакете AppArmor-profiles их около ста. Имеется также «биржа» профилей (сайт http://apparmor.opensuse.org). Но всего интереснее, что AppArmor умеет создавать профили сам, если приложения запускаются в режиме «обучения». Чтобы показать, как это работает, создадим профиль для несложной программы на C:

В SUSE Linux есть графический мастер для управления профилями AppArmor, как часть YaST.

#include <stdio.h>
 int main(int argc, char *argv[])
 {
   int i;
   FILE *fd;
   for (i=1; i<argc; i++) {
     fd = fopen(argv[i], “w”);
     if (fd == NULL) {
       fprintf(stderr, “failed to open %s\n”, argv[i]);
       return 1;
     }
     fprintf(fd, “kilroy was here”); fclose(fd);
   }
 }

Если вы не знаете C, ничего страшного. Программа названа kilroy.c, потому что она просто выводит строку “kilroy was here” [по-нашему, «Здесь был Вася», – прим. ред.] во все файлы, имена которых ей передаются. Я скомпилировал программу:

 $ cc kilroy.c -o kilroy

и если запустить ее так:

 $./kilroy foo bar

то она откроет файлы foo и bar и запишет в них строку. В терминах AppArmor, сейчас программа работает «свободно», так как для нее нет профиля, загруженного в ядро. Она подчиняется только традиционному контролю доступа к файлам в Linux.

Чтобы сгенерировать профиль для kilroy, выполните команду genprof (как root) с именем программы в качестве аргумента:

 # genprof /home/chris/kilroy

Genprof загрузит профиль в ядро в режиме complain и предложит «Запустить программу в новом окне и проявить ее функционал» (“Start the application to be profiled in another window and exercise its functionality now”). Идея состоит в том, чтобы сейчас выполнить полный набор обычных действий программы. Для своего игрушечного примера я просто наберу команду:

 $ ./kilroy foo bar.txt

Так как kilroy запущена в режиме complain, то все действия, запрещенные программе, заносятся в журнал. (Поскольку профиля пока нет, заносятся вообще все действия.) Итак, в журнале сейчас три записи: маркер и открытие на запись файлов foo и bar.txt. Когда я решу, что «проявление функционала» завершено, я вернусь в окно, где запущена genprof. genprof пройдется по записям в журнале (для этого вызывается вспомогательная программа logprof) и спросит меня, разрешить или запретить каждую из них, а также предоставит возможность обобщить записи с помощью шаблонов. Весь диалог длинный, поэтому привожу фрагмент:

 # genprof /home/chris/kilroy
 Writing updated profile for /home/chris/kilroy.
 Setting /home/chris/kilroy to complain mode.

Пожалуйста, запустите приложение, профиль которого нужно создать, в другом окне и выполните все обычные действия. Потом нажмите на кнопку Сканировать (Scan), чтобы найти события AppArmor в системных журналах. Для каждого из них можно будет разрешить или запретить доступ.

 Profiling: /home/chris/kilroy
 [(S)can system log for SubDomain events] / (F)inish
 Reading log entries from /var/log/messages.
Updating AppArmor profiles in /etc/apparmor.d.
Enforce-mode changes:
 .. СТРОКИ ОПУЩЕНЫ ...
 Profile: /home/chris/kilroy
 Path: /home/chris/bar.txt
Mode: w
 Severity: 6
 1 - /home/chris/bar.txt
 2 - /home/*/bar.txt
 [3 - /home/chris/*.txt]
 (A)llow / [(D)eny] / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t /
 (F)inish
Adding /home/chris/*.txt w to profile.
... МНОГО СТРОК ОПУЩЕНО ...

Во второй половине листинга Genprof сообщает, что kilroy открыл файл /home/chris/bar.txt на запись, и я решил обобщить это правило, позволив ему записывать данные в любой файл с именем /home/chris/*.txt. В данном случае мое решение было произвольным; но на практике нужно хорошенько подумать!

По завершении работы Genprof новый профиль сохраняется и автоматически переходит в режим enforce. Результат наших трудов (/etc/apparmor.d/home.chris.kilroy) выглядит следующим образом:

Карантин компьютера

В исходной документации AppArmor говорилось об «иммунизации» приложений, но для предотвращения взлома ничего не делается; скорее, ограничивается возможный ущерб на случай такой беды. «Карантин», пожалуй, более уместная медицинская метафора. Представьте, что AppArmor дает программе большой белый носовой платок – чихать в него, чтоб не сеять вокруг себя микробы.

 # Last Modified: Mon Apr 7 16:17:04 2008
 #include <tunables/global>
 /home/chris/kilroy {
 #include <abstractions/base>
 /home/chris/*.txt w,
 /home/chris/foo w,
 /home/chris/kilroy mr,
 }

Теперь программа kilroy ограничена своим профилем и может делать не все. Например,

 $ ./kilroy foo apple.txt banana.txt

работает отлично, а

 $ ./kilroy orange.txt cabbage
 failed to open cabbage

не пройдет, так как открытие файла cabbage на запись не разрешено профилем, и вызов fopen() завершится неудачно.

Это игрушечный пример. Чтобы создать профиль для настоящей программы, придется продумать, какие ситуации прокрутить, чтобы задействовать все ее возможности. Обычно сперва с помощью genprof создается начальный профиль, затем он на несколько дней переключается в режим complain. Потом запускается logprof, чтобы отследить все нарушения и решить, стоит ли добавлять их в профиль. Наконец, профиль переключается в режим enforce.

В чем же тут польза? Допустим, программу kilroy каким-то образом взломали – например, атакой с переполнением буфера – и вынуждают ее сделать нечто такое, для чего она не предназначалась. Но она не сможет выйти за пределы своего профиля! AppArmor лучше всего работает с теми программами, чей набор операций четко ограничен. Например, почтовый сервер оперирует строго определенными файлами и каталогами, и с помощью профиля AppArmor его можно эффективно контролировать. Особенно полезен AppArmor в ограничении тех программ, которые являются «посредниками в передаче прав», т.е. приложений, которых вы просите сделать что-то от своего имени, но с правами другого пользователя. В эту категорию входит большинство сетевых серверов. Для более подробной информации прочтите man для apparmor, apparmor.d (описывает синтаксис профилей), genprof, logprof, enforce и complain, или зайдите на сайт ttp://en.opensuse.org/Apparmor. LXF

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию