+
Gentoo Hardened SELinux Development
+
+=
1.
+ Introduction
+About this document...=
+
+Dealing with Mandatory Access Control is never easy. SELinux might be av=
ailable
+by default with Linux, enabling it can provide serious headaches - let a=
lone
+developing policies for it. Within Gentoo Hardened, we strive to offer a=
default
+policy that is flexible enough to match the requirements of most of you =
(our=20
+users) yet remain manageable by the limited number of developers that we=
have.
+To ensure that the policy we offer is up to date, we definitely need hel=
p from
+end users and other developers, because developing policies requires int=
imate=20
+knowledge of the products they are written for. With over several thousa=
nd=20
+packages, this is just not feasible for a handful of us. Hence, this Gen=
too
+Hardened SELinux Development guide.
+
+
+Within this document, we will try to explain how to set up an environmen=
t ready
+to build policies yourself and provide patches to Gentoo Hardened. We al=
so cover
+how to deal with malfunctioning domains and even how to create your own,=
new=20
+domains from scratch (if we need to). Further down, we give an overview =
of the=20
+guidelines that we try to follow during the policy developments and fina=
lly
+talk about how to properly create patches and submit them to our bugzilla service.
+
+
+For those who want to run Gentoo Hardened with their own policies, we've=
also
+added a chapter on just that. We know that our policy does not match eve=
ryone's
+requirements, so we definitely want to help you run your own too.
+
+Intended audience<=
/p>
+
+This document is a must-read for everyone willing to provide patches or =
develop
+the Gentoo Hardened SELinux policies.
+
+
+Other SELinux advanced users might find this document interesting as wel=
l.
+
+What you need to know<=
/a>
+
+This document does assume prior knowledge on SELinux policies and the wa=
y the
+reference policy works. For those that need a quick recap, here are the
+highlights...
+
+
+ -
+ SELinux uses domains and types to differentiate its various
+ security objects. A domain is usually referred to as the security co=
ntext
+ of a process (or group of processes) whereas a type is usually refer=
red to
+ as the label given to a particular resource (file, directory, networ=
k
+ interface, socket, network port, ...).
+
+ -
+ SELinux policies describe what inter=
action is allowed between a
+ domain and the other domains and types it needs to work with. If no =
policy
+ allows for a particular activity, then the activity is denied.
+
+ -
+ The structure in which policies are written are called SELinux policy
+ modules which contain three parts: a type enforcement file (with
+ suffix .te) that contains th=
e intra-module permissions, an
+ interface file (with suffix .if) that contains the
+ inter-module permissions and a file context=
s file (with suffix
+ .fc) that contains the file =
context definitions for all file
+ resources that are labeled with the type or types defined in the mod=
ule
+
+ -
+ Inter-domain privileges must be declared through functions in the
+ interface file which can then be cal=
led by other modules. This
+ includes the necessary permissions to allow domain transitions
+
+
+=
2.
+ Setting Up Your Environment
+Patching the reference=
policy
+
+Gentoo Hardened builds its policy upon the reference policy as
+provided by Tresys and managed thr=
ough
+an active community.
+I suggest to use two workspaces when dealing with SELinux policies for G=
entoo
+Hardened: the hardened one for t=
he Gentoo patched policy, and a=20
+local one in which you work and =
make your patches in.
+
+
+Of course, using a source control system like git can be helpful too. Fo=
r now,
+Gentoo Hardened doesn't have a git repository where its policies are bas=
ed from
+(yet). That might sound a bit dull, but it forces the developers to rema=
in as
+close to upstream as possible (and contribute the changes upstream too s=
o that
+newer releases include them automatically). You can definitely use a sou=
rce
+control system yourself - the only reason we do not use it in this docum=
ent is
+that it is easier to document without ;-)
+
+
+Let's create the first workspace:
+
+
+Code Listing2.1: Crea=
ting the SELinux policy workspace |
+
+~$ mkdir dev/hardened
+~$ cd dev/hardened
+~$ ebuild /usr/portage/sec-policy/selinux-bas=
e-policy/selinux-base-policy-2.20101213-r12.ebuild compile
+~$ cp -r /var/tmp/portage/sec-policy/selinux-=
base-policy-2.20101213-r12/work/* .
+~$ rm -rf /var/tmp/portage/sec-policy/selinux=
-base-policy-2.20101213-r12
+ |
+
+
+As result, you should have two or three directories in=20
+dev/hardened called refpolicy and =
strict
+and/or targeted. The only one of=
interest is the
+strict and/or targeted one, depending on the policy
+type you are working with. In the remainder of the document, I'm assumin=
g you
+work with strict.
+
+
+Now the dev/hardened workspace i=
s patched with the Gentoo Hardened
+SELinux patches applicable to the base policy. Gentoo Hardened has two "=
flavors"
+of patches:
+
+
+ -
+ Base policy patches contain the patc=
hes for the SELinux modules that
+ take part of the base policy as well as all interface patches for th=
e
+ modules
+
+ -
+ Module-specific patches that contain=
the permissions affecting the
+ domains and types that are defined in a single module (for instance,=
all
+ interaction between portage_t and portage_exec_t
+ or even portage_t and portage_fetch_t)
+
+
+
+The base policy patches are important to have available at all times. Th=
e
+module-specific ones can be added when you work with that particular mod=
ule.
+
+
+Every time a new revision comes out, you'll need to clean the
+dev/hardened workspace and rebui=
ld it.
+
+Add specific module fi=
les
+
+To update your policy workspace, use the same tactic as describes
+earlier, but now for the specific SELinux policy module package (like
+selinux-postfix).
+
+
+Code Listing2.2: Upda=
ting the dev/hardened workspace |
+
+~$ ls dev/hardened/strict/policy/modules/*/po=
stfix.te
+dev/hardened/strict/policy/modules/services/postfix.te
+
+~$ ebuild /usr/portage/sec-policy/selinux-pos=
tfix/selinux-postfix-2.20101213-r3.ebuild compile
+
+
+~$ cp /var/tmp/portage/sec-policy/selinux-pos=
tfix-2.20101213-r12/work/strict/postfix.te \
+ dev/hardened/strict/policy/modules/services/
+
+~$ cp /var/tmp/portage/sec-policy/selinux-pos=
tfix-2.20101213-r12/work/strict/postfix.fc \
+ dev/hardened/strict/policy/modules/services/
+
+~$ rm -rf /var/tmp/portage/sec-policy/selinux=
-postfix-2.20101213-r12
+ |
+
+
+Finally, clean up the workspace (as it contains built policies and other
+material we do not want to see in our patches)
+
+
+Code Listing2.3: Clea=
ning up the workspace |
+
+~$ cd dev/hardened/strict
+~$ make clean
+ |
+
+Setting up a local wor=
kspace
+
+Setting up a local workspace is easy: just copy the dev/hardened
+one:
+
+
+Code Listing2.4: Sett=
ing up a local workspace |
+
+~$ mkdir dev/local
+~$ cp -r dev/hardened/strict dev/local/
+ |
+
+Navigating the policy =
workspace
+
+The main location you will work with is
+dev/local/strict/policy/modules.=
This location is subdivided in
+categories:
+
+
+ - admin
+ - Administrative SELinux policy modules (portage, logrotate, sudo, .=
..)
+ - apps
+ - Application SELinux policy modules (evolution, mozilla, screen, ..=
.)
+ - kernel
+ - Kernel specific SELinux policy domains (corenetwork, kernel, ...)<=
/dd>
+
- roles
+ - Domains specific to SELinux roles (sysadm, user, staff, ...)
+ - services
+ - Daemon SELinux policy modules (postfix, apache, squid, ...)
+ - system
+ - Core SELinux policy modules (selinuxutil, mount, iptables, ...)
+
+
+The categorization is arbitrary and serves no purpose other than keeping=
the
+modules a but separated. Each module must have a unique name, regardless=
of the
+category!
+
+
+Inside the categories, the modules are available using their three files
+
+
+Code Listing2.5: List=
ing the available sudo files |
+
+~$ cd dev/local/strict/policy/modules/admin=
span>
+~$ ls sudo.*
+sudo.fc sudo.if sudo.te
+ |
+
+Building a module<=
/p>
+
+To build a module, go to the location where the module code is. Then, ru=
n
+make with the development Makefi=
le as provided by the reference policy.
+
+
+Code Listing2.6: Buil=
ding the portage module |
+
+~$ cd dev/local/strict/policy/modules/admin=
span>
+~$ make -f ../../../support/Makefile.devel po=
rtage.pp
+ |
+
+
+You now have a portage.pp file a=
vailable which you can load (using
+semodule -i portage.pp).
+
+Building the base poli=
cy
+
+If you want to build the base policy, run make base.
+
+
+Code Listing2.7: Buil=
ding the base policy |
+
+~$ cd dev/local/strict
+~$ make base
+ |
+
+
+The result should be a base.pp f=
ile that you can load using
+semodule -b base.pp. However, if=
you intend to do a bit more than just
+test this base policy quickly, it is seriously recommended to create you=
r own
+Gentoo overlay for your own selinux-bas=
e-policy and install that
+one as installing a base policy is not only about the policy module itse=
lf, but
+also about the include files that will then be stored in
+/usr/share/selinux/strict/include.
+
+=
3.
+ A Domain Does Not Function Properly
+Introduction
+
+The most likely problem that you are hitting is that a domain does exist=
in
+Gentoo Hardened SELinux, but that it isn't functioning as it should. To =
solve
+this problem, it is adviseable to use the following sequence of investig=
ations:
+
+
+ -
+ Is it really SELinux that is restraining your system?
+
+ -
+ Is the problem related to wrong resource labels / security contexts?
+
+ -
+ Is the problem related to intra-module permissions?
+
+ -
+ Is the problem related to inter-module permissions?
+
+
+Check if SELinux is to=
blame
+
+Make sure that the problem you are seeing is a SELinux-triggered problem=
. An
+easy way to find out is to run SELinux in permissive mode and try again:
+
+
+Code Listing3.1: Swit=
ching to permissive mode |
+
+~# setenforce 0
+ |
+
+
+This only works if the problem is not to=
do with a SELinux-aware
+application (unlike init or sudo which are linked to the
+libselinux library). SELinux-aware applications might alter their behavi=
or if
+SELinux is set on the system regardless of it running in permissive mode=
or not.
+A prime example is vixie-cron (a=
s can be seen in bug #257111). But
+for applications that are not SELinux aware, this is the easiest method =
to find
+out if SELinux is to blame or not.
+
+
+If running your system in permissive mode works around the problem, read=
on. If
+it doesn't, check the regular permissions (strace'ing the application
+might be a good idea too).
+
+Get the proper AVC den=
ials
+
+Assuming that we now know that SELinux is to blame, we need to make sure=
that we
+get the proper AVC denials. Either locate the proper denials in
+/var/log/avc.log (or audit.log) around the time that
+you encountered the issue, or run tail =
-f /var/log/avc.log and reproduce
+the problem.
+
+
+Code Listing3.2: Exam=
ple denials |
+
+~# tail -f /var/log/avc.log
+Apr 22 15:03:33 www1 kernel: [16053.303739] type=3D1400 audit(1303477413=
.188:283):
+avc: denied { dac_read_search } for pid=3D21758 comm=3D"rm" capabilit=
y=3D2
+scontext=3Droot:sysadm_r:portage_t tcontext=3Droot:sysadm_r:portage_t
+tclass=3Dcapability
+ |
+
+
+Analyzing the meaning of the AVC denial is covered by Looking
+at the AVC Log in the Gentoo Hardened SELinux handbook. The denial s=
hould
+give you a pointer where to look for. However, it is possible that no de=
nial is
+occurring, or at least no relevant ones.
+
+
+A first step to get potentially more denials is to switch the
+gentoo_try_dontaudit boolean off=
. This boolean is used by the Gentoo
+Hardened SELinux developers to hide denials which they assume are cosmet=
ic. As
+these developers are known to have a human side (as well), they are know=
n to
+make mistakes ;-)
+
+
+Code Listing3.3: Disa=
bling gentoo's dontaudit statements |
+
+~# setsebool gentoo_try_dontaudit off
+ |
+
+
+Retry getting the proper AVC denials.
+
+
+If it still doesn't work, you can disable all d=
ontaudit statements:
+
+
+Code Listing3.4: Disa=
bling all dontaudit statements |
+
+~# semodule -R -D -B
+ |
+
+
+Retry getting the proper AVC denials.
+
+
+The moment you get the denials you are looking for, isolate them and the=
n undo
+the changes you made earlier:
+
+
+Code Listing3.5: Rese=
tting the auditing defaults |
+
+~# setsebool gentoo_try_dontaudit on
+~# semodule -R -B
+ |
+
+
+If you still do not see any denials, then check out the dmesg output for
+other problems. It is possible that SELinux is not even getting to the p=
oint of
+the policy, which you will not notice by looking at the AVC denials alon=
e.
+However, the chance of this to happen is very slim - most of the time, y=
ou'll
+find the AVC denials you are looking for.
+
+Deducing the correct s=
ecurity contexts
+
+The next step is to see if we are dealing with the right security contex=
ts. This
+does require a bit of insight in how both the application (that is faili=
ng) and
+the policy relate to each other.
+
+
+Say you are having issues with SELinux (re)labeling and you notice the f=
ollowing
+AVC denial:
+
+
+Code Listing3.6: AVC =
denial for setfiles |
+
+Apr 16 14:39:57 testsys kernel: [ 115.778484] type=3D1400
+audit(1302957597.827:224): avc: denied { create } for pid=3D3584
+comm=3D"setfiles" scontext=3Droot:sysadm_r: tcontext=3Droot:sysadm_r:sysadm_t
+tclass=3Dnetlink_audit_socket
+ |
+
+
+In this case, setfiles is runnin=
g in the sysadm_t domain
+even though it should run in setfiles_t=
. So check the security
+context of the setfiles binary a=
s well as the transition rules:
+
+
+Code Listing3.7: Chec=
king setfiles context and rules |
+
+~# ls -lZ /sbin/setfiles
+-rwxr-xr-x. 1 root root 26464 Apr 9 22:22 /sbin/setfiles
+~# sesearch -s sysadm_t -t setfiles_t -c proc=
ess -p transition -A -d
+Found 1 semantic av rules:
+ allow sysadm_t setfiles_t : process transition ;
+~# sesearch -s sysadm_t -t setfiles_exec_t -c=
file -p execute -A -d
+...
+~# sesearch -s setfiles_t -t setfiles_exec_t =
-c file -p entrypoint -A -d
+...
+ |
+
+
+In the above (forced) situation, the problem is with the security contex=
t of the
+binary - it should have been setfiles_e=
xec_t instead of
+bin_t. Usually, entry points are=
named similarly (like
+portage_exec_t or sudo_exec_t). If you are not certain
+about which domain it should be, use se=
search
+
+
+Code Listing3.8: Usin=
g sesearch to find the entrypoint type for a domain |
+
+~# sesearch -s setfiles_t -c file -p entrypoi=
nt -A -d
+Found 1 semantic av rules:
+ allow setfiles_t setfiles_exec_t : file { ioctl ... execute entrypoin=
t open } ;
+ |
+
+
+The sesearch utility is extremel=
y powerful to query the SELinux policy
+(which is currently in memory). I also advise you to use the -C switch to
+see which rules are trigged by certain SELinux booleans:
+
+
+Code Listing3.9: Look=
ing for boolean-triggered settings |
+
+~# sesearch -s named_t -t named_zone_t -c fil=
e -A -d -C
+Found 2 semantic av rules:
+ allow named_t named_zone_t : file { ioctl read getattr lock open } ;=20
+DT allow named_t named_zone_t : file { ioctl read write create getattr s=
etattr lock append unlink link rename open } ; [ named_write_master_zones=
]
+ |
+
+
+In the above example, the named_t domain only has write privileges
+on files labeled named_zone_t if=
the
+named_write_master_zones boolean=
is set (which it currently isn't,
+otherwise the line would stat with ET instead of DT).
+
+
+To gain a bit of insight in the various, available domains, use seinfo:
+
+
+Code Listing3.10: Get=
ting a list of available domains |
+
+~# seinfo -t | grep named
+ named_var_run_t
+ named_checkconf_exec_t
+ named_conf_t
+ named_initrc_exec_t
+ named_log_t
+ named_exec_t
+ named_zone_t
+ named_t
+ named_cache_t
+ named_tmp_t
+ |
+
+
+To gain a bit of insight in the (current) file context rules, use
+semanage:
+
+
+Code Listing3.11: Get=
ting the list of current file context rules |
+
+~# semanage fcontext -l | grep named
+/etc/bind(/.*)? all files syst=
em_u:object_r:named_zone_t=20
+/etc/bind/named\.conf regular file syst=
em_u:object_r:named_conf_t=20
+/etc/rc\.d/init\.d/named regular file syst=
em_u:object_r:named_initrc_exec_t=20
+/etc/rc\.d/init\.d/unbound regular file syst=
em_u:object_r:named_initrc_exec_t=20
+/etc/rndc.* regular file syst=
em_u:object_r:named_conf_t=20
+/etc/unbound(/.*)? all files syst=
em_u:object_r:named_conf_t=20
+/usr/sbin/lwresd regular file syst=
em_u:object_r:named_exec_t=20
+/usr/sbin/named regular file syst=
em_u:object_r:named_exec_t=20
+/usr/sbin/named-checkconf regular file syst=
em_u:object_r:named_checkconf_exec_t=20
+/usr/sbin/unbound regular file syst=
em_u:object_r:named_exec_t=20
+/var/bind(/.*)? all files syst=
em_u:object_r:named_cache_t=20
+/var/bind/pri(/.*)? all files syst=
em_u:object_r:named_zone_t=20
+/var/log/named.* regular file syst=
em_u:object_r:named_log_t=20
+/var/run/bind(/.*)? all files syst=
em_u:object_r:named_var_run_t=20
+/var/run/named(/.*)? all files syst=
em_u:object_r:named_var_run_t=20
+/var/run/ndc socket syst=
em_u:object_r:named_var_run_t=20
+/var/run/unbound(/.*)? all files syst=
em_u:object_r:named_var_run_t=20
+ |
+
+
+Most of the time, fixing domain issues is a matter of relabeling files (=
or
+updating the configuration to match the contexts already defined - both =
work).
+
+Intra-module permissio=
ns are missing
+
+It is possible that you get a denial between correct security contexts, =
but
+that the permission is just never granted. In this case, you can choose =
between
+two things:
+
+
+ -
+ Enhance the module so that the particular permission is granted, or
+
+ -
+ Enhance the module with an additional type where the permission is g=
ranted,
+ and assign this type/label to the related resources
+
+
+
+In both cases you will need to edit the module files (most likely the
+.te file), build the module, loa=
d it, perhaps even relabel the
+files or the package and retry. It is also a good idea to take a look at
+upstream (latest refpolicy repository or the repositories of Fedora and =
co) and
+see if they have already solved this problem or not.
+
+
+Granting additional permissions between existing domains is the easiest,=
but
+might introduce additional problems: if this permission is only needed i=
n a
+particular case yet you grant it for all files and resources related to =
those
+domains, then you are opening up the policy beyond what is necessary. Of=
ten,
+creating an additional domain or type can be beneficial.
+
+
+A noticeable example is Portage' support for CVS/SVN/GIT ebuilds (the so=
-called
+live ebuilds). These ebuilds get their repository and store it in the
+distfiles/svn+src location, whic=
h was by default labelled
+portage_ebuild_t with only read-=
access for the
+portage_sandbox_t domain. Howeve=
r, with those live ebuilds, the
+portage_sandbox_t domain also ne=
eds write privileges to this
+location. Rather than allowing portage_=
sandbox_t write privileges
+to portage_ebuild_t, a new type =
was created called
+portage_svnsrc_t for just this l=
ocation and the rights are
+transferred towards type.
+
+Inter-module permissio=
ns are needed
+
+If the solution for the problem requires permissions between modules, th=
en you
+need to create the proper interface functions in the target domain and c=
all
+these functions from the source domain.
+
+
+TODO extend this explanation, use a common example, like mysql_stream_co=
nnect in
+postfix.
+
+
+TODO explain that changes in the interface require rebuilds and reinstal=
lations
+of the base (package, not only .pp file, due to includes). tell that thi=
s is the
+reason why selinux-base-policy has that many revisions.
+
+=
4.
+ No Domain Exists (Yet)
+Reuse existing domains=
+
+TODO talk about potentially reusing domains (like apache module providin=
g the
+various httpd_* domains which can be reused by lighttpd). Talk about ass=
igning
+the proper labels to the files to see if that is sufficient.
+
+Copy from existing dom=
ains
+
+TODO talk about finding a similar module (apps or service) and start fro=
m a
+(slimmed-down) domain. Not recommended as it might already open too much=
, but it
+is a good start, if not to just look at with every denial you get later.=
Keep it
+short, most information is in next section.
+
+Starting from scratch<=
/a>
+
+TODO talk about defining the proper domains, set proper types (like file=
_type or
+application_type), refer to refpolicy guidelines
+
+Testing new modules
+
+TODO talk about users trying to do maximum testing (all the way). Also, =
if they
+want to support unconfined domains too, how they can do this (and should=
test).
+
+=
5.
+ Policy Guidelines
+
+TODO dealing with cosmetic denials
+
+
+TODO resources - gentoo selinux policy, refpolicy guidelines
+
+=
6.
+ Submitting Patches
+
+TODO differentiate between base patch and module patch.
+
+
+TODO perhaps talk about file context patches. Perhaps we will not make a=
new
+build release for it, but stage it to be included in the next release wh=
en a
+non-filecontext patch is added?
+
+=
7.
+ Running Your Own Policy
+
+TODO describe how to create your own overlay with modules and patchbundl=
es. Also
+usable for developers to stage their ebuild / patch submissions before a=
ctually
+putting in git repo. Ensure that naming is consistent (so that ebuild
+dependencies of packages remain).
+
+
+TODO describe how to exclude sec-policy in regular rsync
+
+
+ The contents of this document are licensed under the Creative Commons -
+ Attribution / Share Alike license.
+
+
+ |
+