woensdag 24 juni 2009

SELinux Lockdown Part Six: Customized SELinux Roles

In part four of this series i have demonstrated how to create and implement a customized SELinux User Domain. Creating Roles is done in very much the same way. As mentioned in my previous article about RBAC: Roles are mappings to User Domains. Some User Domains can be used by users to log into the system because those User Domains have permissions to access the user home directory for example. I refer those these User Domains as primary User Domains. Other User Domains are designed to be secondary. Users can Domain Transition using the sudo or su with newrole command to these secondary User Domains. Secondary User Domains can not be used by a user to log into the system.

In this Chapter i am going to demonstrate how such a secondary User Domain is create and implemented. The goal is to create a Privileged SELinux Role that provides the permissions required to manage a Bind DNS service. This role will be based of off the webadm_t User Domain that was discussed previously. I will also revisit some material from part four: Customized SELinux User Domains because the user primary User Domain must be modified to be able to access our new bindadm_r role.

As mentioned i will start with creating a new secondary User Domain called bindadm that is based of off the pre-defined webadm_t SELinux User Domain. The two SELinux Source Policy files i am going base my new User Domain of are:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/webadm.te
http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/webadm.if

SELinux Source Policy files that have a ".te" extension are called Type Enforcement files. Files with a ".if" extension are called Interface files. Type Enforcement files have Declarations and Policy that are personal or local to the Domain. Interface files have Declarations and Policy that are shared by the Domain with other Domains that may want to interact with our 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;

This is the basic contents for a generic privileged secondary User Domain. I left out policy that is specific to managing the Apache service.
Now i will add policy that is specific to managing the Bind service. I am able to borrow this policy from the bind Source Policy. As i mentioned shared policy is located in Interface files. This means that if i want to include shared policy related to Bind i should be able to find this in the bind.te file if the policy is available:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/services/bind.if

Starting on line 252 in bind.if and ending on line 305 is policy shared by the Bind module to administrate the bind service. I just have to call this Interface in our bindadm Type Enforcement file to include this Policy:

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

This concludes my bindadm Type Enforcement file. Next my bindadm Source Policy should share policy that might be required by other Domains to be able to interact with our bindadm_t Domain. I will base this policy of off the webadm.if file.

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;

The Bind Administrator Shared policy above will later be called by our user primary Customized SELinux User Domain. I am now finished with my bindadm_t User Domain.

My next step is to create a Customized SELinux User Domain for our Bind guy and allow that User Domain to transition to the bindadm_r role by calling the bindadm_role_change interface. This Customized SELinux User Domain will be based of off the staff_t User Domain:

http://oss.tresys.com/projects/refpolicy/browser/trunk/policy/modules/roles/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;

Now i will call the bindadm_role_change interface that i have defined in the bindadm.if Interface file to allow the bindguy_t User Domain to transition to the bindadm_t SELinux restricted environment:

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

I can also automatically create a SELinux User Mapping called bindguy_u which is mapped to the bindguy_r, bindadm_r and system_r role. The system_r role is included so that bindadm_t can stop, start and restart the bind system service.

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

To let the login programs know that bindguy is a valid login user i will add default contexts for this user based of off staff_u default contexts:

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

Both the bindguy and bindadm policy can now be build and installed:

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

Now i can add a new Linux user with the useradd command and -Z option and bindguy_u parameter:

sudo useradd -Z bindguy_u bindguy

For bindguy to be able to use sudo to automatically transition to Linux user root and SELinux Domain bindadm_t i will add to /etc/sudoers:

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

When bindguy logs into the system he will find himself in the bindguy_t User Domain which is based of off the staff_t User Domain. The bindguy_t User Domain can domain transition to the bindadm_t User Domain which is a Domain to be used with root access, that can manage the Bind service.

Bindguy would be able to restart the bind service for example by executing:

sudo service named restart

Bindguy will also be able to edit the various Bind content and configuration files. Bindguy will not be able to change the root password for example.

Note: If you found any errors in this exercise or if you have any question or comments, please contact me. Thanks!

refer: man bind, man semodule, man sudo, man useradd

Geen opmerkingen:

Een reactie plaatsen