46596 (607873), страница 5
Текст из файла (страница 5)
Демон – это консольное приложение, т.к. он работает в неинтерактивном режиме и графическая оболочка ему не нужна.
Создание демона можно логически разделить на три части:
Создание процесса с помощью 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 ) then exit( 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:
# Создание соответствующих типов
type hevil_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);
Данный макрос создаст стандартный домен для демона.
В этот же файл добавим еще правило для демона:
role system_r types daemon_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;
#разрешение на запись в файл
allow daemon_t { ttyfile ptyfile }:chr_file rw_file_perms;
#разрешение писать в файл домашнего каталога
rw_dir_create_file(daemon_t, hevil_home_dir_t)
Теперь остается самый ответственный этап: компилирование и загрузка политики в память. make load
3.4 Демонстрация работы демона
Суперпользователь имеет максимальные права в системе, поэтому все процессы, запущенные от его имени будут иметь такой же уровень привилегий.
Регистрируемся в системе под root.
Запускаем демона командой ./hevil (в каталоге с программой).
Получается, что демон, запущенный пользователем root, будет имеет максимальные, ничем не ограниченные права.
С помощью команды kill [номер сигнала] [PID процесса] посылаем различные сигналы демону. Просмотрев журнал можно убедиться, что все записано в лог, т.е. демон работоспособен.
Теперь с помощью команды make load загружаем новую политику в память.
Теперь посылаем сигналы демону. Он выдаст сообщение об ошибки, что невозможно записать в файл. Это объясняется тем, что правила политики, запрещают производить запись в заданный файл, в то время как классическая система безопасности это разрешает.
Для проверки можно зайти в каталог с логом непосредственно пользователем root и убедиться, что доступ для самого пользователя в заданный каталог разрешен.
Заключение
В данной работе была освещен Security-Enhanced Linux — линукс с улучшенной безопасностью.
Достоинства данной технологии очевидны, т.к. он базируется на принципе наименьших прав, т.е. запущенному процессу дается именно столько прав, сколько ему требуется. Более того, SELinux существует параллельно с классической системой безопасности Linux, независим от нее. SELinux обрабатывает только те запросы, которые разрешены классической системой безопасности и не может разрешить то, что запрещено последней. На примере демона, запущенного от имени root (т.е. с нулевым уровнем привилегий) было продемонстрирована «сила» Security-Enhanced Linux.
Недостатком SELinux является то, что отсутствует удобное ПО по разработке своей собственной политики. Вариант редактирования исходных кодов политик, компилирования, просмотра логов и внесение изменений в код, двигаясь пошагово в цикле – является неудовлетворительным.
В настоящее время ведутся активные работы как по переводу документации SELinux на русский язык, так и попыток создания ПО.
Несомненно, нужно отметить, что LUG (Linux User Group) нашего университета тоже присоединилось к этому движению. Несколько студентов решили объединить свои силы для помощи мировому сообществу.
Ознакомиться с задачами, которые были поставлены в LUG можно на сайте http://www.selinux.ru .
Список литературы
-
Эви Немеет, Гарт Снайдер, Скотт Сибасс, Трент Р.Хейн «UNIX. Руководство системного администратора для профессионалов», 3-е издание
-
Марк Дж. Рочкинд «Программирование для UNIX. Наиболее полное руководство в подлиннике», 2-е издание
-
Алексей Стахнов «Linux. Наиболее полное руководство в подлиннике», 2-е издание
-
http://www.redhat.ru/docs/manuals/enterprise/RHEL-4-Manual/selinux-guide/index.html - официальное руководство по SELinux для Red Hat 4 [03.06.2006].
-
http://www.nsa.gov/selinux - Официальный сайт NSA [03.06.2006].
-
http://www.nsa.gov/selinux/faq.html - Официальный документ SE Linux FAQ [03.06.2006].
-
http://www.nsa.gov/selinux/docs.html - Опубликованные NSA материалы, отчёты и презентации. [03.06.2006].
-
http://www.rhd.ru/docs/articles/selinux_rhel4/ - Получите преимущества SELinux в Red Hat® Enterprise Linux® 4. Фай Кокер и Рассел Кокер. [03.06.2006].
-
http://gazette.lrn.ru/rus/articles/intro_selinux.html - Введение в SE Linux: новый SE Linux. Фей Кокер. [03.06.2006].
-
http://ru.wikipedia.org/wiki/SELinux - Материал из Википедии
-
http://www.osp.ru/text/302/185543/ - SELinux — система повышенной безопасности. Андрей Боровский. [03.06.2006].
Приложение 1
Установка основных пакетов SELinux для Fedora.
Пакеты RPM с новой реализацией SE Linux могут быть получены с узла ftp://people.redhat.com/dwalsh/SELinux
Эти пакеты поддерживаются Дэном Уолшем (Dan Walsh).
Для установки SE Linux на тестовой машине с дистрибутивом Fedora нужно сделать следующее: