I found out about Bubblewrap recently. It allows the user to run a program in a sandbox, and restrict its access to paths and resources on the host.
For instance, we can run a Bash shell which has no network interface:
$ bwrap --unshare-all --new-session --ro-bind / / /bin/bash
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
$ curl icanhazip.com
curl: (6) Could not resolve host: icanhazip.com
Or, maybe you want to run a command which does not have access to your personal files inside
/home:
$ bwrap --ro-bind /usr /usr \
--symlink usr/lib64 /lib64 \
--symlink usr/bin /bin \
--symlink usr/sbin /sbin \
--chdir / \
--unshare-all \
/bin/bash
bash-5.2$ ls /home
ls: cannot access '/home': No such file or directory
Note: The reason that we mount the various directories in /usr and under it separately, but
don’t mount / directly, is to ensure that we can mount something else at /home! In fact, it is
possible to use bwrap to start as a new user with its own home directory that is inside the
~/sandbox of the host’s filesystem. I was wondering why all the online examples used this!
So far, I have had one use-case for such sandboxing: I use a Perl script to convert GnuCash files into Ledger data files, because I use Ledger for analyzing my personal finances. I want this script to never edit the input GnuCash file. I know that the program does not do it; however, having an additional guarantee is not a bad idea, so I use Docker to run the script and use a read-only volume mount to ensure that the input file can not be edited. This has not been easy to use though. So, I will probably shift it to use Bubblewrap soon.