среда, 19 октября 2011 г.

Упреждающая безопасность - SELinux

На пятом курсе в своем дипломе я пыталась реализовать систему защиты пользовательской информации, основанной на принципах работы kernel-mode руткитов – на перехвате системных вызовов и модификации их кода таким образом, чтобы было возможно скрывать важные данные от любого пользователя. Основным посылом для разработки такой системы являлось то, что в операционных системах Linux пользователь с учетной записью root, в том числе и злоумышленник, обманным путем получивший права рута, имеет доступ ко всем файлам и процессам. Через полгода после сдачи диплома я обнаружила, что проблему вполне можно решить давно известными средствами :)) - например, с помощью программы SELinux.

Разграничительный контроль доступа.
В операционных системах Linux для каждого файла используется три типа прав доступа – read, write и execute, а также три типа пользователей, обладающих правами доступа к этому файлу – владелец, группа владельца и все остальные. Права доступа к файлу можно описать одной строчкой – 

      rwx                   rwx                       rwx
(владелец) (группа владельца) (остальные)

Эта строчка описывает, что может делать с файлом каждый пользователь – читать, писать, исполнять.
Кроме приведенных трех типов пользователей существует еще один – root, суперпользователь. Его права доступа к файлу не задаются никогда, потому что он имеет доступ ко всем файлам и процессам в системе.
Такая организация прав, когда для каждой пары субъект-объект (пользователь-файл) существует перечисление типов доступа, называется разграничительным контролем доступа (DAC, discretionary access control). По умолчанию эта организация используется во всех ОС Linux, но она имеет некоторые недостатки.
Во-первых, когда пользователь, обладающий определенными правами, запускает какую-либо программу – например, веб-сервер Apache – процесс этой программы наследует все права пользователя. То есть Apache будет иметь доступ к личным файлам пользователя и файлам его группы. И если на компьютер попадет эксплойт, использующий уязвимость веб-сервера, все личные файлы пользователя и его группы могут оказаться в руках злоумышленника.
Во-вторых, опасность представляет вседозволенность пользователя/процесса, обладающего правами root. Как и в первом случае, с помощью эксплойта, использующего уязвимость программы, имеющей права рута, злоумышленник может получить доступ к системе. Либо же злоумышленник может подобрать пароль к рутовой учетной записи.

Как видно, стандартный DAC не обеспечивает достаточной безопасности. Существуют другие способы организации прав доступа, работающие поверх DAC, такие как RBAC (role-based access control, управление доступом на основе ролей), и MAC (mandatory access control, принудительное управление доступом). Основой этих двух способов является предоставление пользователям и процессам минимальных прав, необходимых им для работы. Программа SELinux, которой посвящен сегодняшний разговор, является реализацией MAC.

Термины и принципы работы SELinux.
SELinux – это программа, реализующая дополнительный уровень безопасности ОС. Она работает поверх стандартной системы безопасности DAC, то есть не может разрешить или запретить пользователю/программе то, что запрещено стандартными средствами. SELinux ограничивает права приложений с помощью политик. Политика – это набор правил доступа приложений и пользователей к файлам и процессам. Политики можно создавать самим с помощью простого языка описаний правил, также существуют уже готовые политики, входящие в поставку программы. В отличие от стандартной системы безопасности ОС, где происходит взаимодействие субъекта с объектом, в SELinux взаимодействуют домен с типом. Домен – это уровень доступа, которым обладает любой процесс в системе, это описание прав процесса (субъекта). А тип – это уровень секретности, которым обладает любой файл/каталог/сокет (объект). И политика на основе правил при вызове доменом типа определяет, имеет ли домен права на открытие этого типа. Еще один термин, роль, имеет отношение к самому пользователю. Роль определяет, к каким доменам имеет доступ пользователь. У каждого домена, типа и роли есть контекст безопасности – это набор всех атрибутов, которыми обладает домен, тип или роль (то есть его права и права на него). 

На рисунке изображены два пользователя с разными ролями и один процесс (субъекты), пытающиеся получить доступ к одному типу (объекту). Также один из пользователей пытается получить доступ к процессу.
Термины SELinux
Итак, работа SELinux заключается в создании и обеспечении работы определенной политики, которая изначально задает каждому домену, типу и роли их права и права доступа к ним, и в дальнейшем регулирует их взаимодействие. Также правила политики самостоятельно, без участия пользователя, следят и реагируют на определенные события – например, при создании нового файла внутри папки файл наследует права этой папки, это описано в специальном правиле. При желании, такие правила можно изменять вручную.

Как это работает?
Чтобы понять, как именно работает SELinux, нужно отвлечься и рассмотреть понятие LSM (Linux Security Modules). LSM - это система, предоставляющая разработчикам систем защиты единый интерфейс для реализации своих проектов, и позволяющая различным системам защиты взаимодействовать с друг другом без конфликтов. Сама эта система не является защитной. Она лишь предоставляет свой функционал разработчикам. По сути, LSM является структурой, каркасом, описывающим общие правила реализации защитных модулей от разных разработчиков. LSM добавляет в ядро некоторые возможности, а разработчики сами решают, каким образом им воспользоваться этими возможностями.

SELinux является одним из таких защитных модулей, основанных на системе LSM. На его примере можно увидеть, какие возможности предоставляет LSM, и как модуль ими пользуется. Например, одной из возможностей является добавление дополнительных полей к структурам ядра - файлам/процессам/сокетам. В случае SELinux эти поля - рассмотренные выше контексты безопасности. Еще одна возможность - добавление в ядро специальных обработчиков безопасности. Задачей обработчиков является подача сигнала при любом важном событии в системе – создании файла, сокета, процесса, директории, монтирования файловой системы или устройства и т.д.. Все эти функции-обработчики определены в файле security.h (их название начинается на «security_»). В случае, если модуль безопасности не установлен – обработчики подают сигналы о важном событии, но ничего не происходит. А в случае, когда модуль безопасности установлен – например, SELinux, обработчик подает сигнал, а затем передает управление функции SELinux, которая проводит проверку прав.


На картинке изображены две ситуации – в первой модуль не установлен, и возможности LSM не используются, во второй установлен SELinux.
Работа LSM и SELinux
 
Как видно на картинке, в момент вызова security_path_mkdir управление переходит к функции SELinux. Проверив права, SELinux передает управление обратно ядерной функции mkdir.


Теперь следует более подробно рассмотреть принцип работы функций SELinux. Сначала функция, зная идентификаторы процесса и файла, обращается в AVC (Access Vector Cache, кэш вектора доступа), в котором хранятся предыдущие решения SELinux (для быстроты). Если в кэше не было найдено подходящее решение, программа обращается к серверу безопасности. Проверяются контексты безопасности процесса и файла, происходит обращение к применяемой политике и формируется решение.

В следующей части будет рассмотрено применение SELinux на практике.