Смекни!
smekni.com

Security-Enhanced Linux — линукс с улучшенной безопасностью (стр. 6 из 7)

Одним из главных, если можно так выразиться, демонов в системе является демон init. Как уже говорилось, init является прародителем всех процессов в системе и имеет идентификатор 1. Выполнив задачи, поставленные в ему в файле inittab, демон init не завершает свою работу – он постоянно находится в памяти и отслеживает выполнение других процессов. Надо отметить, что init становится родителем «осиротевших» процессов (дочерних процессов, у которых родитель завершил свою работу), называемых зомби, для поддержания строгой иерархии процессов в системе.


3. Технологическая часть

3.1 Выбор дистрибутива

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

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

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

Вот эти три дистрибутива: Debian, ReadHat, Slackware.

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

Группа ReadHat включает в: RedHat, FedoraCore, KSI, BlackCat, ASPLinux, AltLinux, Mandrake, BestLinux, TurboLinux и др.

Родителем всей этой группы является дистрибутив RedHat. На сегодня это один из самых популярных дистрибутивов. Компания RedHat представляет несколько вариантов поставки, но все они платные. Поэтому выбор пал на дистрибутив FedoraCore – настольную версию RedHat, отправленной в свободное плавание.

Т.к. поддержка SELinux была включена в дистрибутивы FedoraCore только с версии 2, а последняя 5-ая версия считается еще не устоявшейся, то был выбран дистрибутив FedoraCore 4.


3.2 Создание демона

Демон – это консольное приложение, т.к. он работает в неинтерактивном режиме и графическая оболочка ему не нужна.

Создание демона можно логически разделить на три части:

Создание процесса с помощью fork();

Отрыв от управляющего терминала;

Обработка сигналов или событий (совершение так называемой полезной работы)

Системный вызов fork создает новый процесс. Возвращает идентификатор дочернего процесса или 0 в случае успеха и -1 в случае ошибки (код ошибки – в переменной errno).

На языке Си создание нового процесса будет выглядеть так:

int pid = fork();

if( pid = = -1 ) // fork failed

{perror(“Невозможно создать процесс!”);

exit( 1 );}

else

{if( pid <> 0 ) exit( 0 ); // parent process exits}

Возвращаемое значение -1 свидетельствует об ошибке, но поскольку fork не имеет входных аргументов, то ошибочная ситуация никак не связана с вызывающим процессом. Единственная возможная ошибка – исчерпывание системных ресурсов, то есть либо нехватка места в файле подкачки, либо в системе исполняется слишком много процессов.

Т.к. по завершению fork оба процесса (потомок и предок) получают от него возвращаемое значение, а нам интересен потомок, то строкой «if( pid <> 0 ) thenexit( 0 );» мы завершаем процесс предок (процесс-потомок получает от fork значение 0, родительский процесс – идентификатор процесса-потомка), в то время как дочерний процесс продолжает выполняться.

После завершения родительского процесса контроль над терминалом возвращается запустившей его программе (оболочке), а новый процесс, созданный функцией fork, выполняется в фоновом режиме. Однако наш процесс все еще принадлежит той же группе, что и создавший его процесс. Для того чтобы демон стал полностью независим от запустившего его терминала, новый процесс следует поместить в новую группу, а самый простой способ сделать это - создать новую сессию.

Новая сессия создается вызовом функции setsid:

pid = setsid();

if( pid = = -1 ) // setsid failed

{perror(“Невозможно создать новую сессию”);

exit( 1 );}

Теперь процесс выполняется в режиме демона.

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

В связи с этим было решено написать свой обработчик сигналов.

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

Процесс вызова обработчика называют перехватом сигнала. Когда выполнение обработчика завершается, процесс возобновляется с той точки, где был получен сигнал.

Чтобы сигналы не поступали в программу, можно указать, что они должны игнорироваться или блокироваться. Игнорируемый сигнал просто пропускается и не оказывает на процесс никакого влияния. Блокируемый сигнал ставится в очередь на обработку, но ядро не требует от процесса никаких действий до явного разблокирования сигнала. Обработчик вызывается для разблокированного сигнала только один раз, даже если в течение периода блокировки поступило несколько таких сигналов.

В данной работе демон обрабатывает только сигналы SIGUSR1, SIGUSR2, SIGTERM, SIGINT, SIGQUIT. Остальные сигналы игнорируются, ну кроме сигнала SIGKILL (данный сигнал не может блокироваться и приводит к безусловному завершению процесса на уровне операционной системы).

Сигналы SIGUSR1 и SIGUSR2 не имеют стандартного назначения. Ими можно пользоваться в различных ситуациях.

При получении сигнала SIGUSR1 демон выводит на терминал информацию о программе, при получении SIGUSR2 – системную информацию(PID, PPID, UID, GID).

Все полученные сигналы протоколируется в файл с указанием времени получения сигнала.

3.3 Политика для созданного демона

По умолчанию, в целевой политике все процессы, для которых не определены собственные политики, запускаются в домене unconfined_t, в котором SELinux разрешает все.

На специальном языке программирования создадим собственную политику безопасности, разрешающую демону записывать сообщения в файл лога, который будет находиться в домашнем каталоге сущности hevil (в моем случаем это будет /home/hevil).

Для этого придется отредактировать несколько файлов, ну а потом скомпилировать и загрузить политику вышеуказанными способами.

Для начала нужно создать саму сущность hevil. Прошу заметить, что в настоящий момент мы находимся от имени пользователя root системы UNIX, но в SELinux это будет сущность (пользователь) hevil.

В конец файла /ets/selinux/targeted/policy/src/users.te нужно добавить следующее объявление:

user hevil roles { user_r hevil_r };

Данная строчка означает, что будет создан пользователь hevil с ролями user_r и hevil_r.

Чтобы можно было запустить демона под данной сущностью нужно прописать роль hevil_r в /ets/selinux/targeted/policy/src/domains/misc/hevil.te:

full_user_role(hevil); # Создание обычной пользовательской роли (назначение

# соответствующих прав)

in_user_role(hevil_daemon_t); # Объявление перехода контекста роли user_r в домен

# hevil_daemon_t

Добавим правило перехода между ролями в /ets/selinux/targeted/policy/src/rbac:

allow user_r hevil_r;

allow hevil_r user_r;

Теперь можно будет свободно переходить из роли user_r в hevil_r.

Определим макрос перехода контекста, для этого нужно отредактировать файл

/ets/selinux/targeted/policy/src/ /macros/user_macros.te, добавивследующиестроки:

undefine(`in_user_role')

define(`in_user_role', `

role user_r types $1;

role staff_r types $1;

role hevil_r types $1;')

Устанавливаем с командной строки контекст для домашнего каталога /home/hevil:

find /home/hevil -print0|xargs -0 chcon --h hevil:object_r:hevil_home_t

chcon -h hevil:object_r:hevil_home_dir_t /home/hevil

Типы hevil_home_dir_t и hevil_home_t автоматически создались при создании сущности.

Для корректной работы политики необходимо создать еще тип директории с демоном, тип файла с демоном и исполняемого файла. Это достигается редактированием файла /ets/selinux/targeted/policy/src//types/hevil_types.te:

# Создание соответствующих типов

typehevil_daemon_t, domain;

type hevil_daemon_dir_t, dir_type;

type myapp_exec_t, file_type, sysadmfile, exec_type;

# Правило перехода от типа hevil_daemon_t

# к hevil_daemon_exec_t

type_transition hevil_daemon_t hevil_daemon_exec_t:{ file }

Далее установим контекст для этой директории и файла. Эти действия аналогичны, как и для домашнего каталога.

find /root/daemon -print0|xargs -0 chcon --h hevil:object_r:hevil_home_t

chcon -h hevil:object_r:hevil_home_dir_t /root/daemon

Устанавливаемправилодоступа hevil_r к hevil_daemon_t и hevil_daemon_dir_t.

hevil_t - это пользовательский домен роли hevil_r (создается автоматически).

hevil_daemon_exec_t - тип исполняемого файла.

# Разрешение записи в директорию с демоном

rw_dir_create_file(hevil_t, hevil_daemon_dir_t)

# Разрешениезапускадемона

can_exec(hevil_t, hevil_daemon_exec_t)

Создаем домен, в котором выполняется демон. Вфайл /ets/selinux/targeted/policy/src/domains/program/hevil.te вписываемстрочку:

daemon_domain(daemon_t);

Данный макрос создаст стандартный домен для демона.

В этот же файл добавим еще правило для демона:

rolesystem_rtypesdaemon_t; #разрешен доступ суперпользователя

role hevil types daemon_t; #разрешендоступдля hevil

in_iser_role(daemon_t) #объявлениепереходаконтекста hevil в #daemon_t

# Автоматически при запуске демона осуществляется переход

# вдомендемона

domain_auto_trans(hevil_t, hevil_daemon_exec_t, daemon_t)

# Разрешаем init переходить в daemon_t при загрузке

domain_auto_trans(initrc_t, daemon_exec_t, daemon_t)

#hevil_t может перейти в daemon_tво время запуска демона

domain_auto_trans(hevil_t, daemon_exec_t, daemon_t)

#доступктерминалу

allow daemon_t admin_tty_type:chr_file rw_file_perms;