Большинство администраторов Linux знакомы с SELinux в режиме targeted. Стандартная политика ограничивает конкретные сервисы, оставляя остальные процессы относительно свободными. Для типового веб-сервера или почтового шлюза этого достаточно. Но когда на одной машине обрабатываются данные разных уровней конфиденциальности, targeted-политика оказывается слишком грубым инструментом. Именно здесь раскрывается потенциал MLS и MCS - механизмов, которые превращают Linux в систему с полноценной многоуровневой моделью безопасности. И если кому-то кажется, что подобные вещи нужны исключительно военным ведомствам, реальная практика последних лет убедительно говорит об обратном. Финансовые организации, медицинские учреждения, аналитические платформы - всюду, где регуляторы требуют доказуемого разделения информационных потоков, MLS и MCS становятся не роскошью, а необходимостью.
Что скрывается за аббревиатурами MLS и MCS
MLS расшифровывается как Multi-Level Security и опирается на классическую модель Bell-LaPadula, формализованную ещё в 1970-х годах. Суть её элегантно проста: каждому субъекту (пользователю, процессу) и каждому объекту (файлу, сокету, порту) присваивается уровень чувствительности. Правила доступа жёсткие и не допускают исключений. Читать можно только на своём уровне или ниже - принцип "no read up". Писать - только на своём уровне или выше - принцип "no write down". Информация течёт исключительно вверх по иерархии, и это не условность, а математически обоснованный барьер против утечки данных.
MCS - Multi-Category Security - устроена принципиально иначе. Вместо вертикальных уровней здесь горизонтальные категории, между которыми нет отношения "выше-ниже". Категория "финансы" и категория "персонал" существуют параллельно. Процесс с меткой одной категории физически не дотянется до данных другой. Если MLS строит этажи в здании, то MCS возводит непроницаемые стены между комнатами на одном этаже.
Полный контекст безопасности SELinux имеет следующую структуру:
user:role:type:sensitivity[:category]
Targeted-режим оперирует первыми тремя полями. Четвёртое - sensitivity и category - оживает только при активации MLS или MCS. Именно это поле переворачивает всю логику принятия решений о доступе, добавляя к привычному мандатному контролю по типам ещё один независимый слой проверок.
Архитектура уровней и категорий на практике
Уровни чувствительности в SELinux обозначаются как s0, s1, s2 и далее, где s0 - самый низкий. К каждому уровню можно привязать набор категорий от c0 до c1023. Полная метка формируется из пары "уровень-категории" и задаётся как диапазон:
s0-s3:c0.c15
Эта запись означает допуск от уровня s0 до s3 с категориями от c0 до c15 включительно. Диапазон определяет границы, внутри которых субъект может оперировать. Попытка выйти за них блокируется ядром без единого предупреждения - только строчка AVC-отказа в логах аудита.
Переключение на MLS в RHEL-подобных дистрибутивах начинается с установки соответствующей политики:
yum install selinux-policy-mls
sed -i 's/^SELINUXTYPE=targeted/SELINUXTYPE=mls/' /etc/selinux/config
Перед перезагрузкой критически важно выполнить полную перемаркировку файловой системы, иначе система с высокой вероятностью откажется нормально загружаться:
fixfiles -F onboot
reboot
При загрузке ядро пройдёт по всем файлам и назначит контексты в соответствии с MLS-политикой. На крупных файловых системах процесс растягивается на десятки минут, и прерывать его категорически не рекомендуется. Терпение здесь не добродетель, а производственная необходимость.
MCS как облегчённая альтернатива для повседневной изоляции
Полноценный MLS - инструмент мощный, но требовательный к администрированию. Для многих сценариев вполне достаточно MCS, который работает поверх стандартной targeted-политики и не требует смены всей модели безопасности. Контейнерные среды используют MCS повсеместно, даже если администраторы об этом не подозревают.
Каждый контейнер, запущенный через podman, автоматически получает уникальную пару категорий. Один контейнер работает с меткой s0:c123,c456, другой - s0:c789,c12. Ядро SELinux гарантирует, что процессы первого контейнера физически не прочитают файлы второго, даже если злоумышленник получит root внутри контейнерного пространства имён. По сути, MCS добавляет к namespace-изоляции ещё один независимый рубеж, и этот рубеж контролируется ядром, а не пользовательским пространством.
Назначить категории вручную можно двумя командами:
chcat -l +c100,c200 /srv/project-alpha
semanage login -a -s user_u -r s0:c100,c200 analyst_user
Первая команда присваивает директории категории c100 и c200. Вторая связывает пользователя analyst_user с теми же категориями. Результат прямолинеен: analyst_user получает доступ к /srv/project-alpha, а любой пользователь без этих категорий - нет, вне зависимости от стандартных Unix-прав. Chmod 777 здесь бессилен, и это, пожалуй, самое убедительное достоинство MCS.
Для диагностики текущего состояния меток есть три ключевые команды:
id -Z
ls -Z /srv/project-alpha
ps -eZ | grep httpd
Привычка регулярно проверять контексты экономит часы болезненной отладки.
Назначение уровней пользователям и управление переходами
В MLS-политике каждый пользователь SELinux привязывается к диапазону уровней. Пользователь с допуском s0-s2 может работать с данными уровней s0, s1 и s2, но уровень s3 останется для него невидимым. Настройка выполняется через semanage:
semanage user -a -R "staff_r" -r s0-s2:c0.c255 restricted_u
semanage login -a -s restricted_u -r s0-s2:c0.c255 john
При входе в систему пользователь john автоматически получит контекст с указанным диапазоном. Попытка обратиться к файлу с меткой s3 будет немедленно отклонена ядром, а в /var/log/audit/audit.log появится запись AVC-отказа с подробностями.
Управление переходами между уровнями - тема, требующая особого внимания. Процесс на уровне s1 не может создать файл с меткой s0 (no write down). Это защита от утечки информации вниз по иерархии. Но что если легитимный сервис должен передать данные между уровнями? Для этого в SELinux существуют доверенные субъекты - trusted subjects, которым политика явно разрешает нарушать правила Bell-LaPadula в строго контролируемых условиях:
semanage boolean -m --on mls_trusted_process
Каждое такое исключение - потенциальный канал утечки. Его поведение необходимо дополнительно ограничивать правилами type enforcement, иначе весь смысл многоуровневой модели рассыпается. Бездумное добавление доверенных процессов - одна из тех ошибок, которые превращают мощную систему защиты в декорацию.
Типичные ловушки при эксплуатации многоуровневых политик
Тех, кто впервые внедряет MLS, поджидает несколько неочевидных сюрпризов:
- сетевые сервисы (Apache, PostgreSQL, SSH) требуют явной настройки для работы с метками, и часто для каждого уровня приходится поднимать отдельный экземпляр;
- стандартные утилиты tar и rsync по умолчанию не сохраняют расширенные атрибуты SELinux, что делает резервные копии неполноценными;
- отладка AVC-отказов в MLS значительно сложнее, чем в targeted-режиме, поскольку проблема часто кроется в несовпадении уровней, а не типов;
- автоматическое создание разрешений через audit2allow способно пробить дыру в многоуровневой модели, превратив исправление ошибки в уязвимость;
- пользователи, привыкшие к свободному обмену файлами, сталкиваются с отказами доступа даже при корректных Unix-правах, что вызывает волну заявок в техподдержку.
Для корректного бэкапа с сохранением меток необходимо использовать специальные ключи:
tar --selinux -czf backup.tar.gz /srv/classified
rsync -aAXZ /srv/classified/ backup-host:/backups/
Потеря меток при восстановлении - одна из самых распространённых причин нарушения политики после аварийного восстановления. Бэкап без контекстов безопасности, по сути, не является полноценным бэкапом в среде MLS.
Для разбора инцидентов незаменима связка ausearch и audit2why:
ausearch -m AVC -ts recent | audit2why
Вывод audit2why подскажет, какое именно правило было нарушено - несовпадение типа, уровня или категории. Но слепо следовать его рекомендациям нельзя. Каждое разрешение нужно анализировать вручную, понимая, не разрушит ли оно логику разделения уровней.
Когда многоуровневая модель действительно себя оправдывает
Честно говоря, MLS подходит далеко не каждой системе. Накладные расходы на администрирование, жёсткие ограничения на взаимодействие между уровнями, необходимость перестраивать привычные рабочие процессы - всё это серьёзная цена. Разворачивать полноценный MLS на обычном веб-сервере - примерно то же самое, что ставить банковский сейф в садовый домик.
Но есть среды, где эта модель незаменима. Системы обработки персональных данных с регуляторными требованиями к изоляции потоков. Аналитические платформы, где сотрудники разных департаментов работают на одном кластере, но видеть данные друг друга не должны ни при каких обстоятельствах. Серверы разработки, на которых сосуществуют проекты с разным уровнем коммерческой тайны.
MCS при этом закрывает значительную часть потребностей без тяжёлой артиллерии MLS. Контейнерная изоляция, разделение проектов, ограничение доступа между командами - всё это MCS делает элегантно и с минимальными усилиями. Многие организации начинают именно с категорий, наращивая защиту до полноценных уровней только там, где это продиктовано характером данных. Такой поэтапный подход, пожалуй, самый разумный путь к многоуровневой безопасности. Потому что каждый новый рубеж защиты требует пропорционального роста дисциплины, экспертизы и готовности администраторов жить по строгим правилам, которые они же сами и устанавливают.