Joshua Brindle

How to Win At Security

SELinux on Ubuntu (part 1)

I'm in the process of moving my server from an ancient decrepit Gentoo install to a shiny new Ubuntu Hardy install with SELinux enabled.

The policy installed with Ubuntu is fairly limited. It is a very small base policy with a cups module available. This was the result of Ubuntu politics but obviously I wanted something more comprehensive. The first thing I did was grab the reference policy from oss.tresys.com and try to figure out what policies I wanted installed. Reference policy has 259 modules and I didn't want all of them. 

I took the Gentoo policy ebuild to start, since it is a much smaller policy than Fedora has and I added modules for the services I was going to run. The result (for now) is this:

application = base
authlogin = base
bootloader = base
clock = base
consoletype = base
corecommands = base
corenetwork = base
cron = base
devices = base
dmesg = base
domain = base
files = base
filesystem = base
fstools = base
getty = base
hostname = base
hotplug = base
init = base
iptables = base
kernel = base
libraries = base
locallogin = base
logging = base
miscfiles = base
mls = base
mcs = base
modutils = base
mount = base
mta = base
netutils = base
nscd = base
raid = base
selinux = base
selinuxutil = base
ssh = base
staff = base
storage = base
su = base
sysadm = base
sysnetwork = base
terminal = base
udev = base
unconfined = base
userdomain = base
usermanage = base
unprivuser = base
 
dovecot = module
postfix = module
bind = module
mysql = module
apache = module
dpkg = module
spamassassin = module
ntp = module

 

This is a relatively small policy, yeilding a 500k policy.23. 

Then I ran in to my first problem. The SELinux libraries installed on Hardy won't build the most recent reference policy due to a bug that was fixed after Ubuntu's libraries were built. So I had to upgrade my libraries and policy compiler. Since I normally develop on Fedora I assumed I could grab some sort of source deb, update the code and rebuild it. I couldn't figure out how to do that though, all of the source pointers go to the developers repository which looked just like the upstream source. I have no idea how to build debs so I gave up and just built from the selinux userspace git tree. 

After getting a toolchain I could build the policy on and building and installing the policy I relabeled the filesystem and tried rebooting. Thats when the second problem happened. I couldn't log in via ssh (doh!) and the server is located alot of miles away (like 1000 or something). Good thing the machine has a remote administration console. So I logged in via that and took a look at ps -AZ to see what was going on (I was certain that ssh was running in the wrong context and that is why I couldn't log in, even in permissive). Everything was running in sysadm_t !?! This was pretty baffling to me, I did some sesearch's on the policy (btw, the setools package pulls in the whole thing which requires gtk, tcl, tk, whatever.. too bad there isn't a setools-console package). Well it turns out that if the upstart_init boolean isn't set to true then initrc_t transitions to sysadm_t on shell_exec_t, I have no clue why, very strange. Set the boolean and everything looks good (yay).

Now everything is up and running in the right context (well, mostly everything, mysqld_safe, logger and dd (run for klogd apparently) are running in initrc_t, which is effectively unconfined) I'll work on those later.

Right now I'm getting tons of denials, most are related to having a tmpfs /var/run I think, also udev is doing all sorts of crazy things (but then again doesn't it always). Hopefully I'll get these taken care of and I'll write another article about the success (assuming I succeed and don't give up :D )