--isolate flag or the corresponding profile settings.
What each namespace does
Every request also creates a user namespace. It maps your own uid and gid to themselves, so files keep their owners andid reports your user. It is what lets an unprivileged process create the other namespaces. The capabilities the setup step holds inside that namespace do not survive into your command: the sandboxed process runs with no capabilities.
Network isolation closes some of the same classes as Landlock’s scoping and network rules, but it does so on every kernel nono supports. Landlock abstract-socket scoping needs ABI V6 (Linux 6.12), and Landlock network rules cover TCP only.
Pathname Unix sockets (such as
/run/user/1000/bus or /var/run/docker.sock) are reached through the filesystem, so a network namespace does not block them. Use linux.af_unix_mediation to control them today.Local servers on loopback
By default an isolated command cannot use TCP even on its own loopback. nono’s normal network rules still apply inside the namespace:--block-net denies TCP sockets, and proxied mode allows a connection only to the proxy port. Dev servers, test suites that listen on 127.0.0.1, and language servers over TCP all fail.
Add loopback to allow them:
loopback, the command can bind, listen, and connect on any TCP port on 127.0.0.1 and ::1 inside the namespace. That loopback belongs only to the sandbox:
- Nothing on the host can connect to these listeners, and the command still cannot reach host localhost services.
- Egress is unchanged: the only way out is still the nono proxy, with the same filtering and authentication.
- UDP, raw sockets, and netlink stay denied.
- The proxy port is already held by nono’s bridge listener, so the command cannot take it over.
loopback requires net; on its own it is a startup error, because without the namespace it would reach the host’s localhost. --open-port, --listen-port, and --allow-connect-port stay rejected under isolation, because they refer to the host’s localhost, not the namespace’s.
Networking inside the namespace
The isolated network has no route to the host or the internet. The only way out is via the session proxy:- Network blocking:
--block-netresults in no proxy and no bridge - loopback only. - Proxied networking:
--allow-domain,--network-profile, credentials etc: A loopback listener inside the namespace on the proxy’s port which is served from the supervisor.
Merging and precedence
linux.isolate fields merge by logical OR across extends, packs, and the CLI. Any layer can turn a namespace on, and no layer can turn one off. --isolate adds to a profile’s isolation; it cannot remove it.
Host requirements and failure
nono probes the host at startup by actually creating the namespaces in a scratch process. If the host refuses, nono stops with an error that names the step that failed and the likely cause. Some common causes include:-
Ubuntu 23.10 and later restrict unprivileged user namespaces with AppArmor (
kernel.apparmor_restrict_unprivileged_userns = 1). Allow nono specifically by installing an AppArmor profile, for example/etc/apparmor.d/nono:Adjust the path to where yournonobinary is installed, then runsudo apparmor_parser -r /etc/apparmor.d/nono. This lets any local user obtain an unprivileged user namespace through nono, the same trade Ubuntu makes for its bubblewrap profile. -
Containers. Docker’s and Kubernetes’ default seccomp profiles block
unshare. See Externally provisioned namespaces. -
Hardened kernels with
kernel.unprivileged_userns_clone = 0oruser.max_user_namespaces = 0.
Externally provisioned namespaces
Where unprivileged user namespaces cannot be enabled, create the namespace outside nono with the privileges you already have and run an unchanged nono inside it, without--isolate. Examples: sudo ip netns exec, systemd-run -p PrivateNetwork=yes, or the container itself. nono never runs privileged setup code itself.
Limits
- Linux only. On macOS,
linux.isolateis ignored and--isolateis not available. Seatbelt’s deny-default profile covers the socket classes independently. nono runandnono shellonly.nono wraphas no supervisor to create the namespaces or serve the proxy bridge, so it rejects profiles that setlinux.isolate.- Supplementary groups appear as
nobodyinside the namespace, because only your primary uid and gid are mapped. The kernel still applies your real groups for file access. - Kernel attack surface. Unprivileged user namespaces expose more kernel code to the sandboxed process. See the security model.
loopbackis Linux-only. On macOS a profile that relies on it for a local server still needsnetwork.listen_port.- Not yet available: a mount namespace that masks
$XDG_RUNTIME_DIR, D-Bus, and container sockets, plus a per-session/tmp; a SOCKS5 route for non-HTTP TCP; and reverse forwarding for listen ports. These are planned under NEP-0004.