Enable SELinux on Xen guest running Debian Wheezy

This post describes how to get SELinux running on a Xen guest (domU) that is running Debian Wheezy.

First, you need a guest that is booted by pvgrub and running a distro-supplied kernel ie, a regular (non-Xen) linux image. All that is convered in my previous post on booting unprivileged domains in Xen with pvgrub on Debian Wheezy. This is a required step.

Next we’ll follow Debian’s own SELinux set up, mostly.

You need to install some packages, but I left out some dependencies in particular that I didn’t want so I used –no-install-recommends.

apt-get –no-install-recommends install selinux-basics selinux-policy-default auditd audispd-plugins

In /etc/default/rcS change

set FSCKFIX=yes

I ran selinux-activate, but it doesn’t do what it is supposed to do. So you have to fix these issues by hand.

Add kernel options to enable SELinux in /boot/grub/menu.lst, mine looks like this:

kernel /vmlinuz root=/dev/xvda1 ro selinux=1 security=selinux

Fix pam by adding to /etc/pam.d/login

session required pam_selinux.so multiple

Touch /.autorelabel

Restart the guest. I use xm create -c /path/to/guest/config so I get the console and can watch for relabelling to occur. After relabelling the system should reboot, but it doesn’t. It shuts down and doesn’t come back up. So I xm create -c /path/to/guest/config again. Once I logged in to the guest I ran sestatus and got

SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: default
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: denied
Max kernel policy version: 26

The main issues with Debian’s own SELinux how-to are 1) selinux-activate does not do what it is supposed to in Wheezy 2) we add the kernel options to enable SELinux in /boot/grub/menu.lst.

Also, at somepoint I had to remove a file, but I can’t find the info that I used to justify that step. Here is it:

rm -i /etc/udev/rules.d/010-no-legacy-ptys.rules

Using PvGrub to Start Xen Guests on Debian Wheezy

Goal:

Have guest domains boot with their own kernel, or in other words, be able to run a kernel different than the host. Moreover, this means maintainer of the guest can be responsible for dealing with kernel updates. You can do this with pygrub, but there are reasons you may want to use pvgrub. Note the very minor difference in the spelling of the names! Note: both pygrub and pvgrub are for paravirtualized guests. So if you’re using hardware virtualization, this isn’t for you. Pygrub is named because is a python script. Pvgrub stands for paravirtualized grub.

Caveats:

  • pvgrub is not compatible with grub2, this only applies to if you have grub2 on your guest; you can use it with grub 1 (aka grub-0.9) or no grub at all
  • In Debian 8 all of this will be moot because a grub2 compatible pvgrub is being added, yeah!

Turns out there are some special steps in Debian Wheezy and here’s how I got it working along with reference article I used to figure it out.

These are the required steps and I’ll go into detail on each of the below.

  1. install pvgrub image on the host (dom0)
  2. install linux image on guest and create /boot/grub/menu.lst
  3. edit guest config file on host
  4. start the guest!

Morale Booster:

  1. I figured this out. So can you. I’m a git.
  2. Even when it didn’t work, ie guest didn’t boot, I was still able to shutdown guest, edit guest config file to boot the “old” way and see what I needed to change.
  3. YMMV

In this instance the host is Debian Wheezy running Xen 4.1.4 (for reference).

There is no pvgrub in Debian, so you have to get it from somewhere else. In this case I actually grabbed the _current_ xen release from github and compiled it. This creates the pvgrub images. I was concerned the pvgrub image would not work wtih 4.1.4 but it did, so I’m happy (for now).

The xen.org wiki was the main source where I got this information from and this should be considered a supplement to that article, not a replacement.

Before compiling xen I also needed the following packages in addition to all of the ones lists in the xen wiki post:

libaio-dev
texinfo

Here’s the part that wasn’t clear to me: pvgrub goes on the host, much like pygrub is run from the host. Duh! But that didn’t occur to me at first. So put pvgrub image on your host.

So to complete step #1 install pvgrub on the host you need to:

1) install any of these packages if you don’t already have them:

python-dev gettext bin86 bcc iasl uuid-dev libncurses5-dev pkg-config libglib2.0-dev libyajl-dev libpixman-1-dev bzip2 libc6-dev-i386 libaio-dev texinfo

2) git the xen source:

git clone git://xenbits.xen.org/xen

3) compile xen:
./configure
make

The pvgrub images are gz files in dist/install/usr/local/lib/xen/boot and they are

pv-grub-x86_32.gz
pv-grub-x86_64.gz

and you’ll need the correct one depending on what the guest machine is going to run. My guests are all x86_64. As a side note: I didn’t even compile xen on the host, I did it on another machine running Debian Wheezy then copied over the files I wanted.

4) Copy the pvgrub images to the host machine, in my case I use only amd64 flavors for host and all guests, so I just copied that one to /usr/local/lib/pv-grub-x86_64.gz Made sure its owned by root and permissions are 0644.

To complete step #2 – Install Linux images on guest:

1) on the guest install a linux image of your choosing
2) create /boot/grub/menu.lst with these contents

default 0
timeout 2
title Debian GNU/Linux
root (hd0)
kernel /vmlinuz root=/dev/xvda1 ro
initrd /initrd.img
title Debian GNU/Linux (recovery mode)
root (hd0)
kernel /vmlinuz root=/dev/xvda1 ro single
initrd /initrd.img

where /vmlinuz is a symlink to the kernel image you installed. In my case the guest disk is not partitioned, otherwise the (hd0) would be (hd0,0).

Create /etc/modprobe.conf with contents. Why? Because xen wiki article says to.

alias eth0 xennet
alias scsi_hostadapter xenblk

Likewise update /etc/inittab per xen wiki article:

hvc0:2345:respawn:/sbin/getty 38400 hvc0
xvc0:2345:respawn:/sbin/getty 38400 xvc0

Now we are ready to complete step #3, telling the host how we are going to boot the guest by editing the guest’s configuration file. These are the lines you need in the configuration file:

# points to PVgrub on host (dom0)
kernel = '/usr/local/lib/pv-grub-x86_64.gz'
# location of menu.lst on domU
extra = '(hd0)/boot/grub/menu.lst'

Please note the is usually an entry something like

root = '/dev/xvda1 ro'

in the guest’s configuration file. Remove it! Otherwise when you create the guest you’ll get dumped out on at a grub prompt. I just commented it out.

Now you can halt the guest and then

xm create -c /path/to/guest/config/file

to start the guest, with any luck.

Final thoughts…I’ve not dealt with this yet but the original author suggests making a symlink to /boot/grub/grub.cfg from /boot/grub/menu.lst so updates that use grub.cfg don’t freak out.