Debian/Sarge GNU/UML Howto

Copyright (c) 2006 Matous Jan FIALKA.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Compiling User Mode Linux (kernel)

User Mode Linux is normal Linux (kernel) running in user-space as normal process (thus the name). There are some special things about the whole concept. As such kernel (Linux) sources must be compiled in a specific way.

(user@host)$ su -
(root@host)# cd /usr/src/linux
(root@host)# make ARCH=um oldconfig
(root@host)# make ARCH=um vmlinux

Note: I personally avoid using modules when compiling User Mode Linux, thus there is no need of make ARCH=um modules above. I strictly recommend *NOT* to use modules, things are going much easier without them.

Creating UML "disk" with Debian/Sarge

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 /tmp
(root@host)# dd if=/dev/zero of=sarge.xfs bs=1M count=1 seek=4096
(root@host)# mkfs.xfs -f debian.xfs
(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 debian.xfs /mnt
(root@host)# debootstrap sarge /mnt

You have just created 4GiB file containing XFS (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      /        xfs    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. Because the author's nearest mirrors are in Czech republic, hence he used them. You personally will rather use the nearest mirror of yours.

(chroot@host)# cat > /etc/apt/sources.list << EOF
####### SECURITY UPDATES
deb     http://security.debian.org/ stable/updates main contrib non-free
deb-src http://security.debian.org/ stable/updates main contrib non-free
####### PACKAGES REPOSITORY
deb     http://ftp.cz.debian.org/debian/ stable main contrib non-free
deb-src http://ftp.cz.debian.org/debian/ stable main contrib non-free
EOF

Do some update of new system now. first update the database and then upgrade what is upgradable. Very important thing is not to forget installing the IP Route 2 package!

(chroot@host)# apt-get update
(chroot@host)# apt-get upgrade
(chroot@host)# apt-get install iproute

Do some optional software instalation in this step as well, if needed.

Next logical step is to configure networking. We will not use any utilities such as UML Utilities and we will even not use them at all! First fill in some hostname.

(chroot@host)# echo uml0 > /etc/hostname

Then create the /etc/network/interfaces file assuming that your new User Mode Linux virtual machine will use address 10.0.0.1 from the network 10.0.0.0/24. Suppose that the gateway IP address will be 10.0.0.254.

(chroot@host)# cat > /etc/network/interfaces << EOF
##### lo -- local loopback
auto  lo
iface lo inet loopback

##### eth0 -- uplink
auto  eth0
iface eth0 inet manual
    ip l set up dev eth0
    ip a add 10.0.0.1/24 brd + dev eth0
    ip r add default via 10.0.0.254
EOF

Now you are going to finish. Several more steps are needed. First of them is to umount the previously mounted /proc directory under the chrooted environment before we leave it.

(chroot@host)# umount /proc

Then move out the /lib/tls directory using something similar to the next command.

(chroot@host)# mv /lib/tls /lib/tls.REMOVED

You should too do some firewalling on your new User Mode Linux box.

(chroot@host)# cat > /etc/init.d/firewall << EOF
#!/bin/bash

# function to clear all firewall rules
iptables_clear ()
{
    while read TABLE
    do
        /sbin/iptables -t \$TABLE -L -n | while read C CHAIN REST
        do
            if [ "X\$C" = "XChain" ]
            then
                /sbin/iptables -t \$TABLE -F
            fi
        done
        /sbin/iptables -t \$TABLE -X
    done < /proc/net/ip_tables_names
    /sbin/iptables -Z
    /sbin/iptables -t nat -Z
    /sbin/iptables -t mangle -Z
}

# clear all firewall rules
iptables_clear

# restrictive default firewall politic
/sbin/iptables -P INPUT   DROP
/sbin/iptables -P OUTPUT  DROP
/sbin/iptables -P FORWARD DROP

# allow local traffic
/sbin/iptables -A INPUT  -i lo+ -j ACCEPT
/sbin/iptables -A OUTPUT -o lo+ -j ACCEPT

# allow related/established and outgoing connections
/sbin/iptables -A INPUT  -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A OUTPUT -o eth0 -j ACCEPT
EOF

And to link it to some proper place.

(chroot@host)# ln -s /etc/init.d/firewall /etc/rc2.d/S20firewall

Now exit the chrooted environment, do some cleaning and unmount the loop-mounted FS.

(chroot@host)# exit
(root@host)# rm -f /mnt/root/.bash_history
(root@host)# umount /mnt

Configuring network on the host

There is not much about to configure the networking on the side of the hosting system. You will need the tunctl tool to create tap interfaces and (again) iproute package installed. There will be some need of tweaking firewall too, but nothing very painful.

Let's go. First create a tap0 interface (or any tapX interface, depending on your actual "running-config"). On my system, User Mode Linux virtual machines are ran under the user uml.

(root@host)# tunctl -u uml -t tap0

Next setup the new interface and add the right network on it.

(root@host)# ip l set up dev tap0
(root@host)# ip a add 10.0.0.254/24 brd + dev tap0

If you want this permanent in your system, just add next few lines in you /etc/network/interfaces file.

(root@host)# cat >> /etc/network/interfaces << EOF
##### tap0 -- virtual network interface
auto  tap0
iface tap0 inet manual
    up tunctl -u uml -t tap0
    up ip l set up dev tap0
    up ip a add 10.0.0.254/24 brd + dev tap0
EOF

On your firewall do something similar (these rules are not tightened enought, so be careful with it!) as follows below. You need to have forwarding enabled, but that's clear enough (I hope).

(root@host)# /sbin/iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
(root@host)# /sbin/iptables -A INPUT -i tap0 -j ACCEPT
(root@host)# /sbin/iptables -A OUTPUT -o tap0 -j ACCEPT
(root@host)# /sbin/iptables -A FORWARD -i tap0 -j ACCEPT
(root@host)# /sbin/iptables -A FORWARD -o tap0 -j ACCEPT

If you like to DNAT some ports too, you can, of course. Next rule will route incomming TCP connections on port 2222 on your host system to the User Mode Linux machine to port 22 (where the eth0 is the uplink interface of your *host* box).

(root@host)# /sbin/iptables -t nat -A PREROUTING -i eth0 \
  -p tcp --dport 2222 -j DNAT --to-destination 10.0.0.1:22

Now, when (almost) everything is set up, we can start our first User Mode Linux virtual machine.

Running User Mode Linux machine

I suggest *NOT* to use User Mode Linux under the root user! Use another, normal, user instead. To do so, several things have to be done before you start.

Now move all needed stuff to the uml user's home directory.

(root@host)# cp /usr/src/linux/vmlinux /home/uml/vmlinux
(root@host)# mv /tmp/debian.xfs /home/uml
(root@host)# mv /tmp/swap.img /home/uml
(root@host)# chown -R uml:uml-net /home/uml
(root@host)# exit

And log in as uml due to start the machine.

(user@host)$ su - uml

Start it!

(uml@host)$ ./vmlinux \
  umid=uml0 \
  mem=128M \
  ubd0=debian.cow,debian.xfs \
  ubd1=swap.img \
  con0=fd:0,fd:1 \
  con=pts \
  eth0=tuntap,tap0

And watch it booting up until some like this occures.

--- snipped ---
Virtual console 1 assigned device '/dev/pts/22'
Virtual console 2 assigned device '/dev/pts/25'
Virtual console 3 assigned device '/dev/pts/26'
Virtual console 4 assigned device '/dev/pts/27'
Virtual console 5 assigned device '/dev/pts/29'
Virtual console 6 assigned device '/dev/pts/30'
Virtual console 1 assigned device '/dev/pts/22'

Now you can easily login into it with minicom.

(uml@host)$ minicom -s

Now, you will see a simple menu like this on the screenshot.

Minicom - Setup Menu

Choose "Serial Port Setup".

Minicom - Serial Port Setup

Press "A" and configure the right /dev/pts/X for you. Then do "Exit" a see what happens.

Minicom - Serial Port Setup

Just type "root", log in, change the root's password, allow port 22 (SSH) on firewall, install SSH daemon and you will never need the minicom again!

Note: If you do not have minicom you could alternatively use screen /dev/pts/X (see man screen).

Valid XHTML 1.0 Strict Valid CSS!