What are the differences between nix-bwrapper, nixpak, jail.nix and nixjail and which one should I chose?

I’ve recently been interested in a very deep harderning of my NixOS system, explore what works and what doesn’t my end goal is to get as close as possible to secureblue levels but on NixOS.

while researching for application sandboxing projects (bubblewrap/bubblejail), I’ve come across the following: nix-bwrapper, nixpak, nix-jail (and also nixjail) and jail.nix

my question goes towards anyone using this (or that have tried some of them) which one is the best way to sandbox applications?

keep in mind I do expect to run into errors and seeing how things behave.

5 Likes

I haven’t personally used any of those, though I’ve heard good things about nixpak.

For my own setup, I just use pkgs.bubblewrap together with pkgs.xdg-dbus-proxy, and create wrapper packages using pkgs.writeShellScript and related helpers, without relying on a higher-level framework.

If you’re comfortable building your own wrappers, that approach has worked well for me. It also leaves room to integrate things like seccomp or landlock later.

1 Like

I haven’t used any of these, but was curious too, so I made a breakdown of the differences:

Project Container “runtime” Configuration style NixOS module Package builder xdg-desktop portal integration Architectural details Notes
jail.nix bwrap Functional combinators No Yes Yes Script generator
NixJail bwrap (supports systemd-run scopes) NixOS module Yes Kinda, undocumented Yes Overlay/script generator One-man show
NixPak Custom launcher, backed by bwrap External module system Yes Yes Yes Script generator
Nix-Bwrapper bwrap (via buildFHSEnv) External module system Yes Yes Yes Script generator
nix-jail systemd-run TOML configuration files, CLI No No No Docker-style client/server thing Very weird, was this created because the author doesn’t grok systemd units and asked an LLM to write something in rust?

Naming sucks, pay close attention to noun barreling and punctuation.

Overall I like jail.nix and NixJail best. The codebases are much more inspectable and the APIs are more purpose-built. Especially jail.nix seems well-architected (as you would expect from an author who is clearly a functional programming nerd).

NixJail looks like what I’d imagine myself writing over a few weekends to achieve this; which is to say I like it. Probably what I’d end up with if I did what @sotormd does for long enough. The author clearly cares about marketing their pet projects about as much as I do, so it sees proportional footfall and maintenance, if that’s an issue for you (but it’s so small I don’t really think it needs much maintenance either, which again, exactly what I strive for with pet projects).

In terms of features all but nix-jail are practically identical. NixPak and Nix-Bwrapper clearly have more users, but look to have been scope crept quite a bit. They do have more handholding though. Of the two NixPak seems better, Nix-Bwrapper seems mostly like a module system built around buildFHSUserEnvBwrap and I just don’t like that architecturally.

Stay away from nix-jail, I’d hardly call it a nix project, the author clearly doesn’t understand nix or what it’s about. I doubt they even understand software tbh, given what the docs tell you to do.

15 Likes

@sotormd do you have samples of such usages ? Why do we need xdg-dbus-proxy ?

Sure, here’s an example for a browser with bubblewrap and xdg-dbus-proxy. It isn’t particularly convoluted, the bwrap options are mostly from the archwiki examples.

xdg-dbus-proxy can selectively allow dbus connections. Without it, bubblewrap can only completely allow dbus or disable it entirely (either bind the bus socket or don’t). In this example, it lets me allow only org.mpris.MediaPlayer2.

2 Likes

I use nix-bwrapper to sandbox some proprietary software (namely Spotify/Spicetify) and very much recommend it, NixPak seems cool but has a bug with TUI apps (none of which I sandbox with nix-bwrapper anyways, but there was a recent fix for TUI apps in it so I would trust it more for that).
nix-bwrapper can read Flatpak manifests as well to generate what options it needs to use, so you can use it with less configuration.

Disclaimer: While I am technically something of security researcher myself, I wouldn’t call myself an expert on the matter.

I tried nixPak but instantly ran into a problem because they don’t expose the options of package they are wrapping. So if you use nixos Modules and modify options like in my case programs.firefox.package it will error out.

After that I found jail.nix and stuck with it so far. As TLater already said the codebase is very nice, well documented and it doesn’t push to much abstraction layers, so it is easy to change to your needs. However jail.nix does not at the moment apply either user networking (passt/pasta or slips-net) nor seccomp filters, you have to do this yourself.

Without those basically any sufficiently malicious application can use syscalls to escape the sandbox. To my knowledge neither nix-bwrapper, nixpak or nixjail implement seccomp filters either. Nix-jail claims to do so, I imagine that is because they are using systemd-run. Systemd generally makes it easier to implement than bubblewrap, since bubblewrap itself deems seccomp out of scope.

If you are concerned about hardening your nixos system there is this nice article and while they warn about setuid binaries I would probably still recommend firejail over any of the nix solutions (there are nixos options for it and they play nicely with the base options) or even using good old flatpak with something like Flatseal.

Another important thing and something some of these projects are doing is restricting access to other programs by locking down the nix store. However the best way to do this in general would be by using MAC (Mandatory access control) like AppArmor or SELinux. There was someone doing apparmor on nixos, but they have stalled since writing their thesis. Following the structure how they’ve done it you should be able to implement some profiles yourself. It is important to do this, since some programs, especially the nix binaries are super dangerous to have access to.

While the nix team(s) try their best (lix for example employs pasta for fixed output derivations) the attack surface is too great and besides some nix related project, no program needs access to nix anyway.

Probably a bit late to ask but what exactly is your thread model?

If you just want to defend yourself against the run of the mill supply chain attacks looking for passwords or API keys (which is probably the biggest attack vector for a nix user), all of the tools you mentioned should prove sufficient. I would recommend only storing sensitive data in encrypted form anyway using a password manager.

5 Likes

Your points are valid, but I do want to add that there is ultimately very little feasible beyond that threat model. We shouldn’t lull anyone into a false sense of security regardless of which sandboxing techniques are used.

CVEs showing sandbox escapes against cgroups are a dime a dozen. These techniques will probably never hold up against a targeted attack, not even firejail - the attack surface is just too large (though yes, more layers will always thwart a broader threatosphere).

So: sandboxing is cool, and probably miles ahead of whatever you were doing previously, but if Facebook want their tracking pixel to work they will find a way (although that particular path would be covered by firejail, I think).

2 Likes