Введение в SELinux на CentOS 7 - Часть 3: Пользователи

Вступление

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

_ * Примечание * + Команды, пакеты и файлы, показанные в этом руководстве, были протестированы на CentOS 7. Концепции остаются такими же для других распределений. _

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

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

Пользователи SELinux отличаются от обычных учетных записей пользователей Linux, включая учетную запись root. Пользователь SELinux не является чем-то, что вы создаете с помощью специальной команды, и при этом он не имеет собственного доступа для входа на сервер. Вместо этого пользователи SELinux определяются в политике, которая загружается в память во время загрузки, и таких пользователей всего несколько. Имена пользователей заканчиваются на + _u +, так же как имена типов или доменов заканчиваются на + _t +, а роли заканчиваются на + _r +. Разные пользователи SELinux имеют разные права в системе, и это делает их полезными.

Пользователь SELinux, указанный в первой части контекста безопасности файла, является пользователем, которому принадлежит этот файл. Это похоже на то, как вы видите владельца файла из обычной команды + ls -l +. Метка пользователя в контексте процесса показывает привилегию пользователя SELinux, с которой работает процесс.

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

Чтобы просмотреть это отображение, мы можем запустить команду + semanage login -l +:

semanage login -l

В CentOS 7 это то, что мы можем видеть:

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

Первый столбец в этой таблице, «Имя для входа», представляет локальные учетные записи пользователей Linux. Но здесь есть только три, вы можете спросить, разве мы не создали несколько аккаунтов во второй части этого урока? Да, и они представлены записью, показанной как по умолчанию . Любая обычная учетная запись пользователя Linux сначала сопоставляется с логином по умолчанию . Затем это сопоставляется с пользователем SELinux с именем undefined_u. В нашем случае это второй столбец первого ряда. В третьем столбце показан класс многоуровневой защиты / безопасности нескольких категорий (MLS / MCS) для пользователя. А пока давайте проигнорируем эту часть, а также столбец после этого (Сервис).

Далее у нас есть пользователь * root . Обратите внимание, что он не привязан к логину « default *», скорее ему была дана собственная запись. Еще раз, root также отображается на пользователя SELinux.

system_u - это другой класс пользователей, предназначенный для запуска процессов или демонов.

Чтобы увидеть, какие пользователи SELinux доступны в системе, мы можем запустить команду + semanage user +:

semanage user -l

Вывод в нашей системе CentOS 7 должен выглядеть следующим образом:

                Labeling   MLS/       MLS/
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles

guest_u         user       s0         s0                             guest_r
root            user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
staff_u         user       s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r unconfined_r
sysadm_u        user       s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r unconfined_r
unconfined_u    user       s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r
xguest_u        user       s0         s0                             xguest_r

Что означает этот большой стол? Прежде всего, он показывает разных пользователей SELinux, определенных политикой. Раньше мы видели таких пользователей, как undefined_u и system_u, но теперь мы видим других пользователей, таких как guest_u, staff_u, sysadm_u, user_u и так далее. Названия несколько указывают на права, связанные с ними. Например, мы можем предположить, что пользователь sysadm_u будет иметь больше прав доступа, чем guest_u.

Чтобы проверить нашего гостя, давайте посмотрим на пятую колонку, SELinux Roles. Если вы помните из первой части этого руководства, роли SELinux похожи на шлюзы между пользователем и процессом. Мы также сравнили их с фильтрами: пользователь может обозначить роль, если она предоставлена ​​ролью. Если роли разрешен доступ к домену процесса, пользователи, связанные с этой ролью, смогут войти в этот домен процесса.

Теперь из этой таблицы видно, что пользователь + undefined_u + сопоставлен с ролями + system_r + и +conconcted_r +. Хотя здесь и не очевидно, политика SELinux фактически позволяет этим ролям запускать процессы в домене + undefined_t +. Аналогично, пользователь + sysadm_u + авторизован для роли sysadmr, но guestu сопоставлен с ролью guest_r. Каждая из этих ролей будет иметь для них разные домены.

Теперь, если мы сделаем шаг назад, мы также увидели из первого фрагмента кода, что имя входа по умолчанию сопоставляется с пользователем undefined_u, точно так же, как пользователь root сопоставляется с пользователем undefined_u. Так как логин по умолчанию _ представляет любую обычную учетную запись пользователя Linux, эти учетные записи также будут авторизованы для ролей system_r и undefined_r.

Так что на самом деле это означает, что любой пользователь Linux, который отображается на пользователя undefined_u, будет иметь права на запуск любого приложения, которое работает в домене undefined_t.

Чтобы продемонстрировать это, давайте запустим команду + id -Z + от имени пользователя root:

id -Z

Здесь показан контекст безопасности SELinux для * root *:

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Таким образом, корневая учетная запись сопоставлена ​​с пользователем SELinux неограниченное_u, а для безусловного_u авторизована роль не определенная_r, которая, в свою очередь, разрешено запускать процессы в домене неограниченное_т.

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

  • regularuser

  • switcheduser

  • гостевой пользователь

  • ограниченный пользователь

Далее мы переключаемся на сеанс терминала, зарегистрированный как обычный пользователь. Если вы помните, мы создали несколько учетных записей в https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-2-files-and-processes [второй урок], и обычный пользователь был одним из них. Если вы этого еще не сделали, откройте отдельное окно терминала для подключения к вашей системе CentOS 7 с правами обычного пользователя. Если мы выполним ту же команду + id -Z + оттуда, результат будет выглядеть следующим образом:

[regularuser@localhost ~]$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

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

Мы уже видели список пользователей SELinux:

  • * guest_u *: Этот пользователь не имеет доступа к системе X-Window (GUI) или сети и не может выполнить команду su / sudo.

  • * xguest_u *: У этого пользователя есть доступ к инструментам графического интерфейса, и сеть доступна через браузер Firefox.

  • * user_u *: Этот пользователь имеет больше доступа, чем гостевые учетные записи (графический интерфейс и сеть), но он не может переключать пользователей с помощью su или sudo.

  • * staff_u *: те же права, что и у user_u, за исключением того, что он может выполнять команду sudo для получения привилегий root.

  • * system_u *: Этот пользователь предназначен для запуска системных служб, а не для привязки к обычным учетным записям пользователей.

SELinux в действии 1: ограничение коммутируемого доступа пользователей

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

Давайте сначала проверим способность пользователя переключаться на другую учетную запись. В следующем фрагменте кода обычный пользователь переключается на учетную запись переключателя. Мы предполагаем, что он знает пароль для switcheduser:

[regularuser@localhost ~]$ su - switcheduser
Password:
[switcheduser@localhost ~]$

Затем мы возвращаемся к окну терминала, зарегистрированному как пользователь * root *, и меняем отображение пользователя SELinux для обычного пользователя. Мы будем сопоставлять регулярного пользователя user_u.

semanage login -a -s user_u regularuser

Так что мы здесь делаем? Мы добавляем (-a) учетную запись постоянного пользователя в учетную запись SELinux (-s) user_u. Изменения не вступят в силу, пока пользователь с правами обычного пользователя выйдет из системы и снова войдет в систему.

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

[switcheduser@localhost ~]$ logout

Затем обычный пользователь также выходит из системы:

[regularuser@localhost ~]$ logout

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

[regularuser@localhost ~]$ su - switcheduser
Password:

Вот что мы видим сейчас:

su: Authentication failure

Если теперь мы снова запустим команду + id -Z +, чтобы увидеть контекст SELinux для регуляра обычного пользователя, мы увидим, что вывод совершенно отличается от того, что мы видели ранее: регуляризация теперь сопоставлена ​​с user_u.

[regularuser@localhost ~]$ id -Z
user_u:user_r:user_t:s0

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

SELinux в действии 2. Ограничение разрешений для запуска сценариев

Давайте посмотрим еще один пример ограничения доступа пользователей через SELinux. Запустите эти команды из сеанса * root *.

По умолчанию SELinux позволяет пользователям, сопоставленным с учетной записью guest_t, выполнять сценарии из своих домашних каталогов. Мы можем запустить команду + getsebool +, чтобы проверить логическое значение:

getsebool allow_guest_exec_content

Выходные данные показывают, что флаг включен.

guest_exec_content --> on

Чтобы проверить его действие, давайте сначала изменим сопоставление пользователей SELinux для учетной записи guestuser, которую мы создали в начале этого учебника. Мы сделаем это как пользователь root.

semanage login -a -s guest_u guestuser

Мы можем проверить действие, снова выполнив команду + semanage login -l +:

semanage login -l

Как мы видим, guestuser теперь сопоставлен с учетной записью SELinux guest_u гостя.

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
guestuser            guest_u              s0                   *
regularuser          user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *
system_u             system_u             s0-s0:c0.c1023       *

Если у нас есть окно терминала, открытое как guestuser, мы выйдем из него и снова войдем в новое окно терминала как guestuser.

Далее мы создадим чрезвычайно простой скрипт bash в домашнем каталоге пользователя. Следующий блок кода сначала проверяет домашний каталог, затем создает файл и читает его в консоли. Наконец, разрешение на выполнение изменено.

Убедитесь, что вы находитесь в домашнем каталоге + guestuser +:

[guestuser@localhost ~]$ pwd
/home/guestuser

Создайте скрипт:

[guestuser@localhost ~]$ vi myscript.sh

Содержание скрипта:

#!/bin/bash
echo "This is a test script"

Сделайте скрипт исполняемым:

chmod u+x myscript.sh

Когда мы пытаемся выполнить скрипт как guestuser, он работает как положено:

[guestuser@localhost ~]$ ~/myscript.sh
This is a test script

Затем мы возвращаемся к окну корневого терминала и меняем логическое значение allow_guest_exec_content на + off + и проверяем его:

setsebool allow_guest_exec_content off
getsebool allow_guest_exec_content
guest\_exec\_content --> off

Возвращаясь к консоли, вошедшей в систему как guestuser, мы пытаемся снова запустить скрипт. На этот раз доступ запрещен:

[guestuser@localhost ~]$ ~/myscript.sh
-bash: /home/guestuser/myscript.sh: Permission denied

Вот так SELinux может применить дополнительный уровень безопасности поверх ЦАП. Даже если у пользователя есть полный доступ для чтения, записи и выполнения к сценарию, созданному в его собственном домашнем каталоге, он все равно может быть остановлен от его выполнения. Где вам это нужно? Ну, подумай о производственной системе. Вы знаете, что разработчики имеют доступ к нему, как и некоторые из подрядчиков, работающих в вашей компании. Вы хотели бы, чтобы они обращались к серверу для просмотра сообщений об ошибках и файлов журналов, но вы не хотите, чтобы они выполняли какие-либо сценарии оболочки. Для этого вы можете сначала включить SELinux, а затем убедиться, что установлено соответствующее логическое значение.

Мы вскоре поговорим о сообщениях об ошибках SELinux, но сейчас, если мы хотим увидеть, где было зарегистрировано это отрицание, мы можем посмотреть файл + / var / log / messages +. Выполните это из корневого сеанса:

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

Последние два сообщения в файле на нашем сервере CentOS 7 показывают отказ в доступе:

Aug 23 12:59:42 localhost setroubleshoot: SELinux is preventing /usr/bin/bash from execute access on the file . For complete SELinux messages. run sealert -l 8343a9d2-ca9d-49db-9281-3bb03a76b71a
Aug 23 12:59:42 localhost python: SELinux is preventing /usr/bin/bash from execute access on the file .

В сообщении также показано длинное значение идентификатора и предлагается выполнить команду + sealert + с этим идентификатором для получения дополнительной информации. Следующая команда показывает это (используйте свой собственный идентификатор оповещения):

sealert -l

И действительно, вывод показывает нам более подробно об ошибке:

SELinux is preventing /usr/bin/bash from execute access on the file .

*****  Plugin catchall_boolean (89.3 confidence) suggests   ******************

If you want to allow guest to exec content
Then you must tell SELinux about this by enabling the 'guest\_exec\_content' boolean.
You can read 'None' man page for more details.
Do
setsebool -P guest\_exec\_content 1

*****  Plugin catchall (11.6 confidence) suggests   **************************

...

Это большой объем вывода, но обратите внимание на несколько строк в начале:

  • SELinux запрещает / usr / bin / bash выполнять доступ к файлу. *

Это дает нам довольно хорошее представление о том, откуда исходит ошибка.

Следующие несколько строк также расскажут вам, как исправить ошибку:

If you want to allow guest to exec content
Then you must tell SELinux about this by enabling the 'guest\_exec\_content' boolean.
...
setsebool -P guest\_exec\_content 1

SELinux в действии 3: ограничение доступа к сервисам

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

Давайте сначала удостоверимся, что демон httpd не работает в системе. Как пользователь root, вы можете запустить следующую команду, чтобы убедиться, что процесс остановлен:

service httpd stop

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

[restricteduser@localhost ~]$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Таким образом, учетная запись по умолчанию работает как пользователь undefined_u и имеет доступ к роли undefined_r. Однако эта учетная запись не имеет права запускать какие-либо процессы в системе. Следующий блок кода показывает, чтоограниченный пользователь пытается запустить демон httpd и получает ошибку «Отказано в доступе»:

[restricteduser@localhost ~]$ service httpd start
Redirecting to /bin/systemctl start  httpd.service
Failed to issue method call: Access denied

Затем мы вернемся к окну корневого пользовательского терминала и убедимся, что в файл / etc / sudoers добавлена ​​ограниченная учетная запись пользователя. Это действие позволит учетной записи с ограниченными правами использовать привилегии root.

visudo

А затем в файле добавьте следующую строку, сохраните и выйдите:

restricteduser ALL=(ALL)      ALL

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

[restricteduser@localhost ~]$ sudo service httpd start
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

   #1) Respect the privacy of others.
   #2) Think before you type.
   #3) With great power comes great responsibility.

[sudo] password for restricteduser:
Redirecting to /bin/systemctl start  httpd.service

Пользователь также может остановить службу сейчас:

[restricteduser@localhost ~]$ sudo service httpd stop
Redirecting to /bin/systemctl stop  httpd.service

Это все очень нормально: системные администраторы предоставляют sudo доступ к учетным записям пользователей, которым они доверяют. Но что, если вы хотите запретить данному конкретному пользователю запускать службу httpd, даже если учетная запись пользователя указана в файле sudoers?

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

semanage login -a -s user_u restricteduser

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

Теперь, когда ограниченный пользователь ограничен user_u (что означает роль user_r и домен user_t), мы можем проверить его доступ с помощью команды + seinfo + из окна нашего пользователя root:

seinfo -uuser_u -x

Выходные данные показывают роли, которые может принять user_u. Это object_r и user_r:

  user_u
     default level: s0
     range: s0
     roles:
        object_r
        user_r

Сделав еще один шаг вперед, мы можем запустить команду + seinfo +, чтобы проверить, в какие домены авторизована роль user_r:

seinfo -ruser_r -x

Существует несколько доменов, в которые user_r имеет право войти:

  user_r
     Dominated Roles:
        user_r
     Types:
        git_session_t
        sandbox_x_client_t
        git_user_content_t
        virt_content_t
        policykit_grant_t
        httpd_user_htaccess_t
        telepathy_mission_control_home_t
        qmail_inject_t
        gnome_home_t
        ...
        ...

Но показывает ли этот список httpd_t как один из доменов? Давайте попробуем ту же команду с фильтром:

seinfo -ruser_r -x | grep httpd

Существует несколько доменов, связанных с httpd, к которым у этой роли есть доступ, но httpd_t не является одним из них:

        httpd_user_htaccess_t
        httpd_user_script_exec_t
        httpd_user_ra_content_t
        httpd_user_rw_content_t
        httpd_user_script_t
        httpd_user_content_t

Если взять этот пример, то, если учетная запись с ограниченными правами пытается запустить демон httpd, доступ должен быть запрещен, поскольку процесс httpd выполняется в домене httpd_t, а это не один из доменов, доступ к которым имеет роль user_r. И мы знаем, что user_u (сопоставленный с ограниченным пользователем) может взять на себя роль user_r. Это должно завершиться неудачей, даже если учетной записи с ограниченными правами была предоставлена ​​привилегия sudo.

Возвращаясь к окну терминала с ограниченными учетными записями пользователей, мы пытаемся запустить демон httpd (раньше мы могли его остановить, поскольку учетной записи была предоставлена ​​привилегия sudo):

[restricteduser@localhost ~]$ sudo service httpd start

Доступ запрещен:

sudo: PERM_SUDOERS: setresuid(-1, 1, -1): Operation not permitted

Итак, есть еще один пример того, как SELinux может работать как привратник.

SELinux Audit Logs

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

  • + / Вар / Журнал / аудит / audit.log +

  • + / Вар / Журнал / messages

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

Файл + / var / log / audit / audit.log + будет использоваться, если запущен демон audd. Файл + / var / log / messages используется, если AuditD остановлен и rsyslog запущен. Если оба демона запущены, используются оба файла: + / var / log / audit / audit.log + записывает подробную информацию, в то время как легкая для чтения версия хранится в + / var / log / messages +.

Расшифровка сообщений об ошибках SELinux

Мы рассмотрели одно сообщение об ошибке SELinux в предыдущем разделе (см. «SELinux в действии 2: ограничение разрешений для запуска сценариев»). Затем мы использовали команду + grep для просмотра файла` + / var / log / messages`. К счастью, SELinux поставляется с несколькими инструментами, которые делают жизнь немного проще. Эти инструменты не установлены по умолчанию и требуют установки нескольких пакетов, которые вы должны были установить в первой части этого руководства.

Первая команда - + ausearch +. Мы можем использовать эту команду, если запущен демон audd. В следующем фрагменте кода мы пытаемся просмотреть все сообщения об ошибках, связанных с демоном httpd. Убедитесь, что вы находитесь в своей учетной записи root:

ausearch -m avc -c httpd

В нашей системе было перечислено несколько записей, но мы сконцентрируемся на последней:

Время→ Чт 21 августа 16:42:17 2014 …​ type = AVC msg = аудит (1408603337.115: 914): avc: отказано {getattr} для pid = 10204 comm = "httpd" путь = "/ www / html / index.html" dev = "dm-0" ino = 8445484 scontext = system_u: system_r: httpd_t: s0 tcontext = undefined_u: object_r: default_t: s0 tclass = файл

Even experienced system administrators can get confused by messages like this unless they know what they are looking for. To understand it, let’s take apart each of the fields:

* type=AVC and avc: AVC stands for _Access Vector Cache_. SELinux caches access control decisions for resource and processes. This cache is known as the Access Vector Cache (AVC). That’s why SELinux access denial messages are also known as “AVC denials”. These two fields of information are saying the entry is coming from an AVC log and it’s an AVC event.
* denied \{ getattr }: The permission that was attempted and the result it got. In this case the get attribute operation was denied.
* pid=10204. This is the process id of the process that attempted the access.
* comm: The process id by itself doesn’t mean much. The comm attribute shows the process command. In this case it’s httpd. Immediately we know the error is coming from the web server.
* path: The location of the resource that was accessed. In this case it’s a file under /www/html/index.html.
* dev and ino: The device where the target resource resides and its inode address.
* scontext: The security context of the process. We can see the source is running under the httpd_t domain.
* tcontext: The security context of the target resource. In this case the file type is default_t.
* tclass: The class of the target resource. In this case it’s a file.

If you look closely, the process domain is httpd_t and the file’s type context is default_t. Since the httpd daemon runs within a confined domain and SELinux policy stipulates this domain doesn’t have any access to files with default_t type, the access was denied.

We have already seen the `+sealert+` tool. This command can be used with the id value of the error message logged in the `+/var/log/messages+` file.

In the following code snippet we again `+grep+` through the the `+/var/log/message+` file for SELinux related errors:

[source,code-pre]

cat / var / log / messages | grep "SELinux предотвращает"

In our system, we look at the very last error. This is the error that was logged when our restricteduser tried to run the httpd daemon:

[source,code-pre]

…​ 25 августа 11:59:46 localhost setroubleshoot: SELinux запрещает / usr / bin / su использовать возможность setuid. Для полных сообщений SELinux. запустите sealert -l e9e6c6d8-f217-414c-a14e-4bccb70cfbce

As suggested, we ran `+sealert+` with the ID value and were able to see the details (your ID value should be unique to your system):

[source,code-pre]

тюлень-л

[source,code-pre]

SELinux запрещает / usr / bin / su использовать возможность setuid.

…​

Тип необработанных сообщений аудита = AVC msg = аудит (1408931985.387: 850): avc: отказано {setuid} для pid = 5855 comm = возможность "sudo" = 7 scontext = user_u: user_r: user_t: s0 tcontext = user_u: user_r: user_t: s0 tclass = возможность

type = SYSCALL msg = аудит (1408931985.387: 850): arch = x86_64 syscall = setresuid success = нет выхода = EPERM a0 = ffffffff a1 = 1 a2 = ffffffff a3 = 7fae591b92e0 items = 0 ppid = 5739 pid = 5855 auid = 1008 uid = 1008 uid 0 gid = 1008 euid = 0 suid = 0 fsuid = 0 egid = 0 sgid = 1008 fsgid = 0 tty = pts2 ses = 22 comm = sudo exe = / usr / bin / sudo subj = user_u: user_r: user_t: s0 key = (значение NULL)

Хеш: su, user_t, user_t, возможность, setuid

We have seen how the first few lines of the output of `+sealert+` tell us about the remediation steps. However, if we now look near the end of the output stream, we can see the “Raw Audit Messages” section. The entry here is coming from the `+audit.log+` file, which we discussed earlier, so you can use that section to help you interpret the output here.

=== Multilevel Security

Multilevel security or *MLS* is the fine-grained part of an SELinux security context.

So far in our discussion about security contexts for processes, users, or resources we have been talking about three attributes: SELinux user, SELinux role, and SELinux type or domain. The fourth field of the security context shows the _sensitivity_ and optionally, the _category_ of the resource.

To understand it, let’s consider the security context of the FTP daemon’s configuration file:

[source,code-pre]

ls -Z /etc/vsftpd/vsftpd.conf

The fourth field of the security context shows a sensitivity of s0.

[source,code-pre]

-rw -------. корень корень system_u: object_r: etc_t: s0 /etc/vsftpd/vsftpd.conf

The sensitivity is part of the _hierarchical_ multilevel security mechanism. By hierarchy, we mean the levels of sensitivity can go deeper and deeper for more secured content in the file system. Level 0 (depicted by s0) is the lowest sensitivity level, comparable to say, “public.” There can be other sensitivity levels with higher s values: for example, internal, confidential, or regulatory can be depicted by s1, s2, and s3 respectively. This mapping is not stipulated by the policy: system administrators can configure what each sensitivity level mean.

When a SELinux enabled system uses MLS for its policy type (configured in the `+/etc/selinux/config+` file), it can mark certain files and processes with certain levels of sensitivity. The lowest level is called “current sensitivity” and the highest level is called “clearance sensitivity”.

Going hand-in-hand with sensitivity is the _category_ of the resource, depicted by c. Categories can be considered as labels assigned to a resource. Examples of categories can be department names, customer names, projects etc. The purpose of categorization is to further fine-tune access control. For example, you can mark certain files with confidential sensitivity for users from two different internal departments.

For SELinux security contexts, sensitivity and category work together when a category is implemented. When using a range of sensitivity levels, the format is to show sensitivity levels separated by a hyphen (for example, s0-s2). When using a category, a range is shown with a dot in between. Sensitivity and category values are separated by a colon (:).

Here is an example of sensitivity / category pair:

[source,code-pre]

user_u: object_r: etc_t: s0: c0.c2

There is only one sensitivity level here and that’s s0. The category level could also be written as c0-c2.

So where do you assign your category levels? Let’s find the details from the `+/etc/selinux/targeted/setrans.conf+` file:

[source,code-pre]

cat /etc/selinux/targeted/setrans.conf

[source,code-pre]

# Таблица перевода Multi-Category Security для SELinux # # # Объекты могут быть разделены на категории 0-1023, определенные администратором. # Объекты могут находиться в нескольких категориях одновременно. # Категории хранятся в системе как c0-c1023. Пользователи могут использовать эту # таблицу для перевода категорий в более значимый вывод. # Примеры: # s0: c0 = CompanyConfidential # s0: c1 = PatientRecord # s0: c2 = Неклассифицированный # s0: c3 = TopSecret # s0: c1, c3 = CompanyConfidentialRedHat s0 = SystemLow s0-s0: c0.c1023 = SystemLow-SystemHigh s0 : c0.c1023 = SystemHigh

We won’t go into the details of sensitivities and categories here. Just know that a process is allowed read access to a resource only when its sensitivity and category level is higher than that of the resource (i.e. the process domain _dominates_ the resource type). The process can write to the resource when its sensitivity/category level is less than that of the resource.

==== Conclusion

We have tried to cover a broad topic on Linux security in the short span of this three-part-series. If we look at our system now, we have a simple Apache web server installed with its content being served from a custom directory. We also have an FTP daemon running in our server. There were a few users created whose access have been restricted. As we went along, we used SELinux packages, files, and commands to cater to our security needs. Along the way we also learned how to look at SELinux error messages and make sense of them.

Entire books have been written on the SELinux topic and you can spend hours trying to figure out different packages, configuration files, commands, and their effects on security. So where do you go from here?

One thing I would do is caution you not to test anything on a production system. Once you have mastered the basics, start playing with SELinux by enabling it on a test replica of your production box. Make sure the audit daemons are running and keep an eye on the error messages. Check any denials preventing services from starting. Play around with the boolean settings. Make a list of possible steps for securing your system, like creating new users mapped to least-privilged SELinux accounts or applying the right context to non-standard file locations. Understand how to decipher an error log. Check the ports for various daemons: if non-standard ports are used, make sure they are correctly assigned to the policy.

It will all come together with time and practice. :)
Related