Since the earliest days there has been a command named audit2allow that takes audit messages of operations that SE Linux denied and produces policy that will permit those operations. A lesser known option for this program is the -R option to use the interfaces from the Reference Policy (the newer version of the policy that was introduced a few years ago). I have updated
my SE Linux repository for Lenny [1] with new packages of policy and python-sepolgen that fix some bugs that stopped this from being usable.
To use the -R option you have to install the selinux-policy-dev package and then run the command sepolgen-ifgen to generate the list of interfaces (for Squeeze I will probably make the postinst script of selinux-policy-dev do this). Doing this on Lenny requires selinux-policy-default version 0.0.20080702-20 or better and doing this on Debian/Unstable now requires selinux-policy-default version 0.2.20100524-2 (which is now in Testing) or better.
Would it be useful if I maintained my own repository of SE Linux packages from Debian/Unstable that can be used with Debian/Testing? You can use preferences to get a few packages from Unstable with the majority from Testing, but that s inconvenient and anyone who wants to test the latest SE Linux stuff would need to include all SE Linux related packages to avoid missing an important update. If I was to use my own repository I would only include packages that provide a significant difference and let the trivial changes migrate through Testing in the normal way.
The new Lenny policy includes a back-port of the new Milter policy from Unstable, this makes it a lot easier to write policy for milters. Here is an example of the basic policy for two milters, it allows the milters (with domains foo_milter_t and bar_milter_t) to start, to receive connections from mail servers, and to create PID files and Unix domain sockets.
policy_module(localmilter,1.0.0)
milter_template(foo)
files_pid_filetrans(foo_milter_t, foo_milter_data_t, sock_file file )
milter_template(bar)
files_pid_filetrans(bar_milter_t, bar_milter_data_t, sock_file file )
allow bar_milter_t self:process signull;
type bar_milter_tmp_t;
files_tmp_file(bar_milter_tmp_t)
files_tmp_filetrans(bar_milter_t, bar_milter_tmp_t, file)
manage_files_pattern(bar_milter_t, tmp_t, bar_milter_tmp_t)
After generating that policy I ran a test system in permissive mode and sent a test message. I ran audit2allow on the resulting AVC messages from /var/log/audit/audit.log and got the following output:
#============= bar_milter_t ==============
allow bar_milter_t bin_t:dir search;
allow bar_milter_t bin_t:file getattr;
allow bar_milter_t home_root_t:dir search;
allow bar_milter_t ld_so_cache_t:file read getattr ;
allow bar_milter_t lib_t:file execute;
allow bar_milter_t mysqld_port_t:tcp_socket name_connect;
allow bar_milter_t net_conf_t:file read getattr ioctl ;
allow bar_milter_t self:process signal;
allow bar_milter_t self:tcp_socket read write create connect setopt ;
allow bar_milter_t unlabeled_t:association recvfrom sendto ;
allow bar_milter_t unlabeled_t:packet recv send ;
allow bar_milter_t urandom_device_t:chr_file read;
allow bar_milter_t usr_t:file read getattr ioctl ;
allow bar_milter_t usr_t:lnk_file read;
#============= foo_milter_t ==============
allow foo_milter_t ld_so_cache_t:file read getattr ;
allow foo_milter_t lib_t:file execute;
allow foo_milter_t mysqld_port_t:tcp_socket name_connect;
allow foo_milter_t net_conf_t:file read getattr ;
allow foo_milter_t self:capability setuid setgid ;
allow foo_milter_t self:tcp_socket write setopt shutdown read create connect ;
allow foo_milter_t unlabeled_t:association recvfrom sendto ;
allow foo_milter_t unlabeled_t:packet recv send ;
Running the audit2allow command with the -R option gives the following output, it includes the require section that is needed for generating policy modules:
require
type sshd_t;
type ld_so_cache_t;
type bar_milter_t;
type foo_milter_t;
class process signal;
class tcp_socket setopt read create write connect shutdown ;
class capability setuid setgid ;
class fd use;
class file read getattr ;
#============= bar_milter_t ==============
allow bar_milter_t ld_so_cache_t:file read getattr ;
allow bar_milter_t self:process signal;
allow bar_milter_t self:tcp_socket read write create connect setopt ;
corecmd_getattr_sbin_files(bar_milter_t)
corecmd_search_sbin(bar_milter_t)
corenet_sendrecv_unlabeled_packets(bar_milter_t)
corenet_tcp_connect_mysqld_port(bar_milter_t)
dev_read_urand(bar_milter_t)
files_read_usr_files(bar_milter_t)
files_read_usr_symlinks(bar_milter_t)
files_search_home(bar_milter_t)
kernel_sendrecv_unlabeled_association(bar_milter_t)
libs_exec_lib_files(bar_milter_t)
sysnet_read_config(bar_milter_t)
#============= foo_milter_t ==============
allow foo_milter_t ld_so_cache_t:file read getattr ;
allow foo_milter_t self:capability setuid setgid ;
allow foo_milter_t self:tcp_socket write setopt shutdown read create connect ;
corenet_sendrecv_unlabeled_packets(foo_milter_t)
corenet_tcp_connect_mysqld_port(foo_milter_t)
kernel_sendrecv_unlabeled_association(foo_milter_t)
libs_exec_lib_files(foo_milter_t)
sysnet_read_config(foo_milter_t)
To get this working I removed the require lines for foo_milter_t and bar_milter_t as it s not permitted to both define a type and require it in the same module. Then I replaced the set of tcp_socket operations write setopt shutdown read create connect with create_socket_perms as it s easiest to allow all the operations in that set and doesn t give any security risks.
Finally I replaced the mysql lines such as corenet_tcp_connect_mysqld_port(foo_milter_t) with sections such as the following:
mysql_tcp_connect(foo_milter_t)
optional_policy(
mysql_stream_connect(foo_milter_t)
)
This gives it all the access it needs and additionally the optional policy will allow Unix domain socket connections for the case where the mysqld is running on localhost.