Running Linux on Linux - Virtual Servers

Posted by Steve on Wed 24 Nov 2004 at 21:41

Tags: ,

Thanks to the existance of the user-mode-linux project it is possible to run a complete copy of the GNU/Linux operating system on top of your existing system. These virtual servers are ideal for testing software installations, or setting up mass hosting for customers.

This small introduction will show you how to run a copy of User-Mode-Linux on top of an existing Debian installation, and allow it to access the network.

This system can be used for experimentation, for testing new software, or for running particular services which will be completely isolated from your real machine.

User mode linux, as its name would suggest, runs entirely as a user process with on top of your existing system.

Because it boots up from a virtual filesystem it is possible to install Redhat, Gentoo, or Debian installations. Whatever version of Linux you like.

Here we're going to concentrate upon installing an installation of Debian Stable (woody) on a machine running Debian Unstable. (This is what I use when I'm testing Debian's security.

The guest installation of Woody will have access to the network, and will be able to treated as a complete virtual host.

First of all we need to install the software. As root run:

apt-get install user-mode-linux uml-utilities

This allows us to run a system.

For the system itself we need an operating system image. Much like when we installed Microsoft Windows on top of Debian we need a giant file which the system can treat as it's virtual hard drive.

To run a system you have the choice of creating the filesystem image from scratch yourself, or downloading a pre-made one. Here we are going to use one that Matt Zimmerman created already.

Create a directory to contain your image, and then download it. We will be running our virtual machine as a dedicated user, once we've set it up as root. So we'll create that user and do all the work in it's home directory:

useradd uml
groupadd uml
mkdir /home/uml
cd /home/uml
apt-get install wget bzip2
bunzip2 Debian-3.0r2.ext2.bz2

This gives you a small preinstalled system containing a minimal installation of Debian.

As the image is fairly small (42Mb compressed) we need to resize it to contain some free space. This will allow us to actually have room to install software when it is being used!

Here I'm choosing to make the disk image 2Gb in size. This is plenty of room to install packages on and generally play about with.

dd if=/dev/zero of=Debian-3.0r2.ext2 bs=1 count=0 seek=2G
e2fsck -f Debian-3.0r2.ext2
resize2fs -p Debian-3.0r2.ext2

In order for the guest installation to access the network you'll need to pick an access method. I've chosen to use the tun device, as that's the simplest to work with. For a detailed discussion of alternate methods of accessing the network there is some network documentation on the UML website.

The UML process can be run as any user with the caveat that the user must have permission to work with the network. We just need to add the relevent users to the uml-net group:

adduser uml uml-net

Finally you'll need to install the tun kernel module and cause it to be loaded on boot:

modprobe tun
echo 'tun' >> /etc/modules

We're almost ready to make the system work now - we just need to make a coulpe of changes to the image file we've downloaded so that it can see the network.

We do this by mounting the image and editing the files within it. Mount the guest image:

mkdir /home/uml/tmp
mount -o loop -t ext2 Debian-3.0r2.ext2 /home/uml/tmp

Now we need to setup some of the basic networking settings. We also need to disable the hardware clock as this doesn't work correctly under UML.

These next settings are specific to my home network, but you should be able to change them. What we want to do is give the machine an IP address on the network the host is connected to, with relevent DNS and gateway information.

The simple way to do this is as follows:

rm -f /home/uml/tmp/etc/init.d/hwclock*

echo '' >> /home/uml/tmp/etc/hostname

echo 'auto lo eth0' > /home/uml/tmp/etc/network/interfaces
echo 'iface lo inet loopback' >> /home/uml/tmp/etc/network/interfaces
echo 'iface eth0 inet static' >> /home/uml/tmp/etc/network/interfaces
echo 'address' >> /home/uml/tmp/etc/network/interfaces
echo 'netmask' >> /home/uml/tmp/etc/network/interfaces
echo 'gateway' >> /home/uml/tmp/etc/network/interfaces

echo '  uml240' > /home/uml/tmp/etc/hosts

echo 'nameserver' > /home/uml/tmp/etc/resolv.conf

Finally we want to setup the machine so that APT will work:

echo 'deb stable main contrib non-free'     \
echo 'deb-src stable main contrib non-free' \
echo 'deb woody/updates main contrib non-free'    \

Once this is done we're almost complete - we just need to make sure that ssh is installed so that we can connect to the image.

Using chroot we can lock ourself into the image and install the openssh server, and setup a password for the root user:

chroot /home/uml/tmp
apt-get update
apt-get install ssh
passwd root

That's our minimal setup complete. Everything else we can setup later, once we've installed the image as a real user mode linux process.

Exit the chroot and unmount the image by running the following commands. Notice that I've also changed the permissions on all the files so our lower privileged user can work with them:

umount /home/uml/tmp
chown -R uml:uml /home/uml

Everything from here on can be run as the dedicated uml user, which we created earlier.

If you wish setup a password for that user and change to it - if not as root run:

su - uml

You should now be able to boot the virtual linux machine, causing a complete system to be executed as process, using the file Debian-3.0r2.ext2 as it's virtual disk drive. To do this run:

IPADDR=`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`
linux mem=64M ubd0=Debian-3.0r2.ext2 umid=240 con=null \
  con0=fd:0,fd:1 con1=none eth0=tuntap,,,$IPADDR

The first line is supposed to find your current IP address, this is needed so that the system that you will be running can route through that to find its way onto the internet.

If you know what it is already you could use something simpler:

linux mem=64M ubd0=Debian-3.0r2.ext2 umid=240 con=null \
 con0=fd:0,fd:1 con1=none eth0=tuntap,,,$IPADDR

You should now see your linux system boot up in the console in front of you.

You can now login remotely using the installed openssh server, and work with it as if it were a real machine far far away!

When you're finished with it make sure that you terminate it cleanly, when logged into it as root run:


Do not attempt to run /sbin/reboot as this will fail.

Once you're happy with the way it's working you can set it up to run in the background, via screen, or similar.
The way I do that is to run the following script, which I saved as /home/uml/start:


IPADDR=`/sbin/ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`
screen -S uml-240 -d -m  \
  linux mem=64M ubd0=Debian-3.0r2.ext2 \
  umid=240 con=null \

This runs a screen session called 'uml-240' in the background, you can attach to this by running:

screen -R uml-240

And detach again later with 'Ctrl-A d'.

Because we've installed the uml-utilities package we can also interface with our running system via the uml-mconsole program. This takes the ID of a running system as an argument, the ID corresponds to the umid parameter we used in our startup script.

So to connect to our example system we use:

uml_mconsole 240

Now you can type 'help' to get a list of commands.

That's the end of our introduction, but hopefully enough to get you up and running with a virtual server installation.



Posted by simms (69.157.xx.xx) on Mon 6 Jun 2005 at 14:30
this comment may be less than timely, but it appears that the user-mode-linux package referred to in this article is not available in sarge.

can one install it from unstable 'cleanly' (i.e. only via apt-get) or is that not advisable on a sarge-exclusive system?

[ Parent | Reply to this comment ]

Posted by Anonymous (82.72.xx.xx) on Sun 3 Jul 2005 at 09:22

good article about uml, how about a follow up about xen?



[ Parent | Reply to this comment ]

Posted by Anonymous (217.64.xx.xx) on Sun 25 Sep 2005 at 11:47
> dd if=/dev/zero of=Debian-3.0r2.ext2 bs=1 count=0 seek=2G

Great incantation. When reading what dd manpage/infopage has to say, it does not become apparent that this command will change the size of the output file. How do you guys know this stuff? Does one have to have some Unix programming experience to use Unix to its fullest as a sysadmin?

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Sun 25 Sep 2005 at 11:57
[ View Steve's Scratchpad | View Weblogs ]

Well it certainly helps!


[ Parent | Reply to this comment ]

Posted by Anonymous (80.176.xx.xx) on Wed 30 Aug 2006 at 13:50
Hi all,

Folowing these instructions I encountered a problem with something spawning too fast. To fix this I changed the /etc/inittab file whilst the new file system was mounted. I changed the following section to read as thus:

0:1235:respawn:/sbin/getty 38400 console linux
#1:2345:respawn:/sbin/getty 38400 tty1
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6

[ Parent | Reply to this comment ]

Posted by Anonymous (203.94.xx.xx) on Thu 18 Jan 2007 at 04:29
I tried this but no gain :(

Starting periodic command scheduler: cron.
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes
INIT: Id "1" respawning too fast: disabled for 5 minutes

i really want to use UML to taste diff distros as i use only debian on my single 80 gb partition.

[ Parent | Reply to this comment ]

Posted by mutsuura (68.239.xx.xx) on Tue 23 Jan 2007 at 13:09

Pardon this silly question but how does this differ from 'qemu' per your article:

In other words, can I do the same w/ "qemu"?

Thx Attila

[ Parent | Reply to this comment ]

Posted by amosshapira (203.10.xx.xx) on Wed 21 Feb 2007 at 06:43
What's the question - being able to run linux under linux through UML vs. Qemu?

You can achieve the same goal with both.

The advantage of UML (which is why I got to this article) is that it should make it easier to debug kernel code - just attach GDB to the UML process and off you go. Apart from that, Qemu might be faster (and it can run any OS, not just Linux) but I'm not even sure about the speed advantage after the reading some comparison I saw recently.

BTW - this article seems to be a bit out of date for Etch (e.g. the "groupadd" command is unnecessary, it's possible to setup an "image" using debootstrap instead of downloading the particular one suggested in the article)

[ Parent | Reply to this comment ]

Posted by Anonymous (84.125.xx.xx) on Sun 10 Aug 2014 at 19:21
The link to Zimmerman is broken (

[ Parent | Reply to this comment ]

Posted by Anonymous (2.126.xx.xx) on Sun 10 Aug 2014 at 19:23

The article is ten years old ..

[ Parent | Reply to this comment ]

Sign In







Current Poll

Will you stick to systemd as the default in Debian?

( 892 votes ~ 35 comments )