Введение в SELinux в CentOS 7: базовые понятия

Security Enhanced Linux, или SELinux – это усовершенствованный механизм контроля доступа, встроенный в большинство современных дистрибутивов Linux. Первоначально он был разработан Агентством национальной безопасности США для защиты компьютерных систем от вторжения злоумышленников и взлома. Со временем SELinux появился в открытом доступе, и тогда различные дистрибутивы включили его в свой код.

Для многих системных администраторов SELinux остается неизведанной территорией. Эта тема и правда может показаться сложной и порой довольно запутанной. Однако правильно настроенная система SELinux может значительно снизить риски взлома, а умение работать с ней поможет устранить сообщения об ошибках, связанных с доступом. В этом мануале мы расскажем о базовых механизмах и понятиях системы SELinux – о ее пакетах, командах и файлах конфигурации, а также о сообщениях об ошибках, которые она регистрирует в случае если доступ запрещен. Мы также приведем несколько практических примеров работы с SELinux.

Примечание: Команды, пакеты и файлы протестированы на сервере CentOS 7. Общие понятия одинаковы для всех дистрибутивов.

В этом мануале команды запускаются от имени пользователя root (если не указано иное). Если у вас нет доступа к учетной записи root и вы используете аккаунт с привилегиями sudo, вам необходимо добавить в начало всех команд ключевое слово sudo.

Зачем нужна система SELinux?

Для начала давайте разберемся с несколькими базовыми понятиями.

SELinux реализует так называемый MAC (Mandatory Access Control). Это разграничение контроля внедряется поверх того, что уже есть в каждом дистрибутиве Linux, DAC (Discretionary Access Control).

Чтобы понять, что такое DAC, давайте сначала рассмотрим, как работает традиционная защита файлов Linux.

В традиционной модели безопасности есть три объекта: пользователь, группа и другие —  User, Group и Other (сокращаются как u, g, o), которые могут иметь комбинацию прав на чтение, запись и выполнение (r, w, x). Если, например, пользователь jo создает файл в своем домашнем каталоге, он будет иметь к нему доступ на чтение/запись, как и группа jo. Другие пользователи, возможно, не будут иметь к нему доступа. В следующем блоке кода мы рассмотрим гипотетическое содержимое домашнего каталога пользователя jo.

Примечание: Не создавайте такого пользователя, это просто условный пример. Позже мы выполним несколько практических задач.

Такая команда:

ls -l /home/jo/

Выведет:

total 4
-rwxrw-r--. 1 jo jo 41 Aug  6 22:45 myscript.sh

Пользователь jo может изменить эти права доступа. Например, jo может предоставить (и ограничить) доступ к этому файлу другим пользователям и группам или изменить владельца файла. Подобные действия могут открыть доступ к важным файлам тем пользователям, которым этот доступ не нужен. Кроме того, jo может ограничить доступ и обезопасить данные, но это делается по усмотрению пользователя: системный администратор не может применить его для каждого файла в системе.

Рассмотрим другой случай: когда процесс Linux запускается, он может запускаться от имени пользователя root или другой учетной записи с привилегиями суперпользователя. Это означает, что если хакер получит контроль над приложением, он сможет использовать его для доступа к любому ресурсу, к которому имеет доступ взломанная учетная запись пользователя. В случае пользователя root это, как правило, все процессы на сервере Linux.

Предположим, вы хотите запретить пользователям запускать сценарии оболочки из их домашних каталогов. Это может произойти, если у вас есть разработчики, работающие в производственной системе. Вы хотите, чтобы они просматривали файлы логов, но не хотите, чтобы они использовали команды su или sudo и запускали какие-либо сценарии из своих домашних каталогов. Как это сделать?

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

Настройка тестового сервера

Чтобы лучше разобраться с общими понятиями, давайте создадим тестовый сервер, на котором будет работать веб-сервер и SFTP. Для работы достаточно иметь базовый свежий сервер CentOS 7 с минимальным набором установленных пакетов. На него мы установим Apache и vsftp, но не будем настраивать ни одно из этих приложений.

Также на облачном сервере мы создадим несколько тестовых учетных записей. Мы будем использовать их для практики на протяжении всего этого мануала.

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

Установка сервисов Apache и SFTP

Войдите на сервер как root и запустите эту команду, чтобы установить Apache:

yum install httpd

В выводе вы увидите, что пакет был загружен, затем система попросит подтвердить установку:

Loaded plugins: fastestmirror, langpacks
...
...
================================================================================
Package       Arch           Version                     Repository       Size
================================================================================
Installing:
httpd         x86_64         2.4.6-18.el7.centos         updates         2.7 M
Transaction Summary
================================================================================
Install  1 Package
Total download size: 2.7 M
Installed size: 9.3 M
Is this ok [y/d/N]:

Нажмите y, чтобы установить веб-сервер Apache.

Downloading packages:
httpd-2.4.6-18.el7.centos.x86_64.rpm                       | 2.7 MB   00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : httpd-2.4.6-18.el7.centos.x86_64                             1/1
Verifying  : httpd-2.4.6-18.el7.centos.x86_64                             1/1
Installed:
httpd.x86_64 0:2.4.6-18.el7.centos
Complete!

Запустите его вручную:

service httpd start

Команда service httpd status  должна показать, что сервис запущен:

Redirecting to /bin/systemctl status  httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
Active: active (running) since Tue 2014-08-19 13:39:48 EST; 1min 40s ago
Main PID: 339 (httpd)
...
...

Теперь установите vsftp:

yum install vsftpd

Вы получите такой вывод:

Loaded plugins: fastestmirror, langpacks
...
...
==============================================================================================================
Package                  Arch                     Version                       Repository              Size
==============================================================================================================
Installing:
vsftpd                   x86_64                   3.0.2-9.el7                   base                   165 k
Transaction Summary
==============================================================================================================
Install  1 Package
Total download size: 165 k
Installed size: 343 k
Is this ok [y/d/N]:

Нажмите y, чтобы установить пакет.

С помощью команды:

service vsftpd start

запустите демон vsftpd. Команда должна вернуть:

Redirecting to /bin/systemctl status  vsftpd.service
vsftpd.service - Vsftpd ftp daemon
Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled)
Active: active (running) since Tue 2014-08-19 13:48:57 EST; 4s ago
Process: 599 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
Main PID: 600 (vsftpd)
...
...

Установка пакетов SELinux

SELinux использует несколько пакетов. Некоторые из них установлены по умолчанию. Вот список пакетов для Red Hat:

  • policycoreutils: предоставляет утилиты для управления SELinux.
  • policycoreutils-python: утилиты для управления SELinux
  • selinux-policy: предоставляет справочную политику SELinux.
  • selinux-policy-targeted: предоставляет целевую политику SELinux.
  • libselinux-utils: некоторые инструменты для управления SELinux.
  • setroubleshoot-server: инструменты для расшифровки сообщений лога аудита.
  • setools: инструменты для мониторинга логов аудита, политики запросов и управления контекстом файлов.
  • setools-console: предоставляет инструменты для мониторинга логов аудита, политики запросов и управления контекстом файлов.
  • mcstrans: инструменты для перевода разных слоев в простой для понимания формат.

Некоторые из них уже установлены. Чтобы узнать, какие именно пакеты SELinux уже есть на вашем сервере CentOS 7, можно запустить такую команду (укажите свой поисковый запрос после grep) как пользователь root.

rpm -qa | grep selinux
libselinux-utils-2.2.2-6.el7.x86_64
libselinux-2.2.2-6.el7.x86_64
selinux-policy-targeted-3.12.1-153.el7.noarch
selinux-policy-3.12.1-153.el7.noarch
libselinux-python-2.2.2-6.el7.x86_64

Вы можете установить все пакеты с помощью приведенной ниже команды (yum просто обновит те пакеты, что у вас уже есть) или же указать только те, которых вам не хватает в системе.

yum install policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans

Теперь в вашей системе есть все необходимые пакеты SELinux, а также серверы Apache и SFTP со стандартными настройками. Кроме того, у нас есть 4 простых пользователя для тестирования (вдобавок к root).

Режимы SELinux

Пришло время начать работу с SELinux. Давайте начнем с режимов SELinux. Система SELinux может работать в любом из трех доступных режимов:

  • Enforcing
  • Permissive
  • Disabled

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

Режим permissive – это такое полуоткрытое состояние: в этом режиме SELinux не применяет свою политику, поэтому не блокирует доступ. Однако любое нарушение политики будет зарегистрировано в логах. Это отличный способ проверить настройку SELinux.

Режим disabled говорит сам за себя – система отключена.

Проверка состояния и режима SELinux

Команда getenforce проверяет текущий режим SELinux.

getenforce

Сейчас система SELinux должна быть отключена, потому команда должна вернуть режим disabled:

Disabled

Также можно использовать команду sestatus:

sestatus

Когда система SELinux отключена, команда возвращает:

SELinux status:        disabled

Конфигурационный файл SELinux

Главный конфигурационный файл SELinux — /etc/selinux/config. Запустите следующую команду, чтобы просмотреть его содержимое:

cat /etc/selinux/config

Команда вернет:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

В этом файле есть две директивы. Директива SELINUX определяет режим SELinux, она может иметь три возможных значения – это режимы, которые мы обсудили ранее.

Директива SELINUXTYPE определяет политику. Значение по умолчанию – targeted. С помощью этой политики SELinux позволяет настраивать доступ. Другое возможное значение – MLS (multilevel security), расширенный режим защиты. Для поддержки политики MLS вам нужно установить дополнительный пакет.

Включение и отключение SELinux

Включить SELinux достаточно просто. Однако, в отличие от отключения, этот процесс выполняется в два шага.

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

Для начала нужно отредактировать файл /etc/selinux/config, чтобы указать в директиве SELINUX режим permissive.

vi /etc/sysconfig/selinux
...
SELINUX=permissive
...

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

Перезагрузите систему:

reboot

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

Войдите на свой сервер как root. Затем выполните поиск строки «SELinux is preventing»в файле /var/log/messages.

cat /var/log/messages | grep "SELinux is preventing"

Если вы не нашли сообщений об ошибках, можете переходить к следующему этапу. Однако хорошо бы также сначала поискать в файле /var/log/messages просто слово «SELinux». Для этого запустим команду:

cat /var/log/messages | grep "SELinux"

Это выведет некоторые сообщения об ошибках, связанных с GNOME Desktop. Они случились, когда SELInux находился в режиме disabled или permissive:

Aug 20 11:31:14 localhost kernel: SELinux:  Initializing.
Aug 20 11:31:16 localhost kernel: SELinux:  Disabled at runtime.
Aug 20 11:31:21 localhost journal: Unable to lookup SELinux process context: Invalid argument
Aug 20 11:33:20 localhost gnome-session: SELinux Troubleshooter: Applet requires SELinux be enabled to run.
Aug 20 11:37:15 localhost kernel: SELinux:  Initializing.
Aug 20 11:37:17 localhost kernel: SELinux:  Disabled at runtime.
Aug 20 11:37:23 localhost journal: Unable to lookup SELinux process context: Invalid argument
Aug 20 11:37:44 localhost gnome-session: SELinux Troubleshooter: Applet requires SELinux be enabled to run.
Aug 20 11:39:42 localhost kernel: SELinux:  Initializing.
Aug 20 11:39:44 localhost kernel: SELinux:  Disabled at runtime.
Aug 20 11:39:50 localhost journal: Unable to lookup SELinux process context: Invalid argument

Подобные ошибки – нормальное дело.

На втором этапе нужно отредактировать конфиг /etc/sysconfig/selinux и перевести SELINUX из режима permissive в enforcing.

...
SELINUX=enforcing
...

Снова перезапустите сервер:

reboot

Как только сервер вернется в рабочее состояние, можно запустить команду sestatus, чтобы проверить состояние SELinux. Теперь команда должна показать более подробную информацию о сервере:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          error (Success)
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

Проверьте файл /var/log/messages:

cat /var/log/messages | grep "SELinux"

В не мне должно быть ошибок. Вывод должен выглядеть примерно так:

Aug 20 11:42:06 localhost kernel: SELinux:  Initializing.
Aug 20 11:42:09 localhost systemd[1]: Successfully loaded SELinux policy in 183.302ms.
Aug 20 11:44:25 localhost kernel: SELinux:  Initializing.
Aug 20 11:44:28 localhost systemd[1]: Successfully loaded SELinux policy in 169.039ms.

Повторная проверка режима и состояния SELinux

Чтобы проверить текущий режим SELinux, используйте команду:

getenforce

Если система работает в режиме enforcing, вывод будет выглядеть так:

Enforcing

Вывод будет другим, если SELinux отключен:

Disabled

Можно также запустить команду sestatus, чтобы получить более подробную картину.

sestatus

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

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

Когда SELinux отключен, вывод будет таким:

SELinux status:        disabled

Также можно временно переключаться между режимами enforcing и permissive – для этого есть команда setenforce.

Примечание: Когда SELinux отключен, запустить setenforce нельзя.

Сначала измените режим SELinux с enforcing на permissive:

setenforce permissive

Теперь команда sestatus показывает, что текущий режим отличается от режима, определенного в файле конфигурации:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28

Вернитесь в режим enforcing:

setenforce enforcing

Политика SELinux

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

Чтобы понять, что такое политика, нужно изучить некоторые основные термины. Позже мы рассмотрим некоторые термины подробнее.

Политика SELinux определяет доступ пользователей к ролям, доступ ролей к доменам и доступ доменов к типам.

Пользователи

У SELinux есть набор предварительно встроенных пользователей. Каждая обычная учетная запись пользователя Linux привязана к одному или нескольким пользователям SELinux.

В Linux пользователь запускает процесс. Вспомните, как пользователь jo, открывает документ в редакторе vi — это значит, что учетная запись jo выполняет процесс vi. В терминологии SELinux процесс (демон или работающая программа) называется субъектом.

Роли

Роль – это шлюз, который находится между пользователем и процессом. Роль определяет, какие пользователи могут получить доступ к тому или иному процессу. Роли не похожи на группы, они больше похожи на фильтры. Определение роли в политике SELinux указывает, какие пользователи имеют доступ к этой конкретной роли. Также это определяет, к каким доменам процессов имеет доступ сама роль. Роли в SELinux используются потому, что SELinux реализует так называемый контроль доступа на основе ролей (RBAC, Role Based Access Control).

Субъекты и объекты

Субъект – это процесс, который может потенциально повлиять на объект.

Объект в SELinux – это все, на что можно воздействовать. Это может быть файл, каталог, порт, TCP-сокет, курсор или, например, X-сервер. Действия, которые субъект может выполнять над объектом, являются привилегиями (правами) субъекта.

Домены субъектов

Домен – это контекст, в котором может работать субъект (процесс) SELinux. Этот контекст похож на оболочку вокруг субъекта. Он говорит процессу, что он может и что не может делать. Например, домен определяет, какие файлы, каталоги, ссылки, устройства или порты доступны субъекту.

Типы объектов

Тип – это контекст файла, который определяет цель файла. Например, контекст файла может указывать, что этот файл является веб-страницей или принадлежит каталогу /etc, или что владельцем файла является конкретный пользователь SELinux. Контекст файла в SELinux называется типом файла.

Политика SELinux

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

Сама политика представляет собой набор правил, которые определяют, какие пользователи могут принимать те или иные роли, а также авторизуют эти роли для доступа только к определенным доменам. Домены, в свою очередь, могут обращаться только к тем или иным типам файлов. Получается такая схема:

Пользователь → Роль → Домен → Файл

Реализация политик SELinux также обычно targeted по умолчанию. Если вы помните конфигурационный файл SELinux, который мы рассмотрели ранее, в нем есть директива SELINUXTYPE со значением targeted. Это означает, что по умолчанию SELinux будет ограничивать только определенные процессы (то есть только определенные процессы являются целевыми). Процессы, которые не являются целевыми, будут работать в доменах без ограничений.

Альтернативой является модель «deny-by-default», в которой любой доступ запрещен, если в политике не указано другое. Это была бы очень безопасная модель. Однако при этом  разработчики должны предвидеть, какое право доступа может потребоваться тому или иному процессу. Поведение SELinux по умолчанию нацелено только на определенные процессы.

Поведение политики SELinux

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

Когда система с поддержкой SELinux запускается, политика загружается в память. Политика SELinux поставляется в модульном формате, во основном как модули ядра, загружаемые во время запуска сервера. И так же, как и модули ядра, они могут динамически добавляться и удаляться из памяти во время выполнения. Хранилище политик, используемое SELinux, отслеживает загруженные модули. Команда sestatus показывает имя хранилища политик. Команда semodule -l выводит список модулей политики SELinux, которые загружены в память в данный момент.

Запустите команду semodule:

semodule -l | less
abrt    1.2.0
accountsd       1.0.6
acct    1.5.1
afs     1.8.2
aiccu   1.0.2
aide    1.6.1
ajaxterm        1.0.0
alsa    1.11.4
amanda  1.14.2
amtu    1.2.3
anaconda        1.6.1
antivirus       1.0.0
apache  2.4.0
...
...

Команда semodule может использоваться для ряда других задач, таких как установка, удаление, перезагрузка, обновление, включение и отключение модулей политики SELinux.

Сейчас вам, вероятно, интересно узнать, где находятся файлы модулей. Большинство современных дистрибутивов включают бинарные версии модулей как часть пакетов SELinux. Файлы политики имеют расширение .pp. В CentOS 7 можно запустить следующую команду:

ls -l /etc/selinux/targeted/modules/active/modules/

Список покажет количество файлов с расширением .pp. Посмотрите внимательно и вы увидите, что они относятся к разным приложениям:

...
-rw-r--r--. 1 root root 10692 Aug 20 11:41 anaconda.pp
-rw-r--r--. 1 root root 11680 Aug 20 11:41 antivirus.pp
-rw-r--r--. 1 root root 24190 Aug 20 11:41 apache.pp
-rw-r--r--. 1 root root 11043 Aug 20 11:41 apcupsd.pp
...

Файлы .pp не предназначены для чтения человеком.

Модульность SELinux работает так, что при загрузке системы модули политики объединяются в так называемую активную политику. Эта политика затем загружается в память. Объединенную двоичную версию этой загруженной политики можно найти в каталоге /etc/selinux/targeted/policy.

ls -l /etc/selinux/targeted/policy/

Эта команда покажет активную политику:

total 3428
-rw-r--r--. 1 root root 3510001 Aug 20 11:41 policy.29

Логические настройки SELinux

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

Чтобы увидеть, как это работает, давайте запустим команду semanage boolean -l.

semanage boolean -l | less

Здесь показаны различные опции, которые можно включить или выключить, их действие и текущие статусы:

ftp_home_dir                   (off  ,  off)  Allow ftp to home dir
smartmon_3ware                 (off  ,  off)  Allow smartmon to 3ware
mpd_enable_homedirs            (off  ,  off)  Allow mpd to enable homedirs
xdm_sysadm_login               (off  ,  off)  Allow xdm to sysadm login
xen_use_nfs                    (off  ,  off)  Allow xen to use nfs
mozilla_read_content           (off  ,  off)  Allow mozilla to read content
ssh_chroot_rw_homedirs         (off  ,  off)  Allow ssh to chroot rw homedirs
mount_anyfile                  (on   ,   on)  Allow mount to anyfile
...
...

Первая опция позволяет демону FTP получать доступ к домашним каталогам пользователей. В данный момент настройка отключена.

Чтобы изменить любую из опций, можно использовать команду setsebool. В качестве примера рассмотрим анонимный доступ на запись по FTP:

getsebool ftpd_anon_write

Вывод показывает нам, что опция в данный момент выключена:

ftpd_anon_write --> off

Далее нужно изменить логическое значение, чтобы включить опцию:

setsebool ftpd_anon_write on

Снова проверьте опцию:

ftpd_anon_write --> on

Логические значения изменяются временно. Они возвращаются к своим старым значениям после перезагрузки. Чтобы сделать значение постоянным, нужно использовать флаг -P с командой setsebool.

Заключение

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

Tags: , ,