On Tue, 2006-11-28 at 13:58 -0600, Jason L Tibbitts III wrote:
I would like to revisit the issue of denyhosts and selinux and
address
it properly. From what I gather from the earlier discussion, it would
be best to write a proper policy for denyhosts. Unfortunately, I'm
almost completely ignorant of what needs to happen here.
Here's some essential info about denyhosts:
Denyhosts is written in python. It runs as root either as a daemon or
spawned from cron. It consists of an executable script
(/usr/bin/denyhosts.py), some python modules in
/usr/lib/python2.4/site-packages/DenyHosts, a config file
(/etc/denyhosts.conf), and some databases under /var/lib/denyhosts.
During its operation it reads /var/log/secure, maintains databases and
such under /var/lib/denyhosts, and writes to /etc/hosts.deny.
The delicate issue there is that other programs read /etc/hosts.deny, so
if we move it into its own type (so that we only have to allow denyhosts
to write to it and not other files in /etc), then we have to adjust any
other domains that need to read the new type. An intermediate point is
to push it into etc_runtime_t, a generic type used for runtime generated
or modified etc files.
It may
also make some xmlrpc calls out over the 'net if so configured
(although by default this is not the case).
So network access could be under a boolean.
One complication is that denyhosts can call out to user-supplied
scripts which can do pretty much anything. I've no idea how to
properly handle that kind of thing.
User-supplied or admin-supplied? The scripts should run with the full
privileges of denyhosts or with a reduced subset?
Could someone perhaps help me to get started with a policy?
Most people start with an existing module from the policy sources
(.src.rpm or upstream tarball) and work from it, or
use /usr/share/selinux/devel/policygentool (from selinux-policy-devel)
to create an initial stub. Or use SLIDE and its module building wizard
if you are into Eclipse.
You need to create a .te file with the policy declarations and rules,
a .fc file with the file contexts, and an .if file with an interfaces
the policy module exports to others (e.g. to access the /etc/hosts.deny
file if you put it into a private type, or to transition into the
denyhosts domain from a caller).
Incomplete samples below, no guarantees on correctness...
denyhosts.te:
policy_module(denyhosts, 1.0.0)
##############
#
# Declarations
#
type denyhosts_t; # type for the running process
type denyhosts_exec_t; # type for the executable on disk
init_daemon_domain(denyhosts_t, denyhosts_exec_t) # runs as a daemon
cron_system_entry(denyhosts_t, denyhosts_exec_t) # and as a cron job
type denyhosts_conf_t;
files_config_file(denyhosts_conf_t)
type denyhosts_var_run_t;
files_pid_file(denyhosts_var_run_t)
type denyhosts_var_lib_t;
files_type(denyhosts_var_lib_t)
###########################
#
# Local policy
#
allow denyhosts_t denyhosts_conf_t:file r_file_perms;
files_search_etc(denyhosts_t)
allow denyhosts_t denyhosts_var_run_t:file create_file_perms;
allow denyhosts_t denyhosts_var_run_t:dir rw_dir_perms;
files_pid_filetrans(denyhosts_t,denyhosts_var_run_t,file)
allow denyhosts_t denyhosts_var_lib_t:dir rw_dir_perms;
allow denyhosts_t denyhosts_var_lib_t:file create_file_perms;
files_var_lib_filetrans(denyhosts_t,denyhosts_var_lib_t,file)
corecmd_exec_bin(denyhosts_t)
corecmd_exec_shell(denyhosts_t)
corecmd_search_sbin(denyhosts_t)
files_read_usr_files(denyhosts_t)
files_read_etc_files(denyhosts_t)
files_read_etc_runtime_files(denyhosts_t)
denyhosts.fc:
/usr/bin/denyhosts.py -- gen_context(system_u:object_r:denyhosts_exec_t,s0)
/etc/denyhosts.conf -- gen_context(system_u:object_r:denyhosts_conf_t,s0)
/var/lib/denyhosts(/.*)? gen_context(system_u:object_r:denyhosts_var_lib_t,s0)
--
Stephen Smalley
National Security Agency