Skip to content

Lxroot_old_home

parke edited this page Jan 4, 2022 · 1 revision

Lxroot - a software virtualization tool

About

Lxroot is a lightweight alternative to chroot, Docker, and other software virtualization tools.

Lxroot allows a non-root user to quickly and easily create a "chroot-style" virtual software environment (via Linux namespaces), and then run one or more programs (a "guest userland") inside that environment.

For example, with Lxroot a non-root user can...

  • simultaneously run multiple, different guest userlands on a single Linux host
  • run, for example, an Arch Linux userland on an Ubuntu Linux host
  • run a legacy userland on a modern host
  • run software in an "altered version" of the host system itself
  • run any given graphical X11 client (from any guest userland) on the host's X11 server
  • create a custom userland for developing software and/or building software packages
  • control (or test) the installation (or upgrade) of software packages, as a non-root user, by installing and running the software in an isolated and easily disposable userland
  • manage userlands with standard CLI tools: clone them with rsync, archive them with tar or mksquashfs, delete them rm -rf
  • deny software access to the network
  • restrict read and/or write access to specific directories
  • share one or more directories between an Lxroot environment and the host system
  • share one or more directories between multiple Lxroot environments.

All without root access!

The name "Lxroot" is a combination of "Lx" (as in "Linux") and "chroot".

Guest userland compatibility

Below are notes on using Lxroot with guest userlands from the following Linux distributions:

  • Alpine Linux - The Alpine Linux package manager and userland seem to run well inside Lxroot. (See Demo #1, below.)
  • Arch Linux - The Arch Linux package manager and userland seem to run well inside Lxroot. (See Demo #3, below.)
  • Debian and Ubuntu - Debian's package managers (apt-get and dpkg) require extensive tweaking and shimming before they will run successfully inside Lxroot. Consequently, at present I recommend against attempting to create a Debian or Ubuntu guest userland. If you really want to create a Debian or Ubuntu guest userland, I recommend creating the userland on a native Debian or Ubuntu host. This will probably require root access. Consider using debootstrap. After you have created the userland, you should be able to use lxroot to enter the userland.
  • Void Linux - Void Linux works well as a guest or host. (Note regarding Void as a host: I have only tested this on headless box, but I suspect X11 sharing will work. If X11 sharing does not work on a Void Linux host, please open a bug report.)

Lxroot creates virtual environments via Linux namespaces. When a non-root user creates and enters a Linux namespace, there are inherent and unavoidable limitations. In some cases, these limitations may create compatibility issues, depending on exactly what software you try to run inside Lxroot.

It is also possible (but hopefully unlikely) that your Linux distribution provides a Linux kernel that was compiled with non-root namespaces disabled. In this case, Lxroot will fail to run on your kernel.

Installation

$  git  clone  https://github.com/parke/lxroot.git
$  cd  lxroot
$  make  build

Unit tests

The unit tests install an Alpine Linux guest userland. The tests are then run inside this guest userland. This consumes approximately 9MB of disk space: 3MB in /tmp/lxroot-demo, plus 6MB in /tmp/lxroot-unit. Run the unit tests as follows:

$  make  unit

If the final line of output is something like the below, then the unit tests have completed successfully:

unit.sh  done  all tests passed

Demo #1 - Alpine Linux

Demo #1 will create an Alpine Linux guest userland, and then run an interactive shell inside the guest userland. Demo #1 consumes approximately 9MB of disk space in /tmp/lxroot-demo. Creating the Alpine Linux userland is very simple. All Demo #1 needs to do is download and untar an official Alpine Linux minirootfs tarball, and then copy in an appropriate /etc/resolv.conf file.

Run Demo #1 as follows:

$  make  demo

When you run the demo, you should see something like this:

mkdir  -p  /tmp/lxroot-demo/bin
g++  -g   -fmax-errors=2  -Wall  -Werror  -Wextra  -Wno-unused-parameter  lxroot.cpp  -o /tmp/lxroot-demo/bin/lxroot
cp  bin/lxroot  /tmp/lxroot-demo/lxroot
bash  demo.sh  demo1  /tmp/lxroot-demo

#  ( Welcome to the demo of lxroot!                       )
#  ( This demo creates an Alpine Linux guest userland and )
#  ( then runs an interactive shell inside it.            )

+  cd /tmp/lxroot-demo

#  ( Alpine Linux minirootfs - file found             )
#  ( Alpine Linux minirootfs - file checksum is valid )

+  mkdir demo1
+  tar xzf dist/alpine-minirootfs-3.13.5-x86_64.tar.gz -C demo1
+  cp /etc/resolv.conf demo1/etc/

#  ( We will now run the following command to start an interactive  )
#  ( shell inside the Alpine Linux guest userland:                  )
#  (                                                                )
#  (   ./lxroot  -nr  demo1                                         )
#  (                                                                )
#  ( The '-n' option allows network access.                         )
#  ( The '-r' option maps the uid and gid to zero.  In other words, )
#  (   '-r' simulates being the root user.                          )
#  ( 'demo1' is the name of the directory that contains the         )
#  (   Alpine Linux guest userland.                                 )
#  (                                                                )
#  ( The prompt inside the demo should be something like:           )
#  (                                                                )
#  (   root  -nr  ./demo1  ~                                        )
#  (                                                                )
#  ( 'root'    is the name of the (possibly simulated) user         )
#  ( '-nr'     is a summary of some of the command line options     )
#  ( './demo1' is the name of the newroot directory                 )
#  ( '~'       is the name of the current working directory         )

+  exec ./lxroot -nr demo1

root  -nr  ./demo1  ~  

Demo #2 - Nesting a second Lxroot environment inside Demo #1

Lxroot makes it easy to create a child Lxroot nested inside a parent Lxroot.

The below commands will:

  • enter the guest userland created by Demo #1
  • install the GCC compiler inside the Demo #1 userland
  • use GCC to compile Lxroot inside the Demo #1 userland
  • create a nested child Alpine userland inside the Demo #1 userland
  • lxroot into the nested child Alpine userland.

These commands will use approximately 221MB of disk space in /tmp/lxroot-demo.

To run Demo #2, please run the following commands:

####  To enter the demo #1 userland, run:
$  make  demo
####  Then, inside the demo #1 userland, run:
$  apk  update
$  apk  add  build-base  git
$  git  clone  https://github.com/parke/lxroot.git
$  cd  lxroot
$  make  build
####  Then, to run the unit tests inside the demo #1 userland, run:
$  apk  add  bash  coreutils
$  make  unit
####  Then, to nest a second userland inside of the demo #1 userland, run:
$  make  demo

Demo #3 - Chromium web browser inside an Arch Linux userland

Demo #3 will create an Arch Linux userland that contains the Chromium web browser. Demo #3 will then run an interactive shell in this userland. Run chromium in this shell to run Chromium.

Demo #3 was developed and tested on an Ubuntu 20.04 host. Demo #3 may or may not run on other hosts.

I have also partially tested Demo #3 on a headless Void Linux system. Everything installs, and I suspect Chromium would run successfully if I connected a monitor and intalled a graphical desktop.

Note: Demo #3 uses 5.2GB of disk space. If /tmp runs out of disk space, Demo #3 will fail. In this case, you may edit Makefile to specify a different demo directory and then run make demo3 again.

Chromium's access to the filesystem will be limited to the Lxroot environment. Furthermore, only $HOME and /tmp will be writable; all other directories will be bind mounted in read-only mode.

Demo #3 will need to create an Arch Linux userland from scratch, as Arch Linux does not provide a minirootfs tarball. Therefore, Demo #3 will do the following:

  • download the Arch Linux installion CD .iso file
  • create userland #1 (Alpine Linux, not Arch)
  • lxroot into userland #1 and then:
    • install file decompression utitilies
    • extract the airootfs.sfs file from the Arch .iso file
    • extract userland #2 from the airootfs.sfs file
  • lxroot into userland #2 and then:
    • run pacman to create userland #3
  • lxroot into userland #3 and then:
    • run pacman to install Chromium
  • lxroot into userland #3 as non-root and then:
    • run an interactive shell
    • you should be able to run chromium in this shell

To run Demo #3, please run:

make  demo3

After downloading the .iso file (which may take several minutes), Demo #3 takes about two minutes to build the three userlands on my computer. I have a low TDP CPU, but all files are read and written to a fast ramdisk. Userland #3, which contains everything Chromium needs to run, is 1.7GB. (This 1.7GB could probably be pruned down significantly, if desired.) Demo #3's total disk usage is approximately 5GB of disk space. By default, all files will be written inside /tmp/lxroot-demo. I think you can change this location by editing one line in Makefile.

At present, sound is disabled in Demo #3. If you wish to attempt to enable sound (via PulseAudio), then edit Makefile and add --pulseaudio to the final line of the demo3 recipe, as shown below. You probably also need to create manually create the $XDG_RUNTIME_DIR/pulse directory inside userland3.

$(bin)/lxroot  -nx  --pulseaudio  $(demo)/demo3/userland2/userland3

Documentation

Lxroot can be thought of as an alternative to the standard Unix program chroot. (Lxroot also has similaries to the Linux program unshare.)

However, Lxroot differs significantly from chroot.

  • Any user can run lxroot, whereas only the administrative user (root) can run chroot.
  • Lxroot can bind-mount various combinations of directories to "cut and paste" together custom userlands.
  • Directories can be bind-mounted in read-only mode to prevent undesired modifications to files.
  • Unless network access is granted with the -n option, programs will be denied access to the network.

If you are unfamiliar with chroot, the following pages may provide useful background information.