SELinux. Максимальный уровень защиты – бесплатно

ЧАСТЬ 1


Пару недель назад в новостях промелькнуло сообщение о том, что Red Hat Enterprise Linux на серверах IBM получил уровень сертификации по безопасности EAL4 Augmented with ALC_FLR.3. Это наивысший уровень сертификации, который когда-либо достигался операционной системой. Кроме RHEL5 эта планка достигнута лишь Trusted Solaris. Такой уровень как правило не нужен при внедрениях в коммерческих организациях, но он открыл дорогу для участия в проектах связанных с правительственными и военными организациями США. До этого другие дистрибутивы Linux уже имели подтвержденный уровень доверия EAL4, но без сертификации Labeled Security Protection Profile (LSPP).

Что важно нам, «простым смертным», - нет необходимости платить никому ни копейки для того, чтобы получить на своей машине столь же высокий уровень защиты, какой требуется в военных ведомствах. Как известно, Enterprise Linux строится на кодовой базе Open Source проекта Fedora (прежнее название Fedora Core). Забавно, что в RHEL5 Server более 300 пакетов даже не пересобирались специально под Enterprise Linux – это видно по тегу fc6 в имени пакета (в RHEL5 тег - el5). Так что в ряде случаев общий не только код, но и сами «бинарники». Fedora же совершенно бесплатно доступна для скачивания. Сравнение Enterprise Linux и Fedora приведено здесь.

Итак, каким же образом обеспечивается соответствие столь высокому критерию безопасности? В немалой степени это стало возможным благодаря SELinux (Security-Enhanced Linux) - реализации системы мандатного контроля доступа (MAC), которая может работать (и работает по умолчанию) параллельно с классической дискреционной системой контроля доступа (DAC).

Оставаясь в рамках DAC, мы имеем фундаментальное ограничение в плане разделения доступа пользователей к ресурсам – доступ к ресурсам основывается на правах доступа пользователя. Это классические права rwx на трех уровнях – владелец, группа-владелец и остальные. Плюс к этому, POSIX ACL, которые лишь расширяют число уровней, на которых можно определить права, но не более.

Таким образом, любое приложение, запущенное с правами usera, теоретически может сделать все что угодно со всеми данными, к которым имеет доступ usera. И не важно, например, что данное приложение – это почтовая программа, которой нужно иметь доступ только к письмам usera. Эта программа будет иметь доступ и, например, к видеофайлам usera, и к картинкам usera. И мало того, что сама программа имеет доступ, но она же может и все эти данные сделать доступными остальным. Все становиться гораздо хуже, когда usera имеет UID=0 (то есть это root). Мы утыкаемся в классическую «проблему суперпользователя». В данном случае мы получаем всего лишь два уровня доступа: root и обыкновенные пользователи. Иными словами, становиться невозможным реализовать доступ с использованием минимально необходимых привилегий.

В MAC же права доступа определяются самой системой при помощи специально определенных политик. Если же говорить конкретно о рассматриваемой реализации – SELinux, то такие политики работают на уровне системных вызовов и применяются самим ядром (но можно реализовать и на уровне приложения). SELinux изначально был разработан АНБ США, а в настоящий момент является Open Source-проектом и входит в стандартное «ванильное» ядро Linux. Коммерческая поддержка доступна уже более двух лет в составе RHEL4.

SELinux действует после классической модели безопасности Unix. Иными словами, через SELinux нельзя разрешить то, что запрещено через права доступа пользователей/групп. Политики описываются при помощи специального гибкого языка описания правил доступа. В большинстве случаев правила SELinux «прозрачны» для приложений, и не требуется никакой их модификации. В состав Fedora/RHEL входят готовые политики, в которых права могут определяться на основе совпадения типов процесса (субъекта) и файла (объекта) – это основной механизм SELinux. Две других формы контроля доступа – доступ на основе ролей и на основе многоуровневой системы безопасности (например, ДСП, секретно, совершенно секретно).

Самый простой для работы и поддержки с точки зрения ИТ службы предприятия тип политики - так называемая «целевая» политика, разработанная в рамках проекта Fedora. Эта политика устанавливается и включается по умолчанию и в RHEL4, и в RHEL5 и является единственной, поддерживаемой Red Hat в составе стандартных контрактов поддержки, политикой. В рамках политики описано более 200 процессов, которые могут выполняться в RHEL5 (в RHEL4 описано намного меньше, в том числе httpd,squid,pegasus,Mailman,Named, dhcpd,mysqld, nscd,ntpd,portmap,postgresql,snmpd,syslogd,winbindd). Все, что не описано «целевой» политикой, выполняется в домене (с типом) unconfined_t. Процессы, работающие в этом домене, не защищаются SELinux. Таким образом, все сторонние пользовательские приложения будут без всяких проблем работать в системе с «целевой» политикой в рамках классических разрешений DAC.

Кроме «целевой» политики, в состав дистрибутива входит политика с многоуровневой моделью безопасности (с поддержкой модели Bell LaPadula). Коммерческая поддержка этой политики доступна в RHEL5 со специальной лицензией и только для серверных систем с ограниченным числом установленных пакетов и без X Window System. Именно системы с данной политикой теперь имеют сертификацию EAL4+/LSPP.

Третий вариант политики - «строгий». Тут действует принцип «что не разрешено, то запрещено». Политика основывается на Reference Policy от компании Tresys.
Данная политика не имеет коммерческой поддержки в RHEL.

Графическая утилита настройки system-config-selinux

Fedora и RHEL, безусловно, не единственные дистрибутивы, поддерживающие SELinux. Достаточно вспомнить Debian и Hardened Gentoo. Но, на мой взгляд, именно в Fedora/RHEL воспользоваться преимуществом мандатного контроля доступа наиболее просто «из коробки». Для удобства управления в состав дистрибутива входят графические утилиты управления и мониторинга от Red Hat и Tresys.

В дальнейших постах блога я предполагаю более подробно коснуться SELinux и привести ссылки на ресурсы в Интернет.

ЧАСТЬ 2.1

Вслед за сообщениями о сертификации Red Hat Enterprise Linux 5 по Common Criteria EAL4+ (c расширениями LSPP, RBACPP и CAPP) на серверах HP и IBM, компания HP объявила о начале предоставления услуги поддержки конфигурации RHEL с включенной многоуровневой системой безопасности (multilevel security -MLS).

Что здесь понимается под MLS? MLS – это еще одна форма принудительного контроля доступа (mandatory access control - MAC), доступная нам при использовании SELinux. Политика с поддержкой MLS является опциональной и для большинства пользователей она будет намного менее полезной, чем принудительный контроль на основе Type Enforcement (TE) – основного механизма, используемого в SELinux. Но MLS – это «пропуск» для операционной системы в государственные и военные организации, где без такого рода разграничения полномочий не обойтись.

Политика MLS базируется на формальной модели Bell-LaPadula. В терминах этой модели все субъекты (для простоты - процессы) и объекты (файлы) имеют свой уровень допуска. Субъект с определенным уровнем допуска имеет право читать и создавать (писать/обновлять) объекты с тем же уровнем допуска. Кроме того, он имеет право читать менее секретные объекты и создавать объекты с более высоким уровнем. Субъект никогда не сможет создавать объекты с уровнем допуска ниже, чем он сам имеет, а также прочесть объект более высокого уровня допуска.

Уффф… Надеюсь, я вас не запутал. По-английски это формулируется намного короче:
«write up, read down» и «no write down, no read up».

Для поддержки MLS традиционный контекст SELinux, состоящий из трех частей: пользователь, роль и тип, был дополнен уровнем допуска. Уровень допуска состоит из диапазонов чувствительности данных (например, «секретно», «ДСП») и категорий данных («отдел кадров», «отдел финансовой отчетности»). Подробно мы поговорим об уровнях доступа, когда речь зайдет о мульти-категорийной безопасности (MCS), которую можно использовать и в «умолчальной» целевой политике.

Переходим к техническим деталям реализации, а вернее – к эксперименту с их использованием. Как опциональная, политика MLS доступна начиная с Fedora Core 5. Именно тогда разработчики перешли с использования оригинальной Example Policy на Reference Policy от Tresys. MLS нельзя установить интерактивно через Anaconda (но можно установить при использовании kickstart-файла). На установленной системе даем команду

yum –y install selinux-policy-mls

Тем самым мы устанавливаем базовый модуль MLS, появившийся в RHEL третьим после «целевой» (targeted) и «строгой» (strict) политики. Собственно, этот третий вариант политики и появился в RHEL для соответствия сертификации EAL4+ LSPP. Данная политика поддерживает принудительный контроль доступа TE, RBAC, и, естественно, модель Bell-LaPadula. Далее нам нужно поправить /etc/sysconfig/selinux, сказав, что теперь используется наша новая политика MLS. Меняем policy=targeted на policy=mls. Теперь, поскольку все файлы на существующей ФС создавались во время работы «целевой» (targeted) политики, нам необходимо обновить SELinux-контексты для всех файлов. Самый простейший/правильный способ – команды

touch /.autorelabel; init 6

Когда появиться меню загрузчика GRUB, нажмите «a», и в конец строки, определяющей параметры загрузки ядра, добавьте enforcing=0. Это (естественно, только на время до перезагрузки) переведет SELinux в «разрешительный» режим, когда правила отрабатываются и файлы создаются с правильным контекстом безопасности, но ограничения, налагаемые политикой SELinux, не применяются. Нам это нужно для того, чтобы ничто не помешало обновить контекст безопасности файлов. Ваша система загрузиться так, если бы SELinux был отключен, и все контексты будут обновлены (если вы не ошиблись при наборе touch /.autorelabel) . Теперь настало время снова перезагрузится, но уже без параметра enforcing=0. Перед перезагрузкой убедитесь, что работает демон sshd. В принципе можно обойтись и без перезагрузки, зайдя в текстовую консоль как пользователь root и отдав команду


setenforce 1

Кстати, выбор политики и необходимость обновления контекста безопасности файлов во время перезагрузки можно произвести из GUI, используя system-config-selinux.

После перезагрузки зайдите на машину по ssh. Дает ли доступ к привилегиям команда su? А sudo? А получится ли перевести SELinux в «разрешительный» режим или вообще выключить? Нет. Попробуйте создать файл из-под учетной записи root, а потом простым пользователем посмотреть его метаданные командой ls. «Вместо строчки – только точки».
Также после перезагрузки вы уже не сможете работать с X Window (как не запустится и ряд других служб). Хотя бы из-за того, что будет существовать возможность скопировать информацию из окна терминала с высоким уровнем допуска в терминал с низким.

Привести свою тестовую (подчеркиваю, тестовую!) систему в исходное состояние вы сможете снова перегрузившись с параметром ядра enforcing=0 и выбрав «целевую» политику.

Написание «строгой» MLS политики весьма сложная и комплексная задача. И от версии к версии политика становиться более гибкой, охватывая большее число служб. Для простого пользователя многоуровневая безопасность – излишество. Для большинства задач достаточно того уровня безопасности, который достигается при использовании включенной по умолчанию «целевой» политики SELinux. Однако, и в рамках «целевой» политики можно использовать реализацию мульти-категорийной безопасности (MCS), о чем мы и поговорим в продолжении этого поста «Часть 2.2. SELinux. MLS и MCS: что с чем едят. MCS». А пока ждем выхода Fedora 8! ;)

ЧАСТЬ 2.2

Итак, если воспользоваться преимуществами многоуровневой системы безопасности (multilevel security - MLS) можно только при использовании «строгой» (strict) политики SELinux, то поддержка мульти-категорийной безопасности (MCS) доступна нам в «целевой» (targeted) политике, используемой по умолчанию. В качестве тестовой машины будем использовать RHEL 5.0, но, по большому счету, это не принципиально. Перечисленные базовые вещи должны одинаково работать на всех последних Fedora/RHEL/CentOS/etc, поставляемых с политикой, собранной из Reference Policy. Выполним команду
[root@dhcppc5 ~]$ seinfo | grep Cat
Sensitivities: 1 Categories: 1024
Мы видим, что нам доступно 1024 категории и один тип чувствительности данных. Что это означает? Вспомним, как выглядел контекст безопасности в FС4 и RHEL4:
user:role:type
Такого контекста безопасности вполне достаточно для организации контроля доступа средствами RBAC и TE. Впрочем, если говорить о работе с целевой политикой, где главный инструмент – TE, пользователь и роль нас особенно не интересует. В MLS политике (а рассматриваемая мульти-категорийная безопасность – это подмножество MLS) контекст расширен и включает два уровня безопасности (security level):

user:role:type: sensitivity[:category,…][- sensitivity[:category,…]]

Первым указывается обязательный текущий уровень (low или current), затем через символ дефиса – наивысший разрешенный уровень (high или clearance). Каждый из двух возможных уровней безопасности включает в себя обязательную часть – чувствительность (sensitivity) данных и ноль или больше категорий (category). Sensitivity в целевой политике всегда будет s0. Чувствительности данных, отличные от 0, зарезервированы для государственных и военных организаций и используются только в политике MLS («секретно», «совершенно секретно» и т.п.). Собственно, то, что нам доступен только один уровень чувствительности и 1024 возможных категорий, мы уже видели в выводе команды seinfo. Кстати, число категорий и чувствительностей данных можно поменять, если вы решите пересобрать политику из исходных кодов. Как и для перекомпиляции ядра, у вас должна быть весомая причина, чтобы этим заниматься. Политика SELinux - модульная, и чаще всего нам приходиться компилировать только отдельные модули. Далее мы не будем касаться работы с sensitivity, а сосредоточимся на категориях.

По умолчанию возможности MCS доступны, но не используются в целевой политике. Все файлы имеют чувствительность s0 и не имеют назначенных категорий. Поэтому если вы в выводе команды ls –Z не видите уровня безопасности, хотя и используете политику с поддержкой MCS, знайте, что он равен s0.

Категории обозначаются как с0, с1,… c1024. Для повседневной работы это не очень удобно. Для того чтобы можно было работать с «говорящими» категориями, в Fedora/RHEL по умолчанию запущен демон mcstransd. Он использует конфигурационный файл /etc/selinux/<имя_политики>/setrans.conf. Наиболее «правильным» способом работы с конфигурационными файлами SELinux является использование утилиты semanage, появившейся в Fedora Core 5.

Из man-страницы semanage(8):


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

Вводим команду, показывающую существующие имена уровней безопасности:

[root@dhcppc5 ~]# semanage translation -l
Level Translation
s0
s0-s0:c0.c1023 SystemLow-SystemHigh
s0:c0.c1023 SystemHigh

Как и ожидалось, напротив уровня безопасности s0 у нас пробелы, что мы собственно и видим при выводе команды ls –Z. При помощи команды semanege с ключевым словом translation и опциями -a, -d и -m можно добавлять, удалять и модифицировать имена категорий. Пока что после каждого изменения необходимо перезапускать демон mcstransd. В отличие от уровней чувствительности данных, категории не представляют собой иерархической структуры. Точка в синтаксисе обозначает диапазон категорий, запятая отделяет диапазоны и отдельные категории.

Теперь посмотрим, к каким категориям разрешен доступ пользователям:

[root@dhcppc5 ~]# semanage login -l

Login Name SELinux User MLS/MCS Range

__default__ user_u s0
root root SystemLow-SystemHigh

Рядовым пользователям по умолчанию разрешен доступ только к s0. Отлично, давайте добавим новую категорию.

[root@dhcppc5 ~]# semanage translation -a -T chaos s0:c20
[root@dhcppc5 ~]# service mcstrans restart

Добавим категорию пользователю. Обратите внимание, что сейчас мы работаем с пользователями Linux (ключевое слово команды login) а не SELinux (ключевое слово user)

[root@dhcppc5 ~]# semanage login -a -r chaos butters

Теперь можно зайти пользователем butters, создать файл в /tmp, и посмотреть, сможет ли пользователь, не имеющий доступ к категории chaos, прочитать этот файл:

[butters@dhcppc5 tmp]$ touch /tmp/butters_file

[cartman@dhcppc5 tmp]$ ls -Z /tmp/butters_file
-rw-rw-r-- butters butters user_u:object_r:tmp_t:chaos /tmp/butters_file
[cartman@dhcppc5 tmp]$ cat /tmp/butters_file
cat: /tmp/butters_file: Permission denied

При этом в /var/log/audit/audit.log мы увидим сообщение:

type=AVC msg=audit(1194279634.604:130): avc: denied { read } for pid=10770 comm="cat" name="butters_file" dev=dm-0 ino=655970 scontext=user_u:system_r:unconfined_t:s0 tcontext=user_u:object_r:tmp_t:s0:c20 tclass=file

Кстати, если воспользоваться утилитой audit2allow:

[root@dhcppc5 ~]# cat /var/log/audit/audit.log | audit2allow -l
allow unconfined_t tmp_t:file read;

мы увидим, что с категориями она работать не умеет, а, значит, от чтения журналов нам все равно не уйти ;) Собственно, это и правильно. audit2allow в первую очередь предназначена для решения проблем с TE.

Можно удалить категорию chaos, чтобы позволить остальным доступ к файлу

[butters@dhcppc5 tmp]$ chcat -- -chaos butters_file

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

При проведении этого маленького эксперимента не пользуйтесь командой su. Заходите с новой консоли или по ssh. Дело в том, что su не меняет текущий SELinux-контекст пользователя:

[cartman@dhcppc5 tmp]$ su -
Password:
[root@dhcppc5 ~]# cat /tmp/butters_file
cat: /tmp/butters_file: Permission denied

Что теперь? А теперь мы используя нашу стандартную целевую политику, которая включена по умолчанию, мы можем запретить системному администратору просмотр не предназначенных для него файлов.

В двух словах идея такова:
1. Создаем специальную категорию и специальных пользователей (сотрудников отдела ИБ).
2. Даем доступ к специальной категории только этим специальным пользователям.
3. Присваиваем semanage эту категорию, а сотрудникам ИБ даем возможность запускать этот файл через sudo.
4. В зависимости от ситуации, также поступаем с chcon и chcat.
5. Закрываем пользователю root возможность зайти в систему. Ограничиваем физический доступ. Оставляем su.
6. Все равно остается ряд проблем :) Строгая и MLS политика в этой ситуации подходит лучше, но и описанный вариант – жизнеспособен.

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

http://markelov.blogspot.com

Обновлено: 16.03.2015