Skip to content

Running a minimal ubuntu chroot as regular user

rofl0r edited this page Jan 21, 2021 · 5 revisions

sometimes it's convenient to run a specific piece of software that's either only available for ubuntu (or glibc), or building it would require to build a huge clusterfuck of dependencies. here's how you can use ubuntu inside your sabotage install (and as regular user at that).

step 1: prepare rootfs

  • prepate a directory in your home:
    $ mkdir ~/ubuntu
    $ cd ~/ubuntu
  • get a minimal ubuntu rootfs
    $ wget http://cdimage.ubuntu.com/ubuntu-base/releases/20.04.1/release/ubuntu-base-20.04.1-base-amd64.tar.gz
    $ mkdir root
    $ cd root
    $ tar xf ubuntu-base-20.04.1-base-amd64.tar.gz

if your tar is from GNU coreutils, use instead:

    $ tar --same-owner -xf ubuntu-base-20.04.1-base-amd64.tar.gz

this prevents issues with file ownership when you extract it as root.

  • make sure you have correct permissions for all files inside root/:
    $ chown -R username:username root/

where username is your username.

  • edit inside root/ the file /etc/passwd and remove the last line containing the user _apt:
    $ nano root/etc/passwd
  • fill inside root/ the file /etc/resolv.conf with a nameserver ip
    $ echo "nameserver 8.8.8.8" > root/etc/resolv.conf

step 2: prepare tools to enter the chroot

variant 1 (most generic): using proot

proot allows to chroot as regular user almost everywhere. it achieves this by using ptrace(). this works even on kernels as ancient as 2.6.32. i've uploaded a statically linked binary.

    $ proot -0 -k "3.8.0" -b /dev:/dev -b /proc -r root/ /bin/bash

the only alternatives i'm aware of to achieve the same result as proot (on kernels without USER_NS) is fakeroot and fakechroot, but i really don't recommend them after wasting several hours trying to get them to work. especially fakeroot is a huge turd of code full of cruft and glibc-specific assumptions which doesn't even compile on ubuntu. the rest is fragile bash scripts which reference each other so it's really hard to set them up in a way they find the required files when you can't do a system-wide install. fakeroot and fakechroot are also full of hardcoded paths to glibc dynlinker and libc files, ldconfig and so on, they're really just a huge mess and shouldn't be used.

variant 2 (bubblewrap):

bubblewrap requires USER_NS support built into the kernel. this is the default on most distro kernels > 3.8.0. i uploaded a statically linked binary. it's got lots of options. following stanza allows us to successfully use the rootfs.

    $ bwrap --proc /proc --dev /dev --ro-bind /etc/resolv.conf /etc/resolv.conf --tmpfs /dev/shm --bind ./root / --uid 0 --gid 0 --unshare-user --chdir / /bin/bash

bubblewrap is refreshingly lightweight and generic. certainly the recommended option if your distro ships it and your kernel supports USER_NS.

variant 3: sabotage's super_chroot.c

like bubblewrap, it uses USER_NS, but it's much lighter. basically it's a 20 line C file.

  • copy from sabotage git dir the file enter-chroot to your ~/ubuntu dir:
    $ wget https://raw.githubusercontent.com/sabotage-linux/sabotage/563d56edea4077ff30425716eb624e562bdfedb9/enter-chroot
    $ chmod +x enter-chroot
  • replace the line /bin/sh --login with /bin/bash --login in enter-chroot

  • get super-chroot (it's like a 20 line version of bubblewrap)

    $ mkdir KEEP ; cd KEEP
    $ wget https://raw.githubusercontent.com/sabotage-linux/sabotage/4d436870d2173ebc05c1ab1f7e8e4ec7693bffb0/KEEP/super_chroot.c
    $ cd ..
  • remove the 3 lines containing the string "tarballs" in KEEP/super_chroot.c

  • put the following lines inside a file called config:

export SABOTAGE_BUILDDIR="$HOME/ubuntu/root"
export SUPER=1
[ -z "$H" ] && H="$PWD"
export K="$H"/KEEP
export R="$SABOTAGE_BUILDDIR"

now you can use ./enter-chroot to chroot into the ubuntu rootfs as regular user. the first thing you want to do is run apt update and then install some tools your need inside the chroot.

good luck!