Журнал LinuxFormat - перейти на главную

LXF83:AppArmor

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

Содержание

Армированный Linux

AppArmor – отличный, гибкий инструмент безопасности для Linux. Его создатель, Криспин Коуэн, поведает вам о нем.


Основная беда безопасности приложений – невозможно сказать, как поведет себя ваше приложение в нестандартных условиях: число состояний и вариантов ввода слишком велико, чтобы исчерпывающе протестировать даже небольшую программу. Когда это выливается в проблему? Когда некто обнаруживает, что определённый набор входных данных приводит к некорректному поведению программы, и разрабатывает приложение, эксплуатирующее найденную уязвимость (подобные приложения так и называют – эксплойты, exploits).

Для решения проблемы эксплойтов и разработан AppArmor. AppArmor обеспечивает безопасность приложений, заставляя их делать только то, что они обязаны делать и не более того. Конкретно, AppArmor контролирует файлы и функции POSIX.1e (см. man 7 capabilities), к которым приложение имеет доступ, поскольку контроль над этими ресурсами и привилегиями на вашей машине и есть мечта злоумышленника. В данной статье мы разъясним, как настроить и использовать AppArmor для защиты ваших программ и системы от атак.

AppArmor полностью интегрирован в SUSE Linux 10.1, SLES 9 SP3 и SUSE Linux Enterprise 10. Он устанавливается и работает по умолчанию, но использует скромный набор профилей (об этом позже). Намного больший набор профилей можно найти в /etc/apparmor/profiles/extras/; вы можете скопировать их в /etc/apparmor.d, где хранятся активные профили. В SUSE, интерфейс пользователя Yast содержит кнопку AppArmor, которая выводит графический эквивалент описываемых здесь инструментов genprof и logprof.

AppArmor вступил в жизнь как проприетарная система, но после приобретения Immunix Inc в 2005 году фирмой Novell приложение выпускается по лицензии GPL. С тех пор AppArmor был портирован на Slackware, Ubuntu и Pardus Linux, турецкий дистрибутив.

Для установки AppArmor в Ubuntu, выполните

sudo dpkg -i apparmor-* libapparmor1_2.0-0ubuntu2_i386.deb linux-image-2.6.15-21-386_2.6.15-21.32mr1_i386.deb

Заметьте, что эти пакеты включают новое ядро, поскольку для поддержки AppArmor необходима небольшая заплатка для ядра. Ubuntu основан на Debian, так что пакеты прекрасно подойдут для Debian, MEPIS и прочих систем на базе Debian. Если вы хотите использовать AppArmor в другой системе Linux, потребуется его портировать – см. врезку «Двигаемся дальше».

Обезопасим NTPD

Теории достаточно; обратимся к примеру. Рассмотрим NTPD, Network Time Protocol Daemon. Он обеспечивает синхронизацию вашей системы с главным сервером вашей локальной сети или с интернетом – важная задача! Однако для изменения вашего системного времени NTPD потребуются привилегии суперпользователя (root), а также открытый сетевой порт, чтобы узнавать время на главном сервере. В итоге получается убойная комбинация: открытый сетевой порт и доступ к процессам с правами суперпользователя – классический пример из руководства по безопасности. Злодей, нашедший уязвимость в коде NTPD, сможет атаковать демона NTP и получить права суперпользователя на вашем компьютере.

Права суперпользователя отнять нельзя – ведь тогда NTPD не сможет менять время; открытый сетевой порт удалить тоже нельзя – тогда NTPD не сможет узнавать время. Тут-то и поможет AppArmor, ограничив привилегии NTPD посредством профиля безопасности. Вот AppArmor-профиль для программы ntpd:

/usr/sbin/ntpd {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  capability ipc_lock,
  capability net_bind_service,
  capability setgid,
  capability setuid,
  capability sys_chroot,
  capability sys_resource,
  capability sys_time,
  /drift/ntp.drift rwl,
  /drift/ntp.drift.TEMP rwl,
  /etc/ntp.conf r,
  /etc/ntp/drift* rwl,
  /etc/ntp/keys r,
  /etc/ntp/step-tickers r,
  /tmp/ntp* rwl,
  /usr/sbin/ntpd rix,
  /var/lib/ntp/drift rwl,
  /var/lib/ntp/drift.TEMP rwl,
  /var/lib/ntp/drift/ntp.drift r,
  /var/lib/ntp/var/run/ntp/ntpd.pid w,
  /var/log/ntp w,
  /var/log/ntp.log w,
  /var/run/ntpd.pid w,
}

Сейчас ntpd запускается от имени root, то есть имеет доступ ко всем функциям POSIX.1e. Но этот профиль ограничивает доступ ntpd семью функциями, описанными в коде. Будучи root-процессом, ntpd мог бы читать, записывать и запускать любой файл в файловой системе, но теперь ему доступны только файлы, описанные в профиле.

Что же произойдёт, при наличии данного профиля, если злоумышленник припас программу-эксплойт, направленную против ntdp? Будьте спокойны: ничего. У него нет прав на выполнение, а значит, простой shell-код [«полезная нагрузка» эксплойта, выполняющая задуманные злоумышленником действия, – прим. ред.] вида exec(sh) не пройдет. Если ntpd зачем-либо потребуется командная оболочка (shell), злоумышленник сможет запустить ее, но только из-под профиля, и сможет читать и записывать лишь файлы, принадлежащие ntpd на основании профиля. Короче говоря, злоумышленник сможет разве что изменить ваше системное время. AppArmor разрешил ntpd выполнять только конкретные операции – в литературе по безопасности это называется запуском приложения с наименьшими привилегиями.


Как обезопасить Apache и другие приложения

В мире огромное число приложений – фактически бесконечное, ведь люди не перестают писать код. И если вы собираетесь использовать систему безопасности, контролирующую деятельность приложений, очень важно, чтобы поддержка совместимости политик безопасности с программным обеспечением была простой, особенно при наличии постоянно прибывающих новых приложений.

Профили AppArmor достаточно просты: нетрудно сообразить, как создать их вручную. Фактически, когда в 1998 г. появился AppArmor, именно так и делалось. Сейчас AppArmor поставляется с обучающейся системой: вы запускаете ваши приложения как обычно, а AppArmor следит и запоминает, что требуется разрешать приложению.

Выбрав приложение, для которого нужно разработать профиль, вы отсылаете модулю ядра исходный вариант профиля, функционирующий в режиме ‘complain’ («жалоба»): нарушения политик не блокируются, а записываются в log-файл (журнал). Затем вы запускаете приложение обычным способом, и оно какое-то время работает, заодно заполняя журнал событий, характеризующих его поведение. После этого вы применяете к созданному журналу анализатор AppArmor, который задаст вам интерактивные вопросы о добавлении событий в окончательный профиль.

Фабричные профили

Скрипты, поставляемые с AppArmor, выполнят за вас большую часть работы. Посмотрим, как можно создать профиль для вашего web-сервера и его web-приложений. Выполните от имени суперпользователя (root) genprof /usr/sbin/httpd2-prefork. Если для Apache ещё нет профиля, genprof создаст его, а если есть, то воспользуется уже существующим. Загрузив профиль в ядро в complain-режиме и попросив вас запустить ваше приложение с другого терминала или иным способом, genprof примется создавать журнал событий. В случае Apache, поупражняйтесь с /etc/init.d/apache stop и /etc/init.d/apache.

Затем посетите ваш web-сайт и займитесь обслуживаемыми web-страницами. Как вы скоро увидите, посещать каждую отдельную страницу не обязательно, хотя это довольно просто, если использовать «паучка», например: wget --mirror http://example.com. Зато следует запустить каждый исполняемый файл, относящийся к сайту. Посетив достаточное для представления количество web-страниц, вновь выполните /etc/init.d/Apache stop и вернитесь к genprof.

Нажмите S, чтобы попросить genprof просканировать журнал событий, который находится в /var/log/audit/audit.log, и genprof задаст вам серию вопросов о том, как обрабатывать события. Вопросы задаются по блокам; первый – об управлении дочерними процессами, запускаемыми из программы, для которой создается профиль. Выберите из следующего:

Inherit (наследование) Дочернее приложение (потомок) запускается с тем же профилем безопасности, что и родитель. Идеально для служебных программ; пример – сценария командной оболочки, запускающего программу cp с целью скопировать файл.

Profile (профиль) Потомок имеет свой профиль. Осторожно: этот профиль имеет действие во всей системе, так что для его создания вам придётся проделать большую работу. Если этого потомка (например, web-приложение, обычно запускаемое web-сервером) использует только одна программа, то выбор P является безопасным. Если потомок используется разными программами, придётся погонять его во всех режимах, чтобы правильно определить его поведение для профиля.

Unconfined (неограниченный) Потомок запускается вообще без профиля. Это очень опасный выбор, предполагающий, что у потомка нет уязвимостей. Он существует преимущественно для того, чтобы позволить системным администраторам удаленно управлять AppArmor, потому как программам с ограничениями манипуляции с AppArmor не разрешены.

Deny (запрещено) просто не позволяет родителю запускать этого потомка.

В каждом из блоков вопросов также имеются дополнительные опции abort, которая отменяет все изменения и выходит из genprof, а также Finish, которая обрывает создание профиля на данном этапе и осуществляет выход.

Следующий блок вопросов касается функций POSIX.1e. Здесь имеются опции Allow (Разрешить) приложению доступ к этим функциям, или Deny (Запретить). Если вы уверены, что ваше приложение не атаковалось в момент обучения, то Allow, скорее всего, верный ответ. Однако если профиль создается на машине, открытой для Интернета, ваше приложение вполне может быть атаковано во время «обучения», и здесь нужна осторожность. Создание профиля приложений подобно обучению детей: они учатся на примерах, поэтому не делайте ничего дурного в их присутствии. Последний блок вопросов касается доступа к файлам. Кроме простых Allow и Deny, здесь есть опции:

Glob this access («Глобализовать» доступ) Каждое нажатие клавиши G заменяет на шаблон очередной уровень «хвоста» полного (включающего путь) имени файла. Одно нажатие G превратит /srv/www/htdocs/images/star.gif в /srv/www/htdocs/images/*, второе – в /srv/www/htdocs/*, и т.д.

Glob with extensions («Глобализовать» с расширением) Создаёт шаблон из последней части пути и расширения, так что /usr/local/myfile.html превратится в /usr/local/*.html.

New path specifier (Описание нового пути) Добавьте свой собственный путь путем создания шаблонов вручную, используя *, ?, [, ], -, { и }.

Получив ответ на все вопросы, genprof вновь попросит перейти к сканированию журнала; на сей раз нажмите F. Программа genprof завершится, переведя профиль Apache в режим подавления (enforce-режим). Вам не потребуется перезапускать Apache; AppArmor может изменять статус профилей на фоне запущенного процесса. Теперь ваша система функционирует с ограничениями AppArmor согласно созданной вами политике. Эта политика будет работать и после перезагрузки – вы можете посмотреть ее в /etc/apparmor.d/usr.sbin.httpd2-prefork.

Общие правила

Вопросы о файловом доступе, на которые вы отвечали, лишь номинально относятся к запретам. Намного важнее возможность создать общее правило доступа к файлам. Простейший случай – работа с временными (temporary) файлами, которым обычно намеренно даются случайные имена. Заменив последнюю часть пути шаблоном, вы будете уверены, что программа будет нормально работать, а не закроется с ошибкой, потому что имена временных файлов с каждым запуском меняются.

Другой пример обобщения – имена библиотек. Например, если программе необходим доступ к /usr/lib/libdb_cxx-4.3.so, наш друг genprof может предложить альтернативу /usr/lib/libdb_cxx-*.so, чтобы профиль работал и после обновления версии библиотеки. Пользователю предоставляется компромисс: широкое использование шаблонов сделает профили более удобными и безотказными, но платой за это будут большие разрешения и, как следствие, снижение безопасности. Но даже с широким использованием шаблонов профили AppArmor все еще более безопасны, чем без AppArmor.

Вот ещё один пример: genprof замечает, что событие доступа имеет соответствие в каталоге abstractions, и предлагает, скажем, нечто вроде #include <abstractions/nameservice>, тем самым обеспечивая все правила доступа, необходимые для DNS-запросов и локальных UID-запросов.

Под надзором

Программа genprof помещает отметки в журнале и, таким образом, обучается только на событиях, происходящих в течении данной сессии genprof. Но вы можете обучать программу хоть целую неделю, невзирая на перезагрузки. Команда complain /usr/bin/моя_программа или complain /etc/apparmor.d/usr.bin.моя_программа переведет профиль программы моя_программа в complain-режим и оставит его в этом состоянии, а complain/etc/apparmor.d/* переводит все профили вашей системы в complain-режим.

Запустите ваше приложение на сколь угодно долгое время, позаботившись, чтобы все журналы сохранялись и не удалялись при ротации. Когда вы посчитаете, что набрали достаточное количество событий, используйте программу logprof для обработки журнала так же, как делает genprof – только logprof прочитает весь файл журнала. logprof имеет ключи командной строки, указывающие, где искать журналы, с какого места журнала начинать анализ и где находится профиль, подлежащий обновлению.

Чтобы полностью разделить процессы обучения и создания профиля, отработайте все обучающие режимы для генерации журнала событий на большой тестовой машине в QA-подразделении, а затем просто отправьте набор профилей и log-файлов по электронной почте эксперту по безопасности, который при помощи logprof преобразует события в профили. По завершении выполните команду enforce, которая работает точно так же, как команда complain, но переводит все профили в режим ‘enforce’ («подавление»).

Эти команды AppArmor могут быть выполнены только из командной оболочки root, причём оболочка должна быть свободна от ограничений AppArmor. Все команды также имеют псевдонимы, начинающиеся с aa-, таким образом вы сможете обнаружить все команды AppArmor в вашей системе, просто набрав aa-<TAB> в root-строке.

Как обезопасить свою систему и рабочий стол

Существует две системы политик безопасности. Системы Черного списка перечисляют запрещенные вещи*, а всё остальное разрешается; таким образом, это системы, разрешающие по умолчанию. Системы Белого списка определяют то, что разрешено, а всё остальное запрещается, то есть это системы, запрещающие по умолчанию.

Понятно, что системы Белого списка безопаснее, поскольку злоумышленник не может их обойти, просто приискав экзотический способ нагадить, который не пришёл в голову составителям списка. Но системы Черного списка удобнее для пользователей, потому что они не блокируют вас всякий раз, когда вы изобретаете новый способ применения своего ПК.

AppArmor обходит дилемму «безопасность–удобство», используя гибридную модель. При использовании профиля для конкретной программы AppArmor действует как Белый список: разрешены только указанные файлы и функции, и профиль не позволит злоумышленнику подсунуть программе новый вариант работы во вред. Но на уровне системы AppArmor является Черным списком: ограничиваются только программы, обладающие профилем, и их потомки, а прочие программы работают без ограничений.

Но как же определить, какую программу следует ограничить? Это зависит от вашей модели угрозы. Обязательно должны быть ограничены права всех приложений, имеющих нефильтруемый ввод данных, через которые можно осуществить атаку, потому что AppArmor никак не защищает программы без ограничений.

Открыты сетевые порты

Очень часто встречающаяся модель угрозы – сетевая: плохой парень «откуда-то оттуда», взламывающий ваш сервер или настольный компьютер. AppArmor предлагает обороняться программой unconfined. Она сканирует вашу машину на наличие открытых сетевых портов, находит прослушивающие их программы и выводит их список, а также их профили, если они есть. Если вы создали профили для всех программ, отмеченных в отчете unconfined, все открытые сетевые порты «упрутся» в профили AppArmor, то есть политика AppArmor полностью определит, что сетевой злоумышленник сможет сделать на вашей машине, даже если для всех прочих программ вашей системы вы профилей не создавали.

Вот листинг результата команды unconfined в защищенной системе (web- и mail-сервер в берлоге автора):

4406 /sbin/dhcpcd confined by ‘/sbin/dhcpcd (enforce)’
4758 /sbin/portmap confined by ‘/sbin/portmap (enforce)’
4758 /sbin/portmap confined by ‘/sbin/portmap (enforce)’
5339 /usr/sbin/sshd confined by ‘/usr/sbin/sshd (enforce)’
5479 /usr/sbin/httpd2-prefork confined by ‘/usr/sbin/httpd2-prefork (enforce)’
6151 /usr/sbin/dhcpd confined by ‘/usr/sbin/dhcpd (enforce)’
6151 /usr/sbin/dhcpd confined by ‘/usr/sbin/dhcpd (enforce)’
6263 /usr/lib/postfix/master confined by ‘/usr/lib/postfix/master (enforce)’
6263 /usr/lib/postfix/master confined by ‘/usr/lib/postfix/master (enforce)’
6329 /usr/sbin/xinetd confined by ‘/usr/sbin/xinetd (enforce)’
6329 /usr/sbin/xinetd confined by ‘/usr/sbin/xinetd (enforce)’
8767 /usr/sbin/cupsd confined by ‘/usr/sbin/cupsd (enforce)’
8767 /usr/sbin/cupsd confined by ‘/usr/sbin/cupsd (enforce)’

ПК на замке

Описанный профиль подходит для сервера сетевой группы, поддерживающего web, электронную почту и печать. А как с безопасностью настольных ПК? Используется тот же подход: ограничить все приложения, подверженные атакам из сети. То есть любые приложения, работающие с сетевыми данными.

Некоторые из этих приложений имеют прямой вход из сети, например, почтовый клиент. Другие получают данные из сети опосредованно (например, OpenOffice.org, использующийся для открытия DOC-файлов, которые некто выслал вам в виде почтового вложения). Несмотря на отсутствие прямого соединения с сетью, они осуществляют сетевой ввод и тем создают нешуточную опасность. Анализатор unconfined поможет и здесь, но учтите, что он не сможет найти приложения с чрезвычайно изменчивыми открытыми портами (некоторые IM-клиенты) и, естественно, приложения с опосредованным соединением (такие, как OOo).

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

Гибкость Черного списка всей системы AppArmor позволяет обезопасить только те программы, которые внушают беспокойство. Платой за удобство является необходимость определения таких программ, для чего надо представить себе источники угрозы. Многие из нас ожидают угрозу преимущественно из сети, вот почему программа unconfined столь полезна. По-программный Черный список AppArmor разрешает каждой программе делать только то, что ей полагается, и ничего другого, игнорируя атаки злоумышленников. Комбинация списков помогает вам контролировать работу вашей системы легко и эффективно. Наслаждайтесь!

Проект AppArmor также пытается привлечь больше участников из сообщества Open Source. Если вы администратор или пользователь Linux, вы можете запускать приложения для своих целей и публиковать результаты в списке рассылки apparmor-general (http://forge.novell.com/mailman/listinfo/apparmor-general). Если вы разработчик приложений, подумайте над разработкой и распространением профилей AppArmor с вашим приложением. Намного легче обслуживать профили AppArmor, если они являются частью процесса разработки приложения. Или вы можете помочь в разработке новых возможностей AppArmor. Узнайте больше, посетив http://en.opensuse.org/Apparmor

Персональные инструменты
купить
подписаться
Яндекс.Метрика