Starting a User Mode Linux/Debian-OS as an unprivileged Linux User

Starting a User Mode Linux/Debian-OS as an unprivileged Linux User


3 min read

After reading this article you will be able to start a Debian-Linux (including Kernel) from any (unprivileged) Linux shell.

User Mode Linux (UML) is a modified Linux Kernel that the user starts just like any other Linux program. The UML-Kernel then "boots" a 'Guest Debian Linux' to which the user can log in as root.

This is a great way to play around on a root-shell on an isolated Linux.

Think of UML as something between Docker and a VM:

  • All processes are visible on the host but 'kind of' isolated.

  • All processes run at near host speed (~15% slower).

  • All capabilities and privileges are available within the Guest OS.

  • Host and Guest OS must be of the same architecture (e.g. both x86_64).

  • Does not require access to /dev/kvm.

Alternatively, read Starting a VM as an unprivileged Linux User for using a full VM instead (which will run slower but better isolated).

The instructions have been tested on Segfault's Disposable Root Servers.

A. Configuration

  1. Set up UML and the directory structure:

[[ ! -f ~/.ssh/id_ed25519 ]] && ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
mkdir uml
cd uml
ar x user-mode-linux_5.10um3+b1_amd64.deb
rm user-mode-linux_5.10um3+b1_amd64.deb control.tar.xz debian-binary
tar -xf data.tar.xz
rm data.tar.xz
mv usr/bin/linux.uml .
mv usr/lib/uml/modules .
rm -r usr
[[ ! -f ~/.slirprc ]] && echo "redir tcp 2222 22" >~/.slirprc
  1. Download Debian OS and resize the image:

wget -O debian.img
truncate -s 8G debian.img
  1. Start Debian OS using the UML-Linux Kernel:

export TMPDIR=/tmp
./linux.uml \
    mem=1024M \
    root=/dev/ubda1 rw \
    ubd0=debian.img \
  1. Configure the System

Press Enter when prompted to configure the system:

sed '/boot\/efi/d' -i /etc/fstab
echo "none /lib/modules/$(uname -r) hostfs /sec/root/uml/modules/$(uname -r) 0 2" >>/etc/fstab
mkdir -p /lib/modules/$(uname -r)
# Mount the host's /sec inside the guest OS:
echo "none /mnt/host-fs hostfs / 0 2" >>/etc/fstab
mkdir -p /mnt/host-fs
ln -s /mnt/host-fs/sec /sec # specific
systemctl mask systemd-binfmt.service
systemctl disable getty@tty1
systemctl enable getty@tty0
ssh-keygen -A
cat > /etc/netplan/90-default.yaml <<-'EOF'
  version: 2
  renderer: networkd
      dhcp4: no
      addresses: []
        - to: default
          on-link: true
        addresses: []
growpart /dev/ubda 1
resize2fs /dev/ubda1
# Add an SSH Key
systemctl daemon-reload
mount /mnt/host-fs
cp /mnt/host-fs/root/.ssh/ ~/.ssh/authorized_keys
  1. Create a Shortcut for launching

cat > <<-'EOF'
#! /bin/sh
cd "$(dirname "$0")" || exit
export TMPDIR=/tmp
exec ./linux.uml mem=1024M root=/dev/ubda1 ubd0=debian.img eth0=slirp,52:54:00:00:01,/usr/bin/slirp-fullbolt
chmod +x

B. Starting the UML-Linux Debian OS

  1. Start the Debian OS UML-Linux


Log in using root without a password or use ssh -p2222 root@0 .

  1. Example: Install & start docker:

# UML Kernel does not come with all netfilter modules.
# Use iptables in "legacy"-mode instead:
update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
# Install docker
apt update
apt install
# Start 'Alpine/Linux' inside Docker, inside UML.
docker run --rm -it alpine

C. Advanced tricks

  1. Using the Slirp-Console to forward ports from the host to the UML guest:
# On the UML guest:
apt install telnet
# Make Linux less stupid ( is indeed a valid IP):
iptables -t nat -I OUTPUT -p tcp -d -j DNAT --to-destination
# Access the Slirp console

Shoutz to Matthew (๐Ÿซต๐Ÿง ๐Ÿ‘).