---
title: "Prepare the Linux sandbox"
description: "Set up bubblewrap and the distribution's sandbox profile before starting a Linux node that needs tier 1."
canonical_url: "https://docs.oz0.ai/getting-started/install/linux-sandbox"
---
# Prepare the Linux sandbox

> Set up bubblewrap and the distribution's sandbox profile before starting a Linux node that needs tier 1.

For: People installing a server or node.

Set up bubblewrap and the distribution's sandbox profile before starting a Linux node that needs tier 1.

## Sandbox tier 1 on Linux

Run as root, both `install.sh` scripts run `orchestrator-zero-node sandbox setup` before the node first starts, since a node finds its tier when it starts. On another machine, or after installing by hand, run it yourself:

```bash [Terminal]
sudo oz0-node sandbox setup --dry-run   # what it would do; needs no root
sudo oz0-node sandbox setup
```

It does two things, and says each one and how to undo it:

1. **bubblewrap**, when `bwrap` is missing, with the distribution's package manager: `apt-get`, `dnf`, `apk` or `zypper`.
2. **Ubuntu's own AppArmor profile for bwrap**, where the kernel lets only AppArmor-profiled programs create user namespaces (`kernel.apparmor_restrict_unprivileged_userns=1`, Ubuntu 24.04 and later). Ubuntu 25.04 and later ship that profile, `bwrap-userns-restrict`, enabled, and setup then changes nothing. On 24.04 the profile is in the `apparmor-profiles` package, which setup does **not** install: its postinst would also enforce about 19 other profiles (`dnsmasq`, `smbd`, `nmbd`, `php-fpm`, `avahi-daemon`, `nscd`, `ping` and more), which can break those daemons.<br />

Setup downloads the package with `apt-get download` (apt checks it against the archive's signed indexes), unpacks it with `dpkg-deb -x` in a temporary directory, copies only `extra-profiles/bwrap-userns-restrict` byte for byte into `/etc/apparmor.d` and loads it with `apparmor_parser`; the apparmor service loads it again at every boot. If you installed `apparmor-profiles` yourself, setup copies the file from `/usr/share/apparmor/extra-profiles` instead.<br />

The profile lets `/usr/bin/bwrap` create the sandbox's namespaces and stacks `unpriv_bwrap` on everything bwrap starts, which denies every capability.

It ends by running `sandbox check` as the node's account (`oz0-node`, or `nobody`). On a fresh cloud machine, where unattended-upgrades holds apt's locks for the first minutes, it waits up to five minutes for them. `sudo oz0-node sandbox setup --undo` unloads and removes the profile it copied, which it records in `/var/lib/orchestrator-zero-node-sandbox/setup.json`; a profile it did not copy (one you put there, one changed since, or the one the `apparmor` package installs on 25.04 and later) stays.

Before a release upgrade from 24.04 to 25.04 or later, whose `apparmor` package ships that file itself, run `sudo oz0-node sandbox setup --undo` (and `sandbox setup` again after it, which then changes nothing): dpkg otherwise finds a file no package installed where its own goes and asks what to do, and without a terminal that package's upgrade fails.

`--no-sandbox-setup` keeps either install script away from all of this.

What setup never does, and what you should not do instead:

- **It never writes a profile of its own.** An unconfined profile for `bwrap` that allows `userns` (some tools install one) lets any local user run `bwrap --cap-add ALL` and hold every capability in a user namespace, which is the bypass class [Qualys reported](https://www.qualys.com/2025/three-bypasses-of-Ubuntu-unprivileged-user-namespace-restrictions.txt) in Ubuntu's restrictions. Setup warns about such profiles in `/etc/apparmor.d`, and leaves them to you.
- **It never changes kernel settings.** Setting `kernel.apparmor_restrict_unprivileged_userns=0` would work, but lifts the restriction for every program on the machine. On an old Debian with `kernel.unprivileged_userns_clone=0`, or a machine with `user.max_user_namespaces=0`, setup says which `sysctl` would allow user namespaces.
- **Only `/usr/bin/bwrap` is covered**: Ubuntu's profile attaches to that path, so a bwrap of your own (`OZ0_BWRAP`) stays restricted.

A node still at tier 0 is a [health finding](https://docs.oz0.ai/fleet/nodes#findings) with the fix it worked out. A node installed as a service of the machine before this release has `ProtectKernelTunables` and `ProtectKernelLogs` in its unit, which keep bwrap from mounting a fresh `/proc`: rewrite the unit with `service install` again, with the node's own `--data-dir` and `--service-name` when it was installed with them (`oz0-node sandbox check` on the node names both), for example `sudo /usr/local/bin/orchestrator-zero-node service install --data-dir /srv/oz0 --service-name oz0-b` ([Nodes as services](https://docs.oz0.ai/fleet/services)).

Run the binary install.sh put in `/usr/local/bin`, not the service's own copy in `<data-dir>/bin`: the node's account owns that copy so it can update itself, and the fix never names it.

[Back to Install](https://docs.oz0.ai/getting-started/install).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
