SELinux: максимальная защита


Денис Колисниченко

Сегодня мы поговорим о SELinux - одной из самых популярных систем управления доступом. Помимо SELinux существуют и другие системы управления доступом, например, GrSecurity и LIDS, но самой строгой из них является именно SELinux. При правильной настройке эта система еще ни разу не была взломана. Сразу предупреждаю: не нужно считать данную статью полным руководством по SELinux. Считай ее небольшим обзором, ознакомительной статьей, так как объем публикации не позволяет полностью описать SELinux, но зато мы остановимся на основных понятиях и концепциях этой системы. Большая часть статьи будет уделена практической настройке, а если ты что-то недопонял из теории, в конце статьи ты найдешь список дополнительных ресурсов.

[зачем это надо?]

Linux при правильной настройке считается одной из самых защищенных операционных систем мира. Так зачем нужна дополнительная система управления доступом? Неужели не хватает возможностей самой Linux? Да, не хватает. В Linux есть две крайности - два типа пользователей - обычный пользователь и администратор (root). Права обычных пользователей можно ограничить и с помощью штатных средств Linux. Но что может делать администратор - ты и сам все знаешь. Если злоумышленник завладеет паролем администратора (как он это сделает - это уже другой вопрос), то он получит полную власть над системой. Но если на компьютере установлена система управления доступом, то она не позволит ему ничего сделать. Точнее, может злоумышленник что-то и сделает, но только те операции, которые не причинят системе ощутимого вреда. То есть система управления доступом может ограничить даже действия самого пользователя root, если такие действия могут стать причиной некорректной работы системы (например, угрожать целостности данных, работе самой системы и т.д.).

Вернемся к обычным пользователям. Здесь можно задавать ограничение на доступ к определенным файлам и на использование системных ресурсов - дискового пространства (квоты), процессорного времени, устанавливать максимальное число процессов. И все. Система управления доступом может запретить пользователю выполнять те действия, которые он не должен выполнять. Во многих случаях, даже обычным пользователям часто предоставляются чрезмерные полномочия. Например, зачем пользователю, который зарегистрировался в системе только для чтения почты, возможность компиляции исходного кода или запуска фоновых демонов? Теперь все становится на свои места - мы понимаем, что без SELinux в многопользовательской системе не обойтись. Справедливости ради нужно отметить, что описанные выше фичи также можно организовать, используя GrSecurity или LIDS.

Кроме всего прочего, SELinux контролирует и права доступа к файлам. Например, система проверила права доступа файла и разрешила доступ к файлу. Но потом принимается за работу SELinux. Если в настройках SELinux указано, что данный пользователь (или процесс) не имеет доступа к файлу, тогда SELinux запрещает доступ к файлу. И в самом деле, зачем Web-серверу доступ к каталогу /etc/selinux? Если же система запретила доступ к файлу (это первый этап - проверка прав доступа), тогда SELinux не задействуется.

[как устанавливать SELinux?]

Давай упростим друг другу жизнь и не будем рассматривать установку этой системы на "голый" Linux. SELinux входит в состав Fedora Core (кстати, FC стал первым дистрибутивом, в состав которого была включена SELinux) и дистрибутивов, основанных на нем. Настройку SELinux будем рассматривать на примере ASP Linux 11 - самого свежего SELinux-дистрибутива, который имеется под рукой.

Перейди в каталог /etc/selinux. Здесь ты найдешь файл config, управляющий настройками самой SELinux, а также каталог targeted, в котором будут находиться конфигурационные файлы политики targeted. В нем будут три подкаталога - contexts, policy, users (контексты, политика, пользователи), а также файл booleans, в котором установлены некоторые булевые (логические) параметры. Вообще этот файл руками трогать не нужно - посмотрели и забыли. Во всяком случае, на данном этапе. Итак, что же в каталогах contexts, policy и users? Чтобы получить ответ на этот вопрос, нужно обратиться к скучной теории.

[скучная теория]

Начнем с базового понятия - понятия сущности. Сущность (identity) формирует часть контекста безопасности, задающего домены, в которые можно войти. То есть сущность определяет, что можно сделать. Не нужно путать сущность с идентификатором пользователя (UID). Они параллельно существуют в системе, но их смысл абсолютно разный. Обычно сущность представляется в системе так же, как и имя пользователя. Если в системе есть пользователь den и есть сущность den, выполнение команды su не изменяет сущность SELinux. Предположим, у нас есть пользователь den. Зарегистрируемся под ним и выполним команду id (это команда SELinux), получим такой вывод:

context=den:user_r:user_t

Теперь введем команду su, наберем пароль root и снова введем команду id:

context=den:user_r:user_t

Мы получили тот же самый вывод. Как видишь, контекст остался прежним и не изменился на контекст пользователя root. Правда, есть одно но. Если сущности den разрешен доступ к роли sysadm_r (сейчас роль user_r) и пользователь выполнить команду "newrole -r sysadm_r" (изменит свою роль), а потом снова выполнит id, то получит вывод:

context=den:sysadm_r:sysadm_t

Сущность осталось такой же, но роль и домен (второе и третье поле) изменились. Сущность определяет, какие роли и домены могут быть использованы. Домен (domain) однозначно определяет привилегии процесса. Другими словами, домен представляет собой список того, что может сделать процесс, или, точнее, какие операции может выполнить процесс над разными типами. Примеры доменов: sysadm_t - домен администратора системы, user_t - домен для непривилегированных пользователей. Процесс init выполняется в домене init_t, а named - в named_t.

Тип (type) задается для объекта и определяет доступ к этому объекту. Практически, тип - это тоже самое, что и домен, но если домен относится к процессам, то тип - к файлам, каталогам, сокетам и т.п.

Роль (role) определяет список доменов, которые могут быть использованы. Домены, разрешенные для пользовательской роли, определяются в файлах политики. Если роль не имеет доступа к домену, то при попытке выполнения действия с доменом, доступ будет запрещен. Лучше всего это продемонстрировать на примере: если тебе нужно разрешить непривилегированным пользователям (домен user_t) выполнять команду passwd, в конфигурационном файле нужно прописать:

role user_r types user_passwd_t

Из команды видно, что пользователь с ролью user_r может входить в домен user_passwd_t, т.е. может выполнять команду passwd.

Контекст безопасности (security context) - это набор всех атрибутов, которые связаны с файлами, каталогами, процессами, TCP-сокетами. Контекст безопасности состоит из сущности, роли, домена (или типа вместо домена). Команда id выводит текущий контекст безопасности.

Решение о переходе (transition) определяется контекстом безопасности, который будет назначен выполняемой операцией. Существует два вида переходов:
переход домена процесс - используется при выполнении процесса определенного типа
переход типа файла - используется при создании файла в определенных каталогах

Наконец, рассмотрим последнее понятие - понятие политики. Политика - это набор правил, контролирующих списки ролей, к которым у пользователя есть доступ, доступ ролей к доменам, доступ доменов к типам. Ты точно разобрался с доменами/типами/ролями? Смотри, например, выражение "доступ ролей к доменам" - это означает, какие пользователи имеют право запускать те или иные процессы. А выражение "доступ доменов к типу" - какие процессы имеют право доступа к тем или иным объектам (файлам, каталогам, сокетам). Редактируя файлы политик, ты можешь настроить свою систему так, как пожелаешь.

[да будет SELinux!]

Зарегистрируйся в системе как пользователь root и введи команду:

# system-config-securitylevel

В окне "Настройка уровня безопасности" перейди на закладку "Настройка SELinux". По умолчанию SELinux обычно выключена. Для ее включения установи флажок "Включено".

Сразу после включения этого флажка ты увидишь предупреждение о необходимости перемаркировать файловую систему правильными контекстами безопасности. Перемаркировка будет выполнена после перезагрузки системы. В этом же окне сообщается, что перемаркировка (аналог команды "make relabel") может занять довольно много времени (зависит от размера файловой системы).

После этого обрати внимание на окно "Настройка SELinux". В нем можно выбрать тип политики SELinux. Пока доступна только одна политика - targeted (целевая).

Теперь нажми кнопку "OK" и перезагрузи компьютер командой "reboot". В процессе старта системы появится сообщение:

Warning -- SELinux relabel is required ***

Что свидетельствует о том, что SELinux будет перемаркировывать файловую систему. После этого пойдет загрузка - все как обычно. При входе в X Window на первую консоль будет выведено несколько не совсем обычных сообщений. Их формат мы разберем чуть позже. Первое, что хочется сделать - это ввести команду id, чтобы просмотреть свой контекст безопасности:

context=root:system_r:hotplug_t

Роль system_r - это роль системы, которая выше роли sysadm_r.

Теперь самое время обратиться к конфигурационным файлам SELinux. Открой файл /etc/selinux/config. В этом файле будут всего две директивы: SELINUX и SELINUXTYPE. Первая может принимать следующие значения:
enforcing - применить политику безопасности SELinux
permissive - режим отладки - вместо запрета тех или иных операций SELinux будет просто выводить предупреждения
disabled - SELinux отключена

Для второй директивы возможно два значения:
targeted - будут защищены только целевые сетевые демоны (которые будут явно указаны)
strict - полная защита

Если тебе нужна полная защита, установи пакет selinux-policy-strict. Данный пакет находится на первом CD ASPLinux 11. Со второго компакта я бы посоветовал установить пакет selinux-doc. Дополнительная документация никогда не помешает.

Для аудита политик SELinux используется программа seaudit, но при запуске мы получаем сообщение, что не установлена политика по умолчанию. Самое интересное, что на дистрибутивных дисках я так и не нашел пакет policy, содержащий политику по умолчанию. Пришлось его взять из интернета: ftp://rpmfind.net/linux/ASPLinux/i386/RPMS.10/policy-1.11.3-3.noarch.rpm.

[выбор роли]

Роль имеет большое значение - у каждой роли свои полномочия, например, у роли sysadm_r полномочий намного больше, чем у user_r. Поэтому нужно знать, как можно изменить роль. Вообще-то в цели targeted, в который мы сейчас работаем, роли пользователей особого интереса не представляют, поскольку осуществляется защита только выбранных сетевых демонов, но о команде newrole сказать все-таки нужно. Ее синтаксис следующий:

newrole -r роль

Например:

newrole -r sysadm_r

После этого нужно будет ввести пароль для сущности (пароль пользователя). Если нет прав доступа к указанной роли, ты увидишь сообщение:

den:sysadm_r:sysadm_t is not a valid context

В этом случае указывается, что сущность den не имеет права доступа к роли sysadm_r.

[псевдо-файловая система /selinux]

При запуске системы с поддержкой SELinux в корне появится каталог /selinux - это псевдо-файловая система SELinux (наподобие /proc). С помощью этой ФС можно изменять некоторые параметры, например, режим работы SELinux. Как уже было отмечено, есть два режима работы - разрешающий (permissive) и принудительный (enforcing). В первой режиме SELinux только ругается, и ОС работает так же, как и обычная Linux-система без SELinux, а во втором применяются все настроенные политики. Отладочные сообщения в разрешающем режиме протоколируются в файл /var/log/messages. Для переключения в принудительный режим используется команда:

echo "1" > /etc/selinux/enforce

Для перехода в разрешающий режим используется команда:

echo "0" > /etc/selinux/enforce

[разборки с пользователями]

Лучше добавить всех необходимых пользователей в систему до включения SELinux, но бывают случаи, когда сделать это просто невозможно (система работает продолжительное время, и все пользователи заведены). Если SELinux уже активна, то для добавления нового пользователя нужно выполнить следующие команды:

Становимся администратором:

$ su

Входим в роль sysadm_r:

# newrole -r sysadm_r

Добавляем нового пользователя:

# useradd -c "New user" -m -d /home/newuser -g users -s /bin/bash -u 1005 newuser

# passwd newuser

Но этого мало. Нужно еще настроить роли пользователя. Для этого в файл /etc/selinux/users добавляем строку:

user newuser roles { user_r };

Этим мы назначаем пользователю newuser роль user_r. Если тебе нужно, чтобы пользователь имел доступ к нескольким ролям, тогда укажи несколько ролей через пробел, например:

user setest roles { user_r sysadm_r };

Для активации изменений введи команду:

# make -C /etc/selinux load

Активация изменений займет некоторое время, по окончанию этой операции ты увидишь такие сообщения:

Success
touch tmp/load
make: Leaving directory `/usr/share/selinux/policy/current'

Нужно отметить, что если пользователю нужен доступ только к роли user_r, это можно явно не указывать. Явно указывать нужно лишь в том случае, когда пользователю требуется изменить свой пароль самостоятельно.

[system-config-securitylevel]

Теперь начинается самое интересное. Мы будем редактировать нашу политику. Сейчас у нас используется политика targeted, подразумевающая защиту только указанных тобою сетевых демонов. Запусти конфигуратор system-config-securitylevel. На закладке SELinux появится возможность (после активации SELinux) редактирования политики. Там все просто: приводится список служб и для каждой службы набор опций SELinux. Например, вот список опций для FTP:
Выключить защиту SELinux для демона ftpd
Выключить защиту SELinux для демона initd
Разрешить ftp читать/записывать файлы в домашних каталогах

А вот список привилегий пользователя:
Позволить пользователям читать любые файлы по умолчанию
Разрешить пользователям запускать pppd соединения

[читаем сообщения SELinux]

Рассмотрим пример типичного ругательства SELinux, которое можно обнаружить в /var/log/messages:

May 21 14:44:12 localhost kernel: audit(1148208252.610:29): avc: denied { read } for pid=2054 comm="bash" name=".bash_profile" dev=hda6 ino=23695 scontext=root:system_r:hotplug_t tcontext=root:object_r:user_home_t tclass=file

Строка "avc: denied" означает, что операция была запрещена. Далее следует идентификатор процесса, пытающегося выполнить операцию (for pid), имя процесса (comm), имя объекта (name), имя устройства (dev), номер инода объекта (ino), контекст безопасности процесса (scontext), контекст безопасности объекта (tcontext) - в данном случае это файл ".bash_profile" и тип целевого объекта (tclass=file - тип объекта - файл).

http://www.dkws.org.ua/index.php?page=show&file=a/hacker/selinux

Обновлено: 16.03.2015