Настройка и использование SELinux


Введение.

SELinux - это реализация системы принудительного контроля доступа, которая может работать параллельно с классической системой контроля доступа, используемой в Linux. SELinux изначально был разработан Агентством национальной безопасности США и затем был передан разработчикам открытого кода. В докладе будет рассмотрена настройка политик безопасности SELinux в наиболее распространённых случаях.

С помощью SELinux можно задать явные правила того, как субъекты (пользователи и программы) могут обращаться к объектам системы (файлы и
устройства). Таким образом, можно ограничить программы, прописав возможности их поведения в виде политики, а операционная система обеспечит её соблюдение.

Знакомство с SELinux

Классическая (или дискреционная) модель доступа позволяет манипулировать правами на чтение, запись, поиск/исполнение на уровне пользователей, групп и "остальных", что бывает недостаточно в некоторых случаях. Яркий пример: запуск из-под пользователя некоего сетевого "демона", который может быть скомпрометирован. В этом случае злоумышленник может получить полные права пользователя, который запустил "демона".

Posix ACL (Access Control List) позволяет манипулировать дополнительными условиями доступа, но и этого недостаточно для полной защиты системы.

SELinux позволит дополнительно ограничить сетевого "демона", давая ему полноценно работать, но запрещая подозрительные действия, такие как установление несанкционированного сетевого соединения, чтение или запись файла, который не должен читаться демоном и т.д.

Важно помнить, что SELinux срабатывает только после классической схемы доступа. То есть, если есть некий файл, владелец/группа root:root и права 0600, то какие бы SELinux-метки не стояли, простой пользователь не сможет прочитать этот файл.

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

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

Наиболее распространены следующие три политики:

* Целевая (targered). Эта политика разработана компанией Red Hat и является наиболее используемой;
* Многоуровневая (MLS). Позволяет обеспечивать уровни безопасности и может использоваться госструктурами для хранения информации различных уровней секретности;
* Строгая (strict). Этот вариант политики подразумевает правило "Что не разрешено, то запрещено".

Основные понятия SELinux:

На данном этапе необходимо дать определения основным терминам, используемых в Selinux. Для более простого понимания я параллельно буду
проводить аллегории:

Сущность - этот термин схож с понятием "пользователь" в классической схеме доступа. Сущность может иметь такое же название, как и логин пользователя, но в отличие от логина, сущность не меняется после выполнения команды su. Если провести аналогию, то сущность - это конкретный человек, Вася Пупкин, Петя Смирнов и т.д.

Домен - это список того, что может делать отдельный процесс.
Фактически домен - это действия, минимально необходимые одному процессу для выполнения его задачи. По аналогии из реальной жизни, доменом можно назвать набор действий для совершения какой-либо операции. Например, при отправке факса это действия:
* поднять трубку;
* набрать номер;
* дождаться характерного свиста;
* нажать кнопку отправки факса;
* положить трубку.

А, например, действие "посвистеть голосом в трубку в ответ на характерный свист" не входит в домен "отправка факса", поэтому это действие является недопустимым.

Роль - это список доменов, которые могут быть использованы.
Если некоего домена нет в списке, то роль не может выполнить действия из этого домена.

В данном случае можно провести аналогию с должностью. То есть роль - это фактически должность (или должностная инструкция), которая может выполнять определённые наборы операций, или, в понятии SELinux, домены.

Например, должность "начальник транспортного цеха" содержит домены:
* Планирование маршрутов и рейсов;
* Учёт расхода ГСМ;
* устное мотивирование подчинённых;
* назначение или лишение премий

Тип - это набор действий (операция) применительно к объекту.
Важно понять отличие от домена. Домен относится к процессам, а тип - к объектам, таким как файлы, каталоги, пайпы(pipes), сокеты и т.д.

Возвращаясь к аналогии с факсом, можно увидеть всё тот же набор действий, но уже применительно к самому факсу:
* Поднять трубку (дождаться гудка в линии)
* Набрать номер (тоновый/импульсный)
* Дождаться характерного свиста (Fax handshake)
* Нажать кнопку отправки факса (Fax send)
* Положить трубку (Hand Up)

Контекст безопасности - это набор всех атрибутов, связанных с объектами и субъектами. Контекст безопасности для субъектов (процессов) состоит из сущности, роли, домена, чувствительности и категории. Обычно используется только сущность-роль-домен(или тип), а целевая политика от Fedora использует только домены и типы.

Переход - это смена контекста безопасности. Есть два основных типа переходов:

* Переход домена процесса - процесс меняет контекст; Например, запускается из-под пользователя некий демон. Selinux, на основе метки исполняемого файла, меняет его контекст.
* Переход типа файла - создание файлов в определённых подкаталогах. Например, пользователь создаёт html-страничку в каталоге WEB-сервера. Чтобы WEB-сервер получил доступ к этой страничке, необходимо сменить контекст безопасности файла (WEB-сервер не имеет доступа к контексту пользователя).
* Политика - это набор правил, контролирующих взаимодействие ролей, доменов, типов и т.д.


Настройки SELinux при использовании основных сервисов.

В качестве примера возьмём такую ситуацию:

1. Все файлы WEB-сервера переносим в каталог /srv/http из каталога /var/www/html
2. Все файлы FTP-сервера переносим в каталог /srv/ftp из каталога /var/ftp/pub
3. Все файлы SAMBA-сервера размещаем в каталоге /srv/samba

Распространённые ошибки при настройке.

Основная ошибка при настройке SELinux - пытаться использовать утилиту "audit2allow". Audit2allow анализирует логи аудит-демона (логи находятся по пути /var/log/audit/audit.log) и на основе протокола ошибок доступа к тем или иным объектам строит модуль для SELinux с разрешающими правилами.

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

Вторая распространённая ошибка - попытаться поменять SELinux-тип файлов и каталогов с помощью утилиты "chcon". Chcon по принципу подобна стандартной утилите "chown" из дискреционной модели доступа.
Эта утилита позволяет установить произвольные SELinux-метки на файлы и каталоги. Но так как при обновлении версии используемой политики происходит переназначение меток на всю файловую систему, то все ваши назначенные метки просто перезапишутся метками по умолчанию.

Настройка SELinux для WEB-сервера

Как уже было отмечено в предыдущем кратком обзоре, мы будем переносить файлы из /var/www/ в /srv/http

Выполняем команду:

# semanage fcontext -l | grep http

Эта команда выведет список правил маркировки файлов и каталогов:

/etc/apache(2)?(/.*)? all files system_u:object_r:httpd_config_t:s0
/etc/apache-ssl(2)?(/.*)? all files system_u:object_r:httpd_config_t:s0
...
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0

Нас интересует последняя строка, потому что мы будем переносить файлы из каталога /var/www. Как видно, правила маркировки представляют собой регулярные выражения, к которым применяется определённый контекст безопасности.

Компания Red Hat использует только мандатный доступ, поэтому всегда будет использоваться такой контекст безопасности:

system_u:object_r:<изменяемая часть>:s0

Выполняем следующую команду:

# semanage fcontext --add --type httpd_sys_content_t '/srv/http(/.*)?'

Эта команда не назначит контекст безопасности на файлы или каталоги -- она даст указание SELinux в будущем маркировать файлы и каталоги по указанному пути указанным SELinux-типом.

Далее выполняем команды:

# mkdir -p /srv/http
# ls -Z /srv
drwxr-xr-x root root unconfined_u:object_r:var_t:s0 http

Как видим, SELinux-тип каталога var_t, а к этому типу у WEB-сервера не будет доступа. Продолжаем настройку:

# restorecon /srv/http
# ls -Z /srv
drwxr-xr-x root root unconfined_u:object_r:httpd_sys_content_t:s0 http

Команда restorecon восстанавливает контекст безопасности на файлы и каталоги в соответствии с сохранёнными ранее правилами маркировки.
Теперь, даже после обновления политик безопасности, контекст безопасности нашего каталога (и его содержимого) не изменится.

Далее можно настраивать WEB-сервер на использование каталога /srv/http, как если бы не было SELinux.

Настройка SELinux для серверов FTP и SAMBA

По аналогии с настройкой WEB-сервера, настраиваются и остальные сервисы. Я не буду сейчас повторяться, потому что процесс настройки идентичен настройке SELinux на использование с WEB-сервером. Приведу команды:

# semanage fcontext --add --type public_content_t '/srv/ftp(/.*)?'
# mkdir -p /srv/ftp
# restorecon /srv/ftp
# semanage fcontext --add --type samba_var_t '/srv/samba(/.*)?'
# mkdir -p /srv/samba
# restorecon /srv/samba
# ls -Z /srv
drwxr-xr-x root root system_u:object_r:public_content_t:s0 ftp
drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 http
drwxr-xr-x root root system_u:object_r:samba_var_t:s0 samba

Создание собственной политики безопасности

Рассмотрим в качестве примера связку "Apache и LDAP". Не будем вникать в тонкости настройки Апача на аутентификацию через LDAP (документации в Интернете предостаточно), представим, что уже настроено, а нам необходимо сейчас заставить работать это под SELinux.

Стандартный порт LDAP-сервера имеет номер 389 и имеет SELinux-тип ldap_port_t. Apache не имеет привилегий для доступа к этому типу, поэтому любые попытки "достучаться" к LDAP'у будут отвергнуты.

Далее можно пойти по простому пути: перевести SELinux в разрешающий режим, запустить Apache , произвести аутентификацию через LDAP и потом утилитой audit2allow получить модуль с разрешающими правилами.

Но давайте рассмотрим ситуацию, когда на одном хосте запущено, например, два LDAP-сервера:
* "публичный", на стандартном порту 389
* "приватный", используемый только в пределах хоста на порту 33389

В таком случае, если будет использована утилита audit2allow, разрешение доступа Апачу к типу ldap_port_t повлечёт за собой разрешение к обоим
портам - как к публичному, так и к приватному LDAP-серверам, что нежелательно.

Выходом будет создание некоего третьего SELinux-типа, к которому будут иметь доступ как Apache, так и LDAP; при этом этим третьим типом будет помечен только один порт.

Создадим в каталоге, например, /root/my_ldap_http файл my_ldap_http и внесем в него следующие строки:

module my_ldap_httpd 1.0.0;
require {
attribute port_type;
type httpd_t;
type slapd_t;
class tcp_socket name_connect;
class tcp_socket name_bind;
class tcp_socket send_msg;
class tcp_socket recv_msg;
};

type my_ldap_httpd_port_t, port_type;
allow slapd_t my_ldap_httpd_port_t:tcp_socket { send_msg recv_msg name_bind };
allow httpd_t my_ldap_httpd_port_t:tcp_socket { send_msg recv_msg name_connect };

Далее выполняем следующие команды:

# make -f /usr/share/selinux/devel/Makefile
# semodule -i ldap_http.pp
# semanage port -d -p tcp 389
# semanage port -a -t my_ldap_httpd_port_t -p tcp 389
# semanage port -l|grep ldap

my_ldap_httpd_port_t tcp 389
ldap_port_t tcp 636, 3268, 33389
ldap_port_t udp 389, 636

Выполнив последнюю команду, можно убедиться, что наш новый SELinux тип был успешно создан в SELinux и назначен на порт 389. В дальнейшем Apache и LDAP смогут взаимодействовать только по 389-му порту, при этом остальные LDAP-порты будут недоступны для WEB-сервера.

Заключение.

В заключение хотелось бы сказать, что SELinux - это не панацея от всех бед и не спасительный круг в плане безопасности. Это всего лишь ещё один инструмент (довольно мощный), который позволяет повысить общий уровень безопасности системы. Но уровень безопасности определяется самым слабым звеном в системе; а если этим звеном является администратор хоста, отключающий SELinux, то и уровень безопасности системы в целом будет именно такой, какой видит её админ -- а именно традиционным пользователь-группа-остальные. И не более.

В данном докладе я осветил основные понятия SELinux и базовые приёмы работы с ним; указал на "подводные камни", которые могут возникнуть
при неправильном применении некоторых утилит. Надеюсь, что мой доклад кому-то покажется полезным и интересным.

Литература:

* SELinux: теория и практика безопасности
* http://www.opennet.ru/base/sec/intro_selinux.txt.html
* http://wiki.linuxformat.ru/index.php/LXF93:SELinux
* http://fedoraproject.org/wiki/Docs/Drafts/SELinux_User_Guide
* http://www.nsa.gov/research/selinux/docs.shtml
* http://www.lurking-grue.org/writingselinuxpolicyHOWTO.html
* yum install selinux-doc selinux-policy-doc

Оригинал: http://www.midnight-commander.org/nopaste/LVEE-2009/doklad.odt

Обновлено: 16.03.2015