Firejail: Light, featureful and zero-dependency security sandbox for Linux
firejail.wordpress.com
firejail.wordpress.com
To compare and contrast: bubblewrap is lower level, and is great for embedding or using in one-off invocations, whereas firejail is more oriented towards adding a bit of hardening to everyday applications like Firefox via built-in and custom profiles.
For example, you could temporarily override a path doing something like this:
bwrap --bind / / --bind /tmp/myoverride /usr/lib/qt5.15.2/plugins/kf5 -- ...
to, say, override the KDE plugins while testing. This is useful for me since it's rather challenging during development to actually get KDE apps to reliably load my plugins on NixOS: I think kio slaves are probably wrapped and getting other environments injected into them. Rather than bother with any tricky hacks, Linux namespaces make it relatively easy to test regardless.Bubblewrap is used internally by Flatpak and others.
bin=$(basename "$0")
exec bwrap \
--bind "$PWD" "$PWD" \
--dev /dev \
--die-with-parent \
--dir /tmp \
--dir /var \
--disable-userns \
--new-session \
--proc /proc \
--ro-bind /etc/ca-certificates /etc/ca-certificates \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--ro-bind /etc/ssl /etc/ssl \
--ro-bind /usr /usr \
--setenv PATH /usr/bin \
--share-net \
--symlink /tmp /var/tmp \
--symlink /usr/bin /bin \
--symlink /usr/lib /lib \
--symlink /usr/lib64 /lib64 \
--unshare-all \
--unshare-user \
"/usr/bin/$bin" "$@"
It gets read-write access to the current path, and to its own copy of ~/.cache and ~/.local/share. It doesn't see anything else from your home directory, including any adjacent projects. It can easily be locked down further by allowing read-only access to the project, and read-write access to node_modules and nothing else.Also sandoxing npm really means sandboxing node running npm (which is js).
Of course you can do all these things (on Linux at least), but it involves a dizzying array of technologies.
https://man.openbsd.org/pledge.2
https://man.openbsd.org/unveil.2
A few random examples:
https://github.com/tmux/tmux/blob/c8494dff7b6b9a996866edaf8c...
https://github.com/openbsd/ports/blob/master/www/mozilla-fir...
https://github.com/openbsd/ports/blob/master/www/mozilla-fir...
To get the best isolation you need to patch the source — the application needs to go through initial setup and then drop privileges to the absolute possible minimum. But it's easy to make custom wrappers for third-party applications — the above profiles taken from the OpenBSD ports tree are the proof.
This shouldn't be underestimated. It's really not that useful for most apps that don't have the source patched.
For example, any dynamically linked program that needs to spawn a subprocess using a command that it doesn't ship alongside itself is going to cause problems in your sandbox. That turns out to be the vast majority of programs that have been shipped in the FHS universe for the last few decades. It's only recently that sandboxing has come into vogue.
And the OS's that do a good job (like MacOS) get a bad rap from both developers and users who are mad their programs can't do what they want them to do because they don't have unfettered access to the filesystem any more.
sudo systemd-nspawn \
--directory=/ \
--volatile=yes \
--bind=/home/tmp:/home/tmp \
--private-network \
--port=tcp:80:8000 \
--property=CPUQuota=5% \
--property=MemoryMax=1G \
-- \
bash -c 'yes > /dev/null'$ podman run -it myimage bash
Fuse is rather irrelevant since I will mount volumes if I need to do IO. And slirp has been benchmarked to 9+ Gbps. So sure there's always room for improvement but the current situation is pretty sweet imo.
Like all other systemd-nspawn features, this is not a security feature and provides protection against accidental destructive operations only.
SELinux is pretty standard nowadays, most people just can't be bothered to learn it.
When I started using Linux, the security model had features like root being allowed to pwn the kernel and just about anything else. Now /dev/mem is gone, lockdown exists, namespaces exist, there are many more capabilities than there used to be, seccomp and seccomp-bpf exist, etc.
A lot of security ideas on Linux also rely on trusting the software, a model that may very well make sense in the context of Linux distributions with repositories of open source software. In this case, software itself opts into sandboxing to harden itself. This is pretty much what goes on with stuff like Flatpak. This also sounds like the idea with Pledge.
Can we do better? Maybe. I think adding true, practical sandboxing onto existing kernels not designed with this in mind is possible with tradeoffs. gVisor is an interesting approach: it's not a panacea but certainly a step in the right direction, using a usermode kernel that is itself separated into modules that are heavily locked down using ordinary Linux security mechanisms. This adds an additional layer to the moat that in theory is quite strong.
Another approach is virtual machines. And yes, this approach has some reasonable critique: typical VMMs and virtual machine software are very complex and involve needing to trust that the hardware was implemented correctly that the design isn't flawed, something that some people never trusted and others have lost some faith in with many hardware flaws and Qemu bugs coming to light. However, I still think lightweight virtual machines ought not be ignored entirely. Improvements have been made over time that make the idea of using virtual machines for this purpose a bit more within reason. For example, Firecracker and Ignite are pretty interesting tools for running software in a more sandboxed manner. And, even with virtual machines potentially having flaws, a lot of the time it may at least require root privileges or more to actually exploit some flaws, which makes this not entirely useless from a defense-in-depth standpoint.
But you just want an idiot proof way to call some binary and provide some limits, and have it be guaranteed to actually enforce those limits as a proper security boundary. Do we have it?... No. Will it be simple, something that can be done with some simple syscalls? Probably not. Could it be done with an unfortunately necessarily complicated piece of code? Probably yeah. I'd love to see a tool that can give you basically seamless sandboxing with simple options and backends for different sandboxing approaches like using VMMs or gVisor. Provide easy ways to run X11 or Wayland apps and automatically give you a sandboxed Xephyr instance or something to provide some sandboxing for Xorg apps. Will it happen? Dunno.
As for me, I'd really like a way to create a namespace where only some hosts on the network are accessible. It's possible to do today using various technologies, but it'd be a lot easier using something like the gVisor model with a usermode networking stack, I think. Maybe some day.
https://github.com/netblue30/firejail/commit/97d8a03cad19501...
https://www.redhat.com/sysadmin/mastering-systemd
https://gist.github.com/ageis/f5595e59b1cddb1513d1b425a323db...
Force a chroot, mount directories and devices as ro/rw, private tmp, set limits, many other things
We dropped docker and life is much better/faster
https://github.com/containers/bubblewrap/issues/81
It mentions nsjail and minijail.
We’ve got to make it easier to drop privileges on Linux without raising them first.
It works very well, boots quickly and is definitely well isolated. (Probably maybe)
#!/usr/bin/env bash
set -euo pipefail
args=(
-snapshot
-name cros
-nodefaults
-machine q35,vmport=off,dump-guest-core=off
-cpu host
-smp 4
-accel kvm
-m 4G
-display sdl,gl=on,show-cursor=on
-device virtio-gpu-gl
-nic user,model=virtio-net-pci
-drive format=qcow2,file=/data/cros/cros.qcow2
-usb
-device usb-tablet
-device intel-hda
-device hda-output
-device intel-iommu
-rtc base=utc
-monitor stdio
)
qemu-kvm "${args[@]}"Reasonable tbh.
For those wondering about their differences, Firejail provides a helpful overview here: https://github.com/netblue30/firejail/wiki/Frequently-Asked-...
TL;DR: Firejail has much more comprehensive features than Flatpak (Bubblewrap). Firejail also has more comprehensive network support, support for AppArmor and SELinux, and easier seccomp filtering.
Compared to Snap (which uses AppArmor), Firejail is not only compatible with AppArmor but again goes above and beyond with a lot of additional features.
From what I remember it certainly isn't as simple as you present it and additional features tends to involve additional surface area.
Other aspects in the past was that Firejail's approach to capabilities and namespaces enabled it to act as a setuid binary to gaining root privileges on the host.
Snaps I seem to recall had defined mounted namespaces that didn't need this privilege escalation. Their apparmor profiles are well defined and tunable via the connections mechanism. Although I seem to recall that too having some CVEs present.
In terms of trust though, I rather do trust snaps a lot more than firejail even if the latter is more tunable. I see that latter aspect as a downside, relative to snaps which already come confined and tuned.
There is also systemd itself which can be used in a similar way, and also has quite a nice tool for checking the exposure of a given sandbox.
starting with the Ubuntu 20.04 package base, the Chromium package is indeed empty and acting, without your consent, as a backdoor by connecting your computer to the Ubuntu Store. Applications in this store cannot be patched, or pinned. You can’t audit them, hold them, modify them or even point snap to a different store. You’ve as much empowerment with this as if you were using proprietary software, i.e. none. This is in effect similar to a commercial proprietary solution, but with two major differences: It runs as root, and it installs itself without asking you.
I know the reasons why canonical only keeps one store and it seems rather sane to me. Especially after hearing about the mess with PPAs.
I can run within their environment and unpack their squashfs. The snap runtime is very plain in GitHub.
Please stop sharing FUD.
We've got a real problem that the scope of things which have to be controlled keeps growing, and the ways to do that keep increasing as well.
And perhaps worse: there's precious little documentation of the implications of turning some of these features off. But that's far and away the most common thing you need to do because usually you have something that's broken, unless you disable a "security" feature.