I often wonder what agitprop or ignorance is concealed by those that link SE Linux with phrases like "over my dead body", "disable instantly" or "not for the faint-hearted". Here's a quick recipe for applying SE Linux to a service if there's no standard policy (AFAIK). Testbed: CentOS 5.2, vanilla 2.6.25 kernel with SE Linux enabled (Policy v.21), policycoreutils-gui, selinux-policy-devel and pdnsd. Pdnsd of course it the caching DNS server that, unlike ISC BIND, has an on-disk cache that survives restarts and reboots.
Step 0: run /usr/share/system-config-selinux/polgengui.py and work your way through the screens. Make sure you choose "Standard Init Daemon", TCP/53 and UDP/53, syslog and add the cache and log directory.
Step 1: review your filecontext, interface and Type Enforcement files. Should look something like this:
pdnsd.fc
Code:
/usr/sbin/pdnsd -- gen_context(system_u:object_r:pdnsd_exec_t,s0)
/var/cache/pdnsd(/.*)? gen_context(system_u:object_r:pdnsd_rw_t,s0)
pdnsd.if
Code:
## <summary>policy for pdnsd</summary>
########################################
## <summary>
## Execute a domain transition to run pdnsd.
## </summary>
## <param name="domain">
## <summary>
## Domain allowed to transition.
## </summary>
## </param>
#
interface(`pdnsd_domtrans',`
gen_require(`
type pdnsd_t, pdnsd_exec_t;
')
domain_auto_trans($1,pdnsd_exec_t,pdnsd_t)
allow pdnsd_t $1:fd use;
allow pdnsd_t $1:fifo_file rw_file_perms;
allow pdnsd_t $1:process sigchld;
')
########################################
## <summary>
## Search pdnsd rw directories.
## </summary>
## <param name="domain">
## <summary>
## Domain allowed access.
## </summary>
## </param>
#
interface(`pdnsd_search_rw_dir',`
gen_require(`
type pdnsd_rw_t;
')
allow $1 pdnsd_rw_t:dir search_dir_perms;
files_search_rw($1)
')
########################################
## <summary>
## Read pdnsd rw files.
## </summary>
## <param name="domain">
## <summary>
## Domain allowed access.
## </summary>
## </param>
#
interface(`pdnsd_read_rw_files',`
gen_require(`
type pdnsd_rw_t;
')
allow $1 pdnsd_rw_t:file r_file_perms;
allow $1 pdnsd_rw_t:dir list_dir_perms;
files_search_rw($1)
')
########################################
## <summary>
## Create, read, write, and delete
## pdnsd rw files.
## </summary>
## <param name="domain">
## <summary>
## Domain allowed access.
## </summary>
## </param>
#
interface(`pdnsd_manage_rw_files',`
gen_require(`
type pdnsd_rw_t;
')
allow $1 pdnsd_rw_t:file manage_file_perms;
allow $1 pdnsd_rw_t:dir rw_dir_perms;
')
pdnsd.te
Code:
policy_module(pdnsd,1.0.0)
########################################
#
# Declarations
#
type pdnsd_t;
type pdnsd_exec_t;
domain_type(pdnsd_t)
init_daemon_domain(pdnsd_t, pdnsd_exec_t)
type pdnsd_rw_t;
files_type(pdnsd_rw_t)
########################################
#
# pdnsd local policy
#
# Init script handling
domain_use_interactive_fds(pdnsd_t)
## internal communication is often done using fifo and unix sockets.
allow pdnsd_t self:fifo_file rw_file_perms;
allow pdnsd_t self:unix_stream_socket create_stream_socket_perms;
files_read_etc_files(pdnsd_t)
libs_use_ld_so(pdnsd_t)
libs_use_shared_libs(pdnsd_t)
miscfiles_read_localization(pdnsd_t)
ifdef(`targeted_policy',`
term_dontaudit_use_unallocated_ttys(pdnsd_t)
term_dontaudit_use_generic_ptys(pdnsd_t)
')
allow pdnsd_t pdnsd_rw_t:file manage_file_perms;
allow pdnsd_t pdnsd_rw_t:dir create_dir_perms;
files_pid_filetrans(pdnsd_t,pdnsd_rw_t, { file dir })
sysnet_dns_name_resolve(pdnsd_t)
corenet_non_ipsec_sendrecv(pdnsd_t)
allow pdnsd_t self:tcp_socket create_stream_socket_perms;
corenet_tcp_sendrecv_all_if(pdnsd_t)
corenet_tcp_sendrecv_all_nodes(pdnsd_t)
corenet_tcp_sendrecv_all_ports(pdnsd_t)
corenet_tcp_bind_all_nodes(pdnsd_t)
corenet_tcp_bind_dns_port(pdnsd_t)
allow pdnsd_t self:udp_socket { create_socket_perms listen };
corenet_udp_sendrecv_all_if(pdnsd_t)
corenet_udp_sendrecv_all_nodes(pdnsd_t)
corenet_udp_sendrecv_all_ports(pdnsd_t)
corenet_udp_bind_all_nodes(pdnsd_t)
corenet_udp_bind_dns_port(pdnsd_t)
...and run the "pdnsd.sh" to create the binary policy representation (pdnsd.pp), load it and set default SELinux security contexts.
Step 2: If you run SE Linux in enforcing mode then stopping, starting, restarting and generally using Pdnsd will result in some sealerts. Add these to the pdnsd.te:
Code:
allow pdnsd_t dns_port_t:tcp_socket name_bind;
allow pdnsd_t dns_port_t:udp_socket name_bind;
allow pdnsd_t self:unix_dgram_socket create;
allow pdnsd_t self:unix_dgram_socket connect;
allow pdnsd_t self:unix_dgram_socket write;
allow pdnsd_t self:capability setgid;
allow pdnsd_t self:capability setuid;
allow pdnsd_t pdnsd_rw_t:sock_file create;
allow pdnsd_t pdnsd_rw_t:sock_file unlink;
and run the "pdnsd.sh" again.
Step 3: These lines should be added to your local policy:
Code:
allow pdnsd_t sysctl_t:dir search;
allow pdnsd_t devlog_t:sock_file write;
allow pdnsd_t syslogd_t:unix_dgram_socket sendto;
allow pdnsd_t sysctl_kernel_t:dir search;
allow pdnsd_t sysctl_kernel_t:file read;
and recompile your local policy file to finish things off.
That should be it.
Have fun.