вторник, июля 07, 2009

SELinux Lockdown, 6: Создание ролей SELinux

оригинал - SELinux Lockdown Part Six: Customized SELinux Roles

Продолжаю выкладывать перевод цикла статей по использованию SELinux. Оригинал на английском языке опубликован в блоге Доминика Грифта (Dominick Grift).


В четвёртой части серии описывался процесс создания пользовательских доменов SELinux. Создание ролей осуществляется очень похожим способом. Как уже отмечалось в предыдущей статье про RBAC: роли это сопоставления к пользовательским доменам (прим. перев.: в оригинале - Roles are mappings to User Domains, в отличии от автора я не живу в Голландии, поэтому более удачного перевода пока не предумал). Какие-то домены пользователей могут использоваться пользователями для входа в систему, потому что эти домены, например, имеют полномочия по доступу к домашней директории пользователя. Такие домены в предыдущей части назывались основными (primary) пользовательскими доменами. Другие домены созданы в качестве дополнительных. Пользователи, используя команды sudo или su вместе с newrole, могут осуществить доменный переход (Domain Transition) к этим дополнительным доменам. Дополнительные домены не могут использоваться для входа в систему.

В этой части будет продемонстрировано как создается такой дополнительный пользовательский домен. Целью является реализовать привилегированную роль SELinux, которой предоставлены полномочия по управлению DNS службой Bind. За основу будет взят пользовательский домен webadm_t, обсуждавшийся ранее. Также будет пересмотрен некоторый материал четвёртой части: Создание пользовательского домена SELinux - чтобы разрешить доступ к новой роли bindadm_r, потребуется изменить основной домен пользователя.

Начнём с создания нового дополнительного домена пользователя с названием bindadm, основанного на предустановленном домене SELinux webadm_t. Новый домен пользователя основан на двух файлах с исходным текстом политики SELinux (SELinux Source Policy): webadm.te и webadm.if

Файлы исходных текстов политики SELinux с расширением ".te" называются Type Enforcement файлы. Файлы с расширением ".if" называются интерфейсными (Interface files). Файлы Type Enforcement содержат описания (Declarations) и политику (Policy), персональные или локальные для данного домена (Domain). Интерфейсные файлы содержат описания и политики, общие для этого домена и других доменов, желающими взаимодействовать с данным доменом.

mkdir ~/bindadm; cd ~/bindadm;
echo "policy_module(bindadm, 0.0.1)" > bindadm.te;
echo "role bindadm_r;" >> bindadm.te;
echo "userdom_base_user_template(bindadm)" >> bindadm.te;
echo "allow bindadm_t self:capability { dac_override dac_read_search kill sys_ptrace sys_nice };" >> bindadm.te;
echo "files_dontaudit_search_all_dirs(bindadm_t)" >> bindadm.te;
echo "files_manage_generic_locks(bindadm_t) >> bindadm.te;
echo "files_list_var(bindadm_t)" >> bindadm.te;
echo "selinux_get_enforce_mode(bindadm_t)" >> bindadm.te;
echo "seutil_domtrans_setfiles(bindadm_t)" >> bindadm.te;
echo "logging_send_syslog_msg(bindadm_t)" >> bindadm.te;
echo "userdom_dontaudit_search_user_home_dirs(bindadm_t)" >> bindadm.te;


Это основное содержимое для привилегированного дополнительного домена пользователя. Исключена политика, специфичная для управления службой Apache.
Теперь добавим политику, специфичную для управления службой Bind. Можно позаимствовать эту политику из исходных текстов политики для Bind. Как уже отмечалось, общая политика располагается в интерфейсных файлах. Это значит, что если мы хотим включить общую политику, относящуюся к Bind, можно посмотреть в соответствующем файле политики bind.if если он доступен:

Начиная со строки 252 в bind.if и заканчивая строкой 305 описывается общая политика, разделяемая модулем Bind для управления службой bind. Для включения этой политики в наш Type Enforcement файл требуется всего лишь добавить вызов этого интерфейса:

echo "bind_admin(bindadm_t, bindadm_r)" >> bindadm.te;

На этом Type Enforcement файл bindadm заканчивается. Далее необходимо обеспечить другим доменам возможность взаимодействия с нашим доменом bindadm_t. Реализуем эту часть политики, взяв за основу файл webadm.if.

echo "## Bind administrator role" > bindadm.if;

echo "########################################" >> bindadm.if;
echo "## " >> bindadm.if;
echo "## Change to the bind administrator role." >> bindadm.if;
echo "## " >> bindadm.if;
echo '## ' >> bindadm.if;
echo "## " >> bindadm.if;
echo "## Role allowed access." >> bindadm.if;
echo "## " >> bindadm.if;
echo "## " >> bindadm.if;
echo "## " >> bindadm.if;
echo "#" >> bindadm.if;
echo "interface(\`bindadm_role_change',\`" >> bindadm.if;
echo " gen_require(\`" >> bindadm.if;
echo " role bindadm_r;" >> bindadm.if;
echo " ')" >> bindadm.if;
echo " allow \$1 bindadm_r;" >> bindadm.if;
echo "')" >> bindadm.if;


Позже общая политика администратора Bind (Bind Administrator Shared policy) будет использоваться в нашем основном специально созданном пользовательском домене SELinux.

Следующим шагом будет создание специализированного пользовательского домена SELinux для обслуживания Bind, разрешающего данному домену осуществлять переход к роли bindadm_r вызовом интерфейса bindadm_role_change. Создаваемый домен SELinux будет основан на пользовательском домене staff_t, описание политики смотрим в файле staff.te

echo "policy_module(bindguy, 0.0.1)" > bindguy.te;
echo "role bindguy_r;" >> bindguy.te;
echo "userdom_unpriv_user_template(bindguy)" >> bindguy.te;
echo "sudo_role_template(bindguy, bindguy_r, bindguy_t)" >> bindguy.te;
echo "ssh_role_template(bindguy, bindguy_r, bindguy_t)" >> bindguy.te;
echo "kernel_read_ring_buffer(bindguy_t)" >> bindguy.te;
echo "kernel_getattr_core_if(bindguy_t)" >> bindguy.te;
echo "kernel_getattr_message_if(bindguy_t)" >> bindguy.te;
echo "kernel_read_software_raid_state(bindguy_t)" >> bindguy.te;
echo "auth_domtrans_pam_console(bindguy_t)" >> bindguy.te;
echo "libs_manage_shared_libs(bindguy_t)" >> bindguy.te;
echo "seutil_run_newrole(bindguy_t, bindguy_r)" >> bindguy.te;
echo "netutils_run_ping(bindguy_t, bindguy_r)" >> bindguy.te;
echo "domain_read_all_domains_state(bindguy_t)" >> bindguy.te;
echo "domain_getattr_all_domains(bindguy_t)" >> bindguy.te;
echo "domain_obj_id_change_exemption(bindguy_t)" >> bindguy.te;
echo "files_read_kernel_modules(bindguy_t)" >> bindguy.te;
echo "kernel_read_fs_sysctls(bindguy_t)" >> bindguy.te;
echo "modutils_read_module_config(bindguy_t)" >> bindguy.te;
echo "modutils_read_module_deps(bindguy_t)" >> bindguy.te;
echo "miscfiles_read_hwdata(bindguy_t)" >> bindguy.te;
echo "term_use_unallocated_ttys(bindguy_t)" >> bindguy.te;


Чтобы разрешенить домену bindguy_t осуществлять переход в ограниченное окружение SELinux bindadm_t, добавим вызов интерфейса bindadm_role_change, определенного в нашем интерфейсном файле bindadm.if:

echo "bindadm_role_change(bindguy_r)" >> bindguy.te;

Можно также автоматически создать сопоставление пользователя SELinux с именем bindguy_u ролям bindguy_r, bindadm_r и system_r. Роль system_r включается, чтобы bindadm_t мог останавить, запустить и перезапустить системную службу bind.

echo "gen_user(bindguy_u, user, bindguy_r system_r bindadm_r, s0, s0 - mls_systemhigh, mcs_allcats)" >> bindguy.te;

Чтобы программы входа знали, что bindguy допустимый пользователь, добавим контексты по умолчанию для этого пользователя, взяв за основу контексты по умолчанию пользователя staff_u:

cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/bindguy_u
sed -i 's/staff/bindguy/g' /etc/selinux/targeted/contexts/users/bindguy_u


Теперь можно собрать и установить обе политики bindguy и bindadm:

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i bindguy.pp bindadm.pp


Далее командой useradd, опцией -Z и параметром bindguy_u можно создать нового пользователя Linux:

sudo useradd -Z bindguy_u bindguy

Для того, чтобы разрешить пользователю bindguy использовать команду sudo для автоматического перехода к Linux пользователю root и SELinux домену bindadm_t, добавим в /etc/sudoers:

echo "bindguy ALL=(ALL) ROLE=bindadm_r TYPE=bindadm_t ALL" >> /etc/sudoers;

При входе пользователя bindguy в систему он оказывается в пользовательском домене bindguy_t, основанном на домене staff_t. Домен bindguy_t может осуществлять переход в домен bindadm_t, используемый с правами root и позволяющий управлять службой Bind.

Например, выполнив следующую команду, пользователь bindguy сможет перезапустить службу bind:

sudo service named restart

Также пользователю bindguy разрешается редактировать различные конфигурационные и файлы информационного наполнения Bind. При этом, например, пользователь bindguy не имеет прав изменить пароль пользователя root.

Примечание: Если вы нашли какие-то ошибки в этом упражнении или у вас есть какие-то вопросы или комментарии, пожалуйста свяжитесь с автором. Спасибо!

Справка: man bind, man semodule, man sudo, man useradd

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