Безопасный Linux : Часть вторая. AppArmor – разработка профилей

1. Взгляд назад

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

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

2. Профили AppArmor

Безопасность, обеспечиваемая AppArmor, основана на профилях программ. В сущности, профиль является конфигурационным файлом со своим синтаксисом. Издавна принято, что в *nix-системах файлы настроек хранятся в текстовом виде; не являются исключением и профили AppArmor. Рассмотрим какой-нибудь из существующих профилей:user: more /etc/apparmor.d/sbin.syslog-ng
# $Id$
# ------------------------------------------------------------------
#
# Copyright (C) 2006 Novell/SUSE
# Copyright (C) 2006 Christian Boltz
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# ------------------------------------------------------------------

#include <tunables/global>

#define this to be where syslog-ng is chrooted
@{CHROOT_BASE}=""

/sbin/syslog-ng {
#include <abstractions/base>
#include <abstractions/consoles>
#include <abstractions/nameservice>

capability chown,
capability dac_override,
capability fsetid,
capability fowner,
capability sys_tty_config,

/dev/log w,
/dev/syslog w,
/dev/tty10 rw,
/dev/xconsole rw,
/etc/syslog-ng/* r,
@{PROC}/kmsg r,
/etc/hosts.deny r,
/etc/hosts.allow r,
/sbin/syslog-ng mr,
# chrooted applications
@{CHROOT_BASE}/var/lib/*/dev/log w,
@{CHROOT_BASE}/var/lib/syslog-ng/syslog-ng.persist rw,
@{CHROOT_BASE}/var/log/** w,
@{CHROOT_BASE}/var/run/syslog-ng.pid krw,
}

Как видите, синтаксис профиля прост и должен быть интуитивно понятен каждому, кто имел дело с конфигурационными файлами и языками программирования высокого уровня. В профиле допускаются (сравните с синтаксисом известных вам языков программирования!): комментарии (начинаются с символа #), включение правил и определений из других файлов (директива #include) и определение переменных (в примере профиля есть переменная @{CHROOT_BASE}).

2.1. Включаемые профили и предопределенные переменные

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

В состав AppArmor входит большая подборка базовых наборов правил, которые могут быть включены в профиль директивой #include. Они содержатся в каталоге /etc/apparmor.d/abstractions. Будем называть такие наборы правил включаемыми профилями, так как именно в этом и состоит их назначение – они, по сути, являются профилями, но используются только в составе других профилей. Каждый из включаемых профилей разрешает какую-то определенную функциональность, например, проведение аутентификации, использование сервисов разрешения имен, Kerberos и так далее. Обычно назначение – функциональность, которую разрешает включаемый профиль, – понятно из названия файла:user: ls /etc/apparmor.d/abstractions/

authentication
base
consoles
bash


Помимо правил, разрешающих функциональность, AppArmor имеет также набор предопределенных переменных (файлы, описания которых содержатся в каталоге /etc/apparmor.d/tunables) типа @{HOME}, @{HOMEDIRS} и других. Правда, в разнообразии переменные очень далеко отстали от включаемых профилей:user: ls /etc/apparmor.d/tunables/
global
home
ntpd
proc

Конечно, число переменных можно дополнить самостоятельно

2.2. POSIX-возможности и права доступа к файлам и каталогам

Теперь перейдем к самим правилам, разрешающим программе выполнение определенных действий. Правила делятся на разрешающие определенные возможности и устанавливающие права доступа к файлам и каталогам.

Начнем с простого: установление прав доступа – это наиболее естественное и распространенное ограничение, накладываемое на приложение. Установка прав чтения-записи-исполнения может быть полезно для любой программы: вы можете защитить конфигурационные файлы сервера от случайного удаления, собственные конфиденциальные данные – от чтения посторонними программами... Кроме того, даже при установлении ограничений прав доступа AppArmor предлагает широкий набор возможностей, обеспечивающих необходимую для комфортной работы гибкость, включая ограничения, накладываемые на дочерние процессы (таблица 1).

В профиле правила, указывающие доступные программе файлы и каталоги, записываются в следующем виде: «<путь к каталогу> <права доступа>».

Таблица 1. Режимы доступа к объектам AppArmor

По замыслу создателей AppArmor, именно такой набор опций дает необходимые и достаточные возможности ограничения прав доступа программ к файлам и каталогам. Кроме того, дополнительный контроль дочерних процессов позволяет (избегая недостатков chroot) не выпускать из отдельной «песочницы» не только исходное запущенное приложение, но и его потомков. Однако, как не без основания указывается в документации (см. п. 4 в разделе «Ресурсы»), необходимо избегать применения последних двух опций, так как они выводят дочерние процессы из под контроля AppArmor. Нетрудно также догадаться, что некоторые опции являются взаимоисключающими (например, ix и px).

AppArmor также способен контролировать другие возможности, не касающиеся прав чтения-записи-исполнения файловых объектов. В правилах профиля можно указывать разрешения на использование указанных в стандарте POSIX возможностей (например, изменение приоритетов выполнения процессов).

Каждая такая возможность записывается за ключевым словом capability, а полный список доступных POSIX-возможностей можно увидеть, выполнив команду man capabilities (не забудьте при создании правила убрать «CAP_» из названия возможности). Например, в примере профиля sbin.syslog-ng программе даются возможности chown (POSIX-возможность CAP_CHOWN) – произвольное изменение UID и GID файла; dac_override (по стандарту – CAP_DAC_OVERRIDE) разрешает программам, запускаемым привилегированным пользователем, не принимать во внимание режимы доступа к файлам и так далее.

3. Создание новых профилей

Удобства пользователя AppArmor не заканчиваются понятным синтаксисом профиля. В состав AppArmor входит набор утилит, помогающих создавать профили для различных (включая собственные) программ: autodep, genprof и logprof (в системе есть также символические ссылки на эти команды, которые имеют суффикс «aa-», указывающий на принадлежность AppArmor: aa-autodep, aa-genprof и aa-logprof). Эти утилиты призваны значительно упростить процесс создания профиля. Попробуем с их помощью создать профиль для утилиты passwd (профиль для этой программы уже есть в дополнительном наборе профилей в каталогах /etc/apparmor/profiles/extras и /usr/share/doc/apparmor-profiles/extras в OpenSUSE и Ubuntu соответственно – тем лучше, потом можно будет сравнить результаты).

3.1. Создание нового профиля на примере программы passwd

Создание нового профиля требует некоторого времени и повышенного внимания. Тем не менее, ничего необратимо разрушительного сделать нельзя – вы всегда можете удалить неудачный профиль и вернуться к первому шагу.

Все дальнейшие действия описываются применительно к OpenSUSE 11.1. Однако создание профилей в других дистрибутивах с установленным AppArmor (например, Ubuntu или Mandrive) также не должно вызвать затруднений.

Шаг 1.

Создайте базовый профиль программы с помощью утилиты autodep:root: autodep passwd

У вас любезно поинтересуются, нужно ли создавать новый профиль или достаточно просто скопировать имеющийся:

Профиль: /usr/bin/passwd

[1 – Неактивные локальные профили для /usr/bin/passwd]

[(V)iew Profile] / (U)se Profile / (C)reate New Profile / Abo(r)t / (F)inish

Нажмем «C» – создание нового профиля.

Зыписывается обновленный профиль /usr/bin/passwd.

Все заметили опечатку переводчика, но великодушно простили ее – ошибки делают все...

Взглянем, что получилось:root: more /etc/apparmor.d/usr.bin.passwd
# Last Modified: Sat Apr 11 11:26:24 2009
#include <tunables/global>

/usr/bin/passwd flags=(complain) {
#include <abstractions/base>
}

Немного... Скорее смахивает на шаблон, чем на реальный профиль. Зато этот профиль автоматически помещен в режим complain, что пригодится на следующих шагах.

Шаг 2.

Запустите утилиту профилировки genprof:root: genprof passwd


Профилирование: /usr/bin/passwd

[(S)can system log for SubDomain events] / (F)inish

При старте утилита genprof выводит подсказку – нужно в отдельном окне (не прерывая работу genprof) запустить профилируемое приложение и «продемонстрировать работу программы», т.е. выполнить все то, что вы обычно делаете, и что является обычным для программы. Функции, выполняемые программой passwd, не очень разнообразны, поэтому достаточно просто сменить пароль пользователя:root: passwd user
Changing password for user.


Пароль изменён.

В это время AppArmor в своих лог-файлах фиксирует все обращения профилируемой программы к файлам и каталогам, а также записывает информацию об использовании возможностей POSIX:root: more /var/log/audit/audit.log
...
type=APPARMOR_ALLOWED msg=audit(1239521867.624:29856):
operation="inode_rename" requested_mask="rw::" denied_mask
="rw::" fsuid=0 name="/etc/shadow.tmpPtB7Ev" pid=6011 profile="/usr/bin/passwd"

Закончив работу с приложением, нажмите в окне терминала с запущенной утилитой genprof кнопку «S», а затем поочередно разрешайте действия, произведенные профилируемой программой:...
Профиль: /usr/bin/passwd
Путь: /lib/security/pam_deny.so
Режим: owner mr
Строгость: неизвестно
1 – #include <abstractions/authentication>
2 – /lib/security/pam_deny.so
[3 – /lib/security/pam_*.so]

[(A)llow] / (D)eny / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t / (F)inish / (O)pts

Добавляется /lib/security/pam_*.so owner mr в профиль.

...

Представляемый выбор требует небольшого пояснения:

Allow – разрешить действие;
Deny – запретить действие;
Glob – разрешить действия со всеми файлами указанного каталога;
Glob w/Ext – разрешить действия со всеми файлами этого типа (с таким расширением) в указанном каталоге;
New – включает режим редактирования – вы сможете указать другой путь к файлу/каталогу вместо предложенного genprof;
Abort – прервать работу, при этом будут потеряны все изменения – профиль останется таким, каким был до запуска genprof;
Finish – завершить работу утилиты genprof. При этом сохраняются все изменения, сделанные в правилах;
Opts – выводит дополнительные опции правила.

Нередко genprof предлагает пользователю выбор из нескольких вариантов правил (они пронумерованы, а предлагаемый вариант заключен в квадратные скобки), между которыми можно переключаться, нажимая цифру, соответствующую номеру правила. В приведенном выше примере варианты следующие: 1 – #include <abstractions/authentication>
2 – /lib/security/pam_deny.so
[3 – /lib/security/pam_*.so]

Здесь предлагается подключить шаблон аутентификации <abstractions/authentication>, либо разрешить доступ к файлу /lib/security/pam_deny.so, либо разрешить доступ к файлам по шаблону /lib/security/pam_*.so. Последний вариант является активным – выбрав Allow, вы внесете в профиль правило с разрешением доступа ко всем файлам по указанному шаблону.

Итоговый профиль будет переведен в режим enforce. Его работоспособность можно проверить, снова запустив программу passwd: если пароль удалось сменить, значит, лишнего вы ничего не запретили.

В результате, после нескольких не очень удачных попыток, итоговый профиль получился следующим:/usr/bin/passwd {
#include <abstractions/authentication>
#include <abstractions/base>
#include <abstractions/nameservice>

capability chown,
capability sys_resource,

/etc/.pwd.lock wk,
/etc/pwdutils/logging r,
/etc/shadow rwl,
/etc/shadow.* rwl,
/proc/*/mounts r,
/proc/filesystems r,
/usr/bin/passwd r,
owner /usr/share/cracklib/pw_dict.hwm r,
owner /usr/share/cracklib/pw_dict.pwd r,
owner /usr/share/cracklib/pw_dict.pwi r,
}

В случае, если получившийся профиль по каким-то причинам вам не нравится (слишком много похожих правил или было разрешено что-то совсем ненужное программе), то можно либо повторить процедуру, либо отредактировать профиль вручную. Например, если у вас на основе предложения genprof было создано правило owner /etc/shadow.tmpm755bg rw,

то его необходимо изменить на такое:/etc/shadow.* rw,

(или, как вы увидите ниже, можно еще больше сузить рамки:owner /etc/shadow.tmp?????? rw,).

Программа passwd создает временный файл, который имеет в имени за shadow.tmp случайную строку (из шести символов), поэтому права на чтение и запись должны быть предоставлены для всех таких файлов.

По умолчанию в правилах будет записан параметр owner (почему-то не фигурирующий в официальной документации) – он указывает, что доступ к файлу/каталогу разрешен только для владельца. Для утилиты passwd это неактуально, а для программ, используемых разными пользователями, это очень важная возможность. Например, при разрешении доступа браузера к файлам настроек/истории и т.д. используйте правило типаowner /home/*/.firefox/** rw,

В этом случае, запустив Firefox, вы можете быть уверены, что программа сможет получить доступ только к подкаталогу .firefox домашнего каталога пользователя, запустившего браузер (который и является владельцем всех файлов и подкаталогов .firefox).

В двух последних примерах правил мы применили шаблоны подстановок (globs). С помощью этих шаблонов можно задавать разнообразные пути и имена файлов (таблица 2).

Таблица 2. Шаблоны подстановок

При использовании шаблонов * и ** возникают некоторые нюансы, которые могут оказаться полезными на практике. Продемонстрируем их на примере: /tmp/* – все файлы в каталоге /tmp
/tmp/*/ – все каталоги в каталоге /tmp
/tmp/** – все файлы и каталоги по иерархии ниже каталога /tmp
/tmp/**/ – все каталоги по иерархии ниже каталога /tmp

После редактирования профиля вручную требуется указать AppArmor на необходимость заново прочитать профили программ:root: rcapparmor restart

3.2. Сравнение с эталоном

Теперь сравним получившийся у нас профиль с имеющимся «в запасе» у AppArmor. Для этого можно воспользоваться утилитой diff или сравнить файлы самостоятельно в текстовом редакторе (размер профилей невелик).

Отличия представлены в таблице 3.

Таблица 3. Отличия между самодельным и оригинальным профилями

Необходимо также заметить, что строчки/usr/share/cracklib/pw_dict.hwm r,
/usr/share/cracklib/pw_dict.pwd r,
/usr/share/cracklib/pw_dict.pwi r,

в профиле появились только после запуска утилиты passwd от имени обычного пользователя.

Итак, мы создали профиль, контролирующий поведение утилиты passwd на основе принципа «запрещено все, что не разрешено явно». При этом наш профиль получился даже лучше, чем поставляемый в комплекте с AppArmor! Да и создание его – не такой уж и сложный процесс.

4. Что защищать?

Но это еще не все возможности, которые любезно предоставляет AppArmor. Одна из самых сложных проблем – это определение тех утилит, сервисов и программ, которые требуют защиты. Здесь на помощь приходит утилита unconfined из набора средств AppArmor. Не секрет, что наибольший риск несут те программы, которые доступны потенциальным злоумышленникам через сеть. Утилита unconfined предоставит список работающих программ, которые имеют открытые TCP и UDP-порты, а также укажет на наличие/отсутствие профилей для этих программ:$ unconfined
2494 /usr/sbin/avahi-daemon не ограничен
3266 /usr/sbin/cupsd не ограничен
5490 /usr/sbin/hpiod не ограничен
5493 /usr/bin/python2.5 не ограничен
6391 /usr/sbin/mysqld не ограничен
6621 /usr/lib/postfix/master ограничен
6725 /usr/sbin/dovecot не ограничен
6870 /usr/sbin/apache2 не ограничен

Таким образом, вы всегда сможете создать свой «черный список» программ, отвечающих на запросы из сети, и соответствующим образом их защитить.

5. Заключение

Во второй части из серии статей «Безопасный Linux» мы детально рассмотрели процесс создания профиля приложения на примере утилиты passwd. Теперь можно упрочить авторитет Linux в области безопасности, защитив систему не только от известных «дыр», но и от тех, которые будут найдены еще не скоро!

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

http://www.ibm.com/developerworks/ru/library/l-apparmor-2/

Обновлено: 13.03.2015