User Mode Linux

UML

UML

Well back in the day, before the hardware visualization craze of the 2000’s back in the dark days of 1999, there was UML, or better known as User Mode Linux.  Sadly the freshmeat announcement is all but lost, but sourceforge is still with us so we have the archives.

UML, simply put is a Linux kernel that has been modified to run in user space.  So to the OS, it is just another usermode program.  Because it runs in user space, there is no kernel dependencies, or special hardware required, as UML is just a user program.  Much in the way Qemu emulates a full machine, UML instead is the kernel process running with paravirtualized drivers so it should give overall a better/faster experience than hosting via Qemu.  Keeping in mind that VMware was a 1.0 launch product in may of 1999, and Bochs was back from 1994.

So what happened to UML?  The market was just too young to understand the power of hosted virtual machines, although there were some at the time.  Overall the market was in the idea of large servers that could ‘share’ thousands of websites, and most people didn’t either want to run root in their own little world, or didn’t even know there were other options besides getting an entire physical box.  I used to rent some UML VM out from a Canadian outfit back when I’d stream audio out on shoutcast, as I found my crappy connection at home couldn’t handle more than 5 listeners, but I could stream to the UML instance, and have it advertise out on shoutcast, and handle the 20-30 users I’d get back then.  Now that we live in the gated walled world of corporate hosting, I don’t think most people would even imagine going through the hell of building their own hosting infrastructure.

So it’s 2016, who cares today?

Well this… ‘friend’ of a ‘friend’ bought what they thought was a dedicated machine in a one year contract.  Except it turned out to be a KVM VM, with ‘dedicated’ processors to the instance.  Ouch.  They also got a bunch of ip addresses, but the idea of being able to run their web servers in VMs, along with an OpenVPN concentrator seemed to become an impossibility.  Obviously user mode Qemu is an option but it would be far too slow.  So I figured this would be a good time to use something from the past, UML.

So the ‘base’ host is running Debian 8.1.  So the first thing to do is to install the 2 neeed packages for networking, the bridge & uml utilities.

apt-get install bridge-utils uml-utilities
apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386

And with that in place I want to run 32bit UML kernels, which means I need the 32bit ‘runtime’ so the Debian way to enable 32bit exe’s is:

dpkg –add-architecture i386
apt-get update
apt-get upgrade
apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386

One thing to keep in mind about UML, or x86 Linux in general is that you cannot mix a 64bit kernel with a 32bit userland, the 64 bit kernel can run 32bit executables and libraries, but it really needs a full 64bit userland.  So from the UML page, to get going I went with the kernel linux-2.6.24-rc7.bz2 and an ancient copy of Debian 4.0 I found here.

For anyone interested in more ‘modern’ kernels and filesystems, be sure to check out uml.devloop.org.uk & fs.devloop.org.uk.

Ok, now we want to add a bridge interface for this type of setup.  The idea is that the UML’s will have ONLY an internal connection to the bridge, as the base machine owns all the physical addresses.

So it being Debian we modify the /etc/network/interfaces file to add:

auto br0
iface br0 inet static
address 10.13.0.1
netmask 255.255.255.0
network 10.13.0.0
broadcast 10.13.0.255
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off
pre-up brctl addbr br0
post-down brctl delbr br0

The choice of 10.13.0.0/24 is 100% up to you.  You can use any RFC 1918 address without any issues.  Now I put this stuff in a script to fire up a UML host that will create my tap0 interface, bring it up, add it to the bridge, and fire up the UML.  On termination it’ll remove the tap from the bridge, and delete the interface.

tunctl -t tap0
ifconfig tap0 0.0.0.0 promisc up
brctl addif br0 tap0
./linux-2.6.24-rc7 ubda=test_fs eth0=tuntap,tap0 mem=512M
brctl delif br0 tap0
tunctl -d tap0

And once UML has booted up, a simple ifconfig can bring up the network, and I should be able to ping the bridge address

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
(none):~# ifconfig eth0 10.13.0.10 netmask 255.255.255.0
(none):~# ping 10.13.0.1
PING 10.13.0.1 (10.13.0.1) 56(84) bytes of data.
64 bytes from 10.13.0.1: icmp_seq=1 ttl=64 time=0.043 ms
64 bytes from 10.13.0.1: icmp_seq=2 ttl=64 time=0.067 ms

You get the idea.

Because I’m running some ancient debian root filesystem, I had to set the /etc/apt/sources to include the official archive to at least install things like ssh.

deb http://archive.debian.org/debian etch main

But that is pretty much that.

Now for the real fun part, putting it on the internet!  I’ve found that this is a simple way to redirect in port 80 on the registered address I want to use, and it allows the UML instance to NAT out the same address.

/sbin/iptables -t nat -A POSTROUTING -s 10.13.0.10/32 -o eth0 -j SNAT –to 1.2.3.4
/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -d 1.2.3.4 -j DNAT –to 10.13.0.10:80
/sbin/iptables -t nat -A POSTROUTING -s 10.13.0.10/32 -o eth0:0 -j MASQUERADE

Remember that you’ll also need to enable ipv4 forwarding for this to work!  You’ll need to run:

sysctl -w net.ipv4.ip_forward=1

or add it to /etc/rc.local
And with all that done, the 32bit web server is now talking. It’s not what everyone was hoping for, but at least it’s a solution.

As an update, for those who don’t have the option of TUN/TAP bridging, there is always SLiRP, as covered here.

9 thoughts on “User Mode Linux

  1. Wow. Again, an amazingly well written tutorial. Thanks for that! That really got me interested in UML. I was aware of its existence, but that’s about it. I once faced the exact same issue – but I failed to figure out that UML would help here.
    Seems like my weekend project suddenly became to toy around with UML.

    Cheers,

    -Florian

    • Hey no problem! This whole blog is about my overcoming stupid self inflicted problems, like buying the wrong equipment, and hammering that square peg into the round hole.

      I don’t think I’ve messed with UML since 2003 with the advent of VMWare ESXi 2.0, and of course Qemu letting me run stuff like my beloved OS/2.

      It’s cool that UML is still in development, and you can easily download version 4 kernels, or roll your own. I wonder what the performance is KVM vs UML. Maybe UML is something overlooked in the world of running Linux on Linux?

      • I think so. It’s amazing how easy this is to use… I mean: you basically just start the kernel like you would any other program. I personally like that it enables you to toy around with various kernel and userland builds without screwing up your main system. I think this really can come in handy in a lot of ways.

        • It really is a ‘low barrier’ way to say test Linux kernel 4.x on Debian 2 for the hell of it.

          According to this list, however it appears to be far slower compared to other emulation strategies. But like Qemu this one doesn’t require any device driver access.

  2. There was an implementation for Windows, but finally it became an time expensive and difficult to maintain project mess due the big differences between Linux and NT API and was passed in favor of coLinux.

    Now coLinux isn’t actively developed anymore, and it only supports 32Bit windows versions. It supposedly became irrelevant due VTx assisted virtualization. Ironically enough right now MS decides to retake this older concept and make it profitable. I wonder if this time it will have success.

    • colinux is very different from a NT subsystem though. If MS had documented the subsystem stuff, I’m sure Linux would have been ported to NT quite a while ago, and would have been a player in the corporate world.

      Is it too little too late now? I don’t think so, I have been in multiple environments where you can ONLY get Windows servers as part of their corporate support strategy. SUA/SFU was one way to get a UNIX like environment, but they could easily turn into a major PITA to get more ‘interesting’ things working. A Linux personality for NT will go a very very long way IMHO.

      UML on Win32 is related to the LINE project which again died out around 2002.

    • Ah yes, but now they’ve changed their minds and while wslv1 is still supported, wsl2 is now a virtual machine running under hyper-v, with network shares to access files across the systems.

      My own environment is now wsl; previously it was mostly cygwin, with some msys. Where native Linux is required, I use an Android tablet, or in extreme cases a virtual machine.

      Right now I’m looking at uml because I’m interested in getting a full Linux desktop environment working on an unrooted Android phone; termux has proot, but it’s not enough isolation and doesn’t work for multiple user stuff or init.

  3. That is an interesting solution – though I can’t help but think Linux containers and Docker might be more effective… But then again, I don’t read this blog for normal solutions – this is obviously a more interesting read 😛

    • docker still needs something like KVM. And KVM can’t run KVM. But you can deploy UML in a docker like scenario, you could setup a generic web server, and then mount it’s filesystem via loop, reconfigure it’s ip address, and spin it up and add it into a load balancer as needed, and similarly destroy them. The magic of it, is that it’s all user mode code, so having a crap hosting solution is still workable.

      lol, and yes, this is not the source for normal solutions, but rather living on edge situations.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.