Keeping /selinux

Just a very quick paragraph on a just-reported issue: if you upgrade your SELinux utilities to the latest version and you switch from /selinux to /sys/fs/selinux as the mountpoint for the SELinux file system, you might get into issues. Apparently, init (which is responsible for mounting the SELinux file system through a call to libselinux) is trying to mount it on – well yes – /sys/fs/selinux but at that time, /sys is not mounted yet.

I haven’t been able to reproduce just yet, because I just recently had to move all my systems to use an initramfs (thank you you-need-an-initramfs-when-you-have-a-separate-usr-partition) which premounts /sys. But the current workaround should be to keep /selinux for now. The utilities support it still, and that gives me some time to look and investigate the issue.

Posted in Hardened, SELinux | 3 Comments

20120215 policies now stable

Today I’ve stabilized the sec-policy/selinux-* packages that provide the 20120215 “series” of SELinux policies. Together with the stabilization, the more recent userspace tools (like the policycoreutils as well as libraries like libsemanage and libselinux) have been pushed out as well. I will be dropping the older policies and userspace tools soon (as they are now deprecated). The documentation has been updated to reflect this too.

    Some of the enhancements include

  • support for permissive domains (allowing users to mark one specific SELinux domain, such as mplayer_t, as permissive (even though the rest of the system is running in enforcing mode)
  • support for file context translations, so we can now say “/usr/lib64 (and below) should have the same contexts as /usr/lib”
  • support for role attributes, which means for policy developers, we now have similar freedom as with type attributes
  • support for named file transitions, so a policy rule can say that domain A, if creating a file in a directory labeled B, then that specific file should have label C. Same for directories, btw.

Although some of these enhancements were available as features individually, the policies we had were not aligned with it – and now, that has changed ;-)

Posted in Hardened, SELinux | Leave a comment

Linux Sea now in ePub

On request of Matthew Marchese, I now automatically build an ePub version of Linux Sea for those that like to read such resources on a digital reader. Thanks to the use of DocBook, this was simply a matter of using its xsl-stylesheets/epub/docbook.xsl stylesheet against the DocBook sources and zip the created directory structures (OEBPS and META-INF) to get to the ePub file.

Posted in Linux Sea | 1 Comment

Why both chroot and SELinux?

In my previous post, a very valid question was raised by Alexander E. Patrakov: why still use chroot if you have SELinux?

Both chroot (especially with the additional restrictions that grSecurity enables on chroots that make it more difficult to break out of a chroot) and SELinux try to isolate an application so it only has access to those resources it needs. Chroot does this on file-level basis (and a bit more with grSecurity), SELinux on more general resources. However, things that make SELinux strong (flexible and detailed policy language, fine-grained authorizations) are also its weakness (consolidating files into groups having the same file label), and chroot does have an advantage on this.

Suppose that a flaw exists in BIND through which an attacker can read files on the host (through BIND). With SELinux, the domain in which BIND runs is prohibited from accessing and reading files whose label is not one of the labels that the policy thinks BIND should be able to read. More specifically, the BIND policy in the reference policy (which is what both Gentoo and RedHat base their policies on, and generally policies are only enlarged, never really shrinked):

  • etc_runtime_t (read) means access to the files in /etc that are modified at runtime (like mtab, profile.env, gentoo’s /etc/env.d)
  • named_var_run_t (read) is access to /var/run/bind and /var/run/named (and a few other related locations)
  • named_checkconf_exec_t (read/execute) is access to read and execute /usr/sbin/named-checkconf
  • named_conf_t (read) to read the BIND-related configuration files
  • dnssec_t (read) to read the DNSSEC keyfiles
  • locale_t (read) to access /etc/localtime, /usr/share/locale/*, /usr/share/zoneinfo/*
  • etc_t (read) to read the general configuration files in /etc (including passwd, fstab, …)
  • proc_t (read), proc_net_t (read) and sysfs_t (read) to access those pseudo filesystems
  • udev_tbl_t (read) to access /dev/.udev and /var/run/udev (but I have no idea yet why this is in)
  • named_log_t (read/write) for the log files of BIND
  • net_conf_t (read) to access /etc/hosts (including deny/allow), resolv.conf, …
  • named_exec_t (read/execute) the BIND executables
  • named_zone_t (read) to access the zone files, also write access in case of slave system
  • cert_t (read) to read certificate information
  • named_cache_t (read/write) to access its cache
  • named_tmp_t (read/write) to work with temporary files

Isolation provided by SELinux is as powerful as the width of its labeling. For instance, by giving the named daemon read access to /etc files like passwd, fstab, group, hosts, resolv.conf and more, a malicious user who can exploit this hypothetical vulnerability can obtain information that might help him in his further attempts. By chrooting BIND, the files placed in the chroot itself should not offer the information he might be looking for (for instance, the passwd file, if needed at all, is limited to just the named and root accounts, etc.)

Chrooting, but not enabling SELinux, could lead to escalation. A chroot cannot restrict what a process is allowed to do beyond the regular access privileges that are given on the user. If a user can upload an exploit through BIND and have BIND execute it, he can use this as an attack vector for further activities. SELinux here prohibits BIND to write stuff it can also execute (there is no write and execute privilege defined here). It also ensures that the BIND daemon never exists his security domain (transitioning towards another domain with perhaps other privileges) as there are no transition rules from named_t to any other domain.

Another MAC system that would be better suited to fit both is grSecurity’s RBAC model. Iirc, it uses path definitions to say which files are allowed to access and which not. The weakness SELinux here has (aggregation into sets of files with the same label) doesn’t exist for grSecurity. This debate on path-based versus label-based access controls have been going on for very long time now – just google it ;-)

So, Alexander, in short: chroot further limits the SELinux-allowed privileges to a more fine-grained set of file system resources (files/directories).

Posted in Gentoo, Hardened, SELinux | 1 Comment

Chrooted BIND for IPv6 with SELinux

BIND, or Berkeley Internet Name Domain, is one of the Internet’s most popular domain name service software (DNS). It has seen its set of security flaws in the past, which is not that strange as it is such a frequently used service on the Internet. In this post, I’ll give a quick intro on how to use it in Gentoo Hardened (with PaX)… chrooted… for IPv6… with SELinux ;-)

Installing is of course, as usual, dead easy on Gentoo (Hardened/SELinux). Make sure you have USE=”ipv6″ set, and then emerge bind. Also install bind-tools as they contain some great tools to help with DNS troubleshooting. Then we’re editing /etc/conf.d/named to set the CHROOT variable. I also set CHROOT_NOMOUNT so that Gentoo doesn’t bind-mount the information in the chroot but instead uses the files in the chroot.

CHROOT="/var/named/chroot"
CHROOT_NOMOUNT="1"

Now we need to either temporarily add some privileges in SELinux, or run the portage_t domain in permissive mode. If you go for privileges, then add the following:

allow portage_t var_t:chr_file { create getattr setattr };

If you however want to temporarily run the portage_t domain in permissive mode, do that as follows:

~# semanage permissive -a portage_t

We are doing this because we are now going to ask the BIND ebuild to prepare the chroot for us. Doing so however requires portage to work on our live file system (and not in the regular “sandbox” mode). SELinux however forces portage in the portage_t domain and only gives it the privileges it needs for building and installing software.

~# emerge --config bind

When done, remove the previous SELinux allow rules again (or set the portage_t domain back in enforcing mode, through semanage permissive -d portage_t). Next we need to relabel the files in the chroot. By default, all files are labeled by SELinux as var_t in that location because it isn’t aware that it needs to see /var/named/chroot as a “root” location.

~# setfiles -r /var/named/chroot /etc/selinux/strict/contexts/files/file_contexts /var/named/chroot

So far so good. Now let’s create a simple named.conf file (in /var/named/chroot/etc/bind):

options {
  directory "/var/bind";
  pid-file "/var/run/named/named.pid";
  statistics-file "/var/run/named/named.stats";
  listen-on { 127.0.0.1; };
  listen-on-v6 { 2001:db8:81:21::ac:98ad:5fe1; };
  allow-query { any; };
  zone-statistics yes;
  allow-transfer { 2001:db8:81:22::ae:6b01:e3d8; };
  notify yes;
  recursion no;
  version "[nope]";
};

# Access to DNS for local addresses (i.e. genfic-owned)
view "local" {
  match-clients { 2001:db8:81::/48; };
  recursion yes;
  zone "genfic.com" { type master; file "pri/com.genfic"; };
  zone "1.8.0.0.8.b.d.0.1.0.0.2.ip6.arpa" { type master; file "pri/inv.com.genfic"; };
};

The zone files referenced in the configuration file are located in /var/named/chroot/var/bind (in a subdirectory called pri – which I use for “primary”). The regular one would look similar to this:

$TTL 1h ;
$ORIGIN genfic.com.
@       IN      SOA     ns.genfic.com. ns.genfic.com. (
                        2012041101
                        1d
                        2h
                        4w
                        1h )

        IN      NS      ns.genfic.com.
        IN      NS      ns2.genfic.com.
        IN      MX      10      mail.genfic.com.
        IN      MX      20      mail2.genfic.com.

genfic.com.     IN      AAAA    2001:db8:81:80::dd:13ed:c49e;
ns              IN      AAAA    2001:db8:81:21::ac:98ad:5fe1;
ns2             IN      AAAA    2001:db8:81:22::ae:6b01:e3d8;
www             IN      CNAME   genfic.com.;
mail            IN      AAAA    2001:db8:81:21::b0:0738:8ad5;
mail2           IN      AAAA    2001:db8:81:22::50:5e9f:e569;
; (...)

while the one for reverse lookups looks like so:

$TTL 1h ;
@       IN      SOA     1.8.0.0.8.b.d.0.1.0.0.2.ip6.arpa ns.genfic.com. (
                        2012041101
                        1d
                        2h
                        4w
                        1h )

        IN      NS      ns.genfic.com.
        IN      NS      ns2.genfic.com.

$ORIGIN 1.8.0.0.8.b.d.0.1.0.0.2.ip6.arpa.

1.e.f.5.d.a.8.9.c.a.0.0.0.0.0.0.1.2.0.0         IN      PTR     ns.genfic.com.
8.d.3.e.1.0.b.6.e.a.0.0.0.0.0.0.2.2.0.0         IN      PTR     ns2.genfic.com.
; (...)

We can now start the init script:

~# rc-service named start

On the slave, don’t set the allow-transfer directive and set its type to “slave”. In each zone, you will need to tell where the master is:

zone "genfic.com" {
  type slave;
  masters { 2001:db8:81:21::ac:98ad:5fe1; }
  file "sec/com.genfic";
};

By default, the SELinux policy for BIND does not allow BIND to write stuff in its directories. On the slave system, you will need to change this. A SELinux boolean here does the trick:

~# setsebool -P named_write_master_zones on;

There ya go ;-) Okay, all very condensely written, but it should give some feedback on how to proceed. I’m adding this information to the new online resource I’m writing – A Gentoo Linux Advanced Reference Architecture. Nothing really ready yet, just writing as I go forward with exploring these technologies…

Posted in Gentoo, Hardened, SELinux | 1 Comment

Documentation updates for initramfs needed?

A quick help request from the community: if you know of any Gentoo documents that need updates in order for end users to know when and how to use initramfs, please file bugreports and have them block bug #407959. Currently, we have updated the Gentoo Handbook, Gentoo Quickinstall guides and added an Initial ramfs Guide.

The tracker bug is also used to check if and when the eventual roll-out of software can happen, and we want to make sure that we do not forget documentation (something we learned from the openrc migration). Not that the change is as large as was the case with openrc, but it is still nice to have updated documentation in time ;-)

Posted in Gentoo | 2 Comments

Get your devtmpfs ready

If you are using stable profiles, you might want to verify if you are already running a kernel with devtmpfs support enabled. Why? Well, currently you might not need it, but the upcoming openrc/udev packages require it and they currently do not fail at install time if you have it enabled or not. As a result, upgrading these packages might give you a system that might fail to boot (if you have no initramfs but separate /usr partition) or gives many errors (if you have an initramfs).

To verify if it is enabled, check your kernel configuration:


# zgrep DEVTMPFS /proc/config.gz
# CONFIG_DEVTMPFS is not set

If you get the output as described above, best update your kernel configuration to include it. The second devtmpfs-related option (to automatically mount it on /dev) is not needed afaik.

And for those that have been with Gentoo for a while – devtmpfs is not devfs. Well, it is. But it isn’t. Somewhat. Oh well, there’s discussion on that which I’m not going to elaborate on. Safe to say that we’re getting older if we start feeling “Been there, done that, got the t-shirt” ;-)

Edit: as Robin mentioned in the comments, the udev ebuild does check at it. However, it doesn’t fail an installation so you could miss the message. Apologies for the lies, Robin ;-) Post updated.

Posted in Gentoo | 8 Comments

More on initramfs and SELinux

With the upcoming udev version not supporting separate /usr locations unless you boot with an initramfs, we are now starting to document how to create an initramfs to boot with. After all, systems with a separate /usr are not that uncommon.

As I’ve blogged about before, getting an initramfs to work well with SELinux has not been an easy drift. In effect, I’m going to push out the FAQ (the Gentoo wiki already has it) that the user will need to boot in permissive mode, and have an init script in the boot runlevel that will reset the contexts of /dev and then switch to enforcing mode. And those that want to make sure SELinux stays on can then also enable the secure_mode_policyload SELinux boolean so that you cannot go back to permissive mode (without rebooting).

For those interested, this is the init script I use on my guest systems (which are for development purposes, so they do not toggle the SELinux boolean):


#!/sbin/runscript
# Copyright (c) 2007-2009 Roy Marples
# Released under the 2-clause BSD license.

description="Switch into SELinux enforcing mode"

depend()
{
need localmount
}

start()
{
ebegin "Restoring file contexts in /dev"
restorecon -R /dev
eend 0

ebegin "Switching to enforcing mode"
setenforce 1
eend $?
}

I call it selinux_enforce for a lack of imagination (and to make it more clear, because if I’d name it “wookie” I’ll be scratching my head in a few weeks trying to figure out why I did that in the first place).

With that enabled, I cannot provide a “denial-free” boot-up anymore (you’ll see many denials from the init_t domain, amongst others, which are best not hidden). That is to say, until I take some time to patch the initramfs to handle SELinux.

Oh, btw, this is for both dracut-generated as well as genkernel-generated initramfs’s. At least the technologies are consistent there.

Posted in Hardened, SELinux | 3 Comments

Hunting fuser

I am able to work on Gentoo and SELinux about one hour per day. It’s more in total time, but being a bit exhausted makes me act a bit more slowly which boils down to about one hour per day. And one hour per day isn’t bad, you’re able to do many things in that hour.

The last few days, I’ve been hunting SELinux denials. I’ve set my mind onto releasing the 2.20120215-r5 policy only when I’ve been able to boot a minimalistic Gentoo installation without any visible denials, so either dontaudit them or fix them. Of course, I only want to allow if I’m absolutely confident that they are needed on some systems, but I also only want to dontaudit when I understand what it is doing (and find that it isn’t something needed).

Some of the denials are driving me up the walls, often having an entire evening hunting for a single one… and this is why you haven’t seen many updates since a week or so. The one I’m hunting now, is shown in the logs as follows:

Mar 12 20:21:32 testsys kernel: [    6.550618] type=1400 audit(1331580090.874:4): avc:  denied  { getattr }
  for  pid=1512 comm="fuser" path="socket:[3159]" dev=sockfs ino=3159
  scontext=system_u:system_r:initrc_t tcontext=system_u:system_r:udev_t tclass=unix_stream_socket
Mar 12 20:21:32 testsys kernel: [    6.551232] type=1400 audit(1331580090.875:5): avc:  denied  { getattr }
  for  pid=1513 comm="fuser" path="socket:[3160]" dev=sockfs ino=3160
  scontext=system_u:system_r:initrc_t tcontext=system_u:system_r:udev_t tclass=netlink_kobject_uevent_socket
Mar 12 20:21:32 testsys kernel: [    6.562005] type=1400 audit(1331580090.885:6): avc:  denied  { getattr }
  for  pid=1530 comm="fuser" path="socket:[3705]" dev=sockfs ino=3705
  scontext=system_u:system_r:initrc_t tcontext=system_u:system_r:udev_t tclass=netlink_kobject_uevent_socket
... (these netlink_kobject_uevent_socket ones are repeated a few times)

I have no idea who (or what) is executing fuser to find some information. The shown PIDs are those of fuser, and of course that isn’t running anymore when the system is booted. The timeframe shown also doesn’t seem to provide much information, because it is the time that it is logged by the system logger apparently (I once hoped I was wrong here, but repeated tests and introducing delays and such seems to confirm it). And because the target is on dev=sockfs, it’s hardly something I’m able to actively search for.

Or at least that I know of.

The source context is initrc_t, so it is started from an init script. And the target is always udev_t, so it might be triggered by the udev (or a udev-related) init script (as it seems to only look for these of udev, but that might be a coincidence). But alas, I still don’t know what is calling it as I can’t find a script or udev rule that calls fuser :-( It doesn’t affect the runtime behavior of my system (everything seems to work just fine) so I might go on and dontaudit it. But I so want to know what this is about.

To be continued…

Posted in Hardened, SELinux | 8 Comments

Introducing 2.20120215 policies

A few weeks after being released, we now have the 20120215-based policies available for our users (and also the newer userspace utilities). The packages currently reside in the hardened-dev overlay as they will need to see sufficient testing before we merge those to the main tree. For most users, nothing changes, albeit there are a few changes under the hood that you might get in contact with later…

The selinux-base-policy package now depends on a new package called selinux-base. This is the “real” base policy package, and now only includes those modules that upstream (reference policy) marks as being base modules. The rest of the modules that we (Gentoo) originally included in base are now built by the selinux-base-policy package and inserted in the policy store together with the base policy. This change is done to make future development a bit more flexible, but also because the policy build fails when we include too many packages.

The selinux-unconfined package loads in the unconfined module. Users that know the difference between the strict and targeted policy types: loading the unconfined module in a “strict” policy will make the system support domains like in “targeted” mode. Currently, there is little use in this module as we (err, I) still need to get this in a good shape. This change is needed to support unconfined domains later when we work with MCS or MLS. The older definitions (using targeted or strict) remain supported though.

The pesky change we had to do to /lib64/rcscripts/addons/lvm-st{art,op}.sh is not necessary anymore. This has nothing to do with the tools, but more with an update on the policy itself. I have to give you some reason to upgrade, don’t I ;-)

Now that the new policy is in, we can start using named transitions as well as use translations so that our file contexts aren’t cluttered with all those /lib64 + /lib definitions. These changes will go in later.

For those interested in helping, please give these policies thorough testing. I had some work in “forward-porting” the patches we had that weren’t included upstream yet because of changes in the underlying structure. I hope none are forgotten. If you do find regressions, either ping me on IRC or file a bugreport.

Posted in Hardened, SELinux | Leave a comment