Julien Valroff's weblog and personal homepage
Secure UML setup on Debian
Introduction
What’s UML?
User-Mode Linux is a safe, secure way of running Linux versions and Linux processes. Run buggy software, experiment with new Linux kernels or distributions, and poke around in the internals of Linux, all without risking your main Linux setup.
User-Mode Linux gives you a virtual machine that may have more hardware and software virtual resources than your actual, physical computer. Disk storage for the virtual machine is entirely contained inside a single file on your physical machine. You can assign your virtual machine only the hardware access you want it to have. With properly limited access, nothing you do on the virtual machine can change or damage your real computer, or its software.
Why using UML?
- Testing (hardware, networking…)
- Education/development
- For fun
Alternatives
- Xen – http://www.cl.cam.ac.uk/research/srg/netos/xen/
- VMWare – http://www.vmware.com/
- Linux V-Server – http://www.linux-vserver.org/
- Qemu – http://fabrice.bellard.free.fr/qemu/
Purpose of this article
This article aims a providing a step-by-step guide for setting up as securely as possible network-connected Debian virtual machines on a Debian host. I will talk about Debian Sarge, but this article should appy to future stable releases without any major changes, as I will use upstream methods as much as possible.
This documentation comes without any waranty, use it at your own risk.
Requirements
- Packages:
- user-mode-linux – http://packages.debian.org/stable/misc/user-mode-linux
This is the kernel itself, as an executable, as well as the associated kernel modules. As we are going to compile our own kernel, we won’t use this package, which is anyway not available in Debian Sarge, the current stable release as of writing - uml-utilities – http://packages.debian.org/stable/otherosfs/uml-utilities, the required userspace utilities
- user-mode-linux – http://packages.debian.org/stable/misc/user-mode-linux
- The host should have tun/tap enabled in the kernel, and its kernel can optionaly be patched with skas3 (this patch improves both performance and stability of the UML instances)
- You should also have knowledge in linux kernels (compiling, installing…), networking and system administration, in order to be able to debug in case of problem
I will also take as a basis you have full control on the host (ie. you own the root password) in order to set up the network.
Basic set up
As already described earlier, UML is a Linux kernel running as a process on a Linux host. To run one or several UML instances, you will need to compile the UML kernel, build a root file system containing Debian Sarge,
Compiling the UML kernel
UML being a port of linux to itself, it is on the same level as other architectures. You will thus have to compile the kernel specifying the architecture, so as not to compile for the host architecture (i386 for most of you I guess).
Download the latest kernel sources from www.kernel.org (or, better, from the nearest mirror), and process like for any other kernel build, just add ARCH=um at the end of each command. So as not to forget required options, I would suggest to run first make defconfig ARCH=um: this will select all default options for the um architecture. You can then run make {menu,x,g}config ARCH=um as you would do for any other kernel.
For security, I recommend to not use kernel modules. I also disable HOSTFS option, which would allow a user in a UML to mount a directory of the host from the UML. The rest of the compile options are up to you, here is an example .config file.
Two files result from the kernel building: linux and vmlinux (which are in fact hardlinks to the same file). For the tutorial, I will only talk about linux, but you can use any of them.
Creating the root filesystem
Once we have the Linux compiled we will continue preparing our new “disk” containing the Debian/Sarge GNU/Linux distribution. You will need at least do apt-get install debootstrap (as root user) before the next (very simple) step.
user@host$ su - root@host# apt-get install debootstrap
Then create both images, one for the system and one for the swap filesystem (FS).
root@host# cd /home/uml root@host# dd if=/dev/zero of=sarge.img bs=1M count=1 seek=4096 root@host# mkfs.ext3 -f sarge.img root@host# dd if=/dev/zero of=swap.img bs=256M count=1 root@host# mkswap swap.img
Mount new image and install Debian/Sarge GNU/Linux on it.
root@host# mount -o loop sarge.img /mnt root@host# debootstrap sarge /mnt
You have just created 4GiB file containing EXT3 (use any filesystem you like to) filesystem with Debian/Sarge GNU/Linux base system installed in. Now you will need to change your root directory within the chroot command and do some more settings.
Setting up UML system
root@host# chroot /mnt
It is nice to have something in /proc directory when you are working in a system.
chroot@host# mount -n proc
Because User Mode Linux is using special type of devices to know where it’s filesystems are, we need to create appropiate device files for it.
chroot@host# mkdir /dev/ubd chroot@host# cd /dev/ubd chroot@host# for i in 0 1 2 3 4 5 6 7; do mknod $i b 98 $[ $i * 16 ]; done
Next action is to create the right /etc/fstab file due to need of system to know what device should what directory mount on (just “copy&paste” next stuff in the terminal).
chroot@host# cat > /etc/fstab <<EOF /dev/ubd/0 / ext3 defaults 0 0 /dev/ubd/1 none swap defaults 0 0 none /proc proc defaults 0 0 sys /sys sysfs defaults 0 0 none /dev/pts devpts defaults 0 0 EOF
Now create list of mirrors to get your new Debian/Sarge GNU/Linux packages and sources. Please chenge the following lines to use the nearest mirror of yours.
chroot@host# cat > /etc/apt/sources.list <<EOF deb http://ftp.fr.debian.org/debian/ stable main contrib non-free deb http://security.debian.org/ stable/updates main contrib non-free EOF
contrib and non-free sections are optional – remove them if you want to only use DFSG free software.
Setting up the network
So as to be able to update the system, we now have to set up the network. Although there are various possible configurations, the tun/tap setup is the preferred method due to its stability, performance and ease of use.
Configure the host
We will need to create a tun/tap instance on the host. Edit your /etc/network/interfaces file to add the following part:
root@host# cat >> /etc/network/interfaces <<EOF auto tap0 iface tap0 inet static address 192.168.2.254 netmask 255.255.255.0 tunctl_user uml-net uml_proxy_arp 192.168.2.5 uml_proxy_ether eth0 EOF
Running qemu guests
To secure the qemu set-up, it is great to launch the virtual machines as an under-privileged user. As advised in other how-to’s, create a new user uml, and move all the needed stuff to the uml user’s home directory. To harden the security, you can even launch the linux binary as a non-existing user, using a semi-random UID, and chrooted in the uml user’s home directory. You can use the following do-chroot.c program (taken from the “User Mode Linux” book – no licence specified, please contact me if re-distributing it is not allowed):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <stdio.h> #include <errno.h> #include <stdlib.h> int main(int argc, char **argv) { int uid; char *dir, **command, *end; if(argc < 3){ fprintf(stderr, "Usage - do--chroot dir uid command-line...\n"); exit(1); } dir = argv[1]; uid = strtoul(argv[2], &end, 10); if(*end != '\0'){ fprintf(stderr, "The uid \"%s\" isn't a number\n", argv[2]); exit(1); } command = &argv[3]; if(chdir(dir) < 0){ perror("chroot"); exit(1); } if(chroot(".") < 0){ perror("chroot"); exit(1); } if(setuid(uid) < 0){ perror("setuid"); exit(1); } execv(command[0], command); perror("execv"); exit(1); } |
Using screen to access easily the UML instances even without network, and so as to be able to launch them automatically at boot time (using cron @reboot), here is the script I have for launching uml guests:
[ -e /home/uml/tmp/sarge/mconsole ] || TMPDIR=/tmp_fs screen -S sarge -dmU \ /root/do-chroot /home/uml/ 1050 ./linux \ uml_dir=/tmp sarge mem=64M ubd0=./debian.cow,./sarge.img \ ubd1=./swap.img devfs=mount eth0=daemon,00:20:1B:B5:99:83,unix,/tmp/ctl/uml_switch.ctl \ con0=null,fd:2 con1=fd:0,fd:1 mode=skas0
The first part is a test to avoid launching the same uml guest several times.
Also, do not forget to specify a specific MAC address for each uml instance you may launch, or they will all have the same hardware address, which will obviously cause issues (I needed time to figure out why some of my UML virtual machines were slow on network, whereas others were ok…).
References
- The User-mode Linux Kernel Home Page – http://user-mode-linux.sourceforge.net/
- Matous Jan FIALKA’s UML Quick Howto – http://uml.ligatura.org/
- The UML How-to – http://user-mode-linux.sourceforge.net/UserModeLinux-HOWTO.html
- Book “User Mode Linux” by Jeff Dike (ISBN 0-13-186505-6)
Recent Comments