doos 0.1.0: user-level overlayfs containers with slirp networking
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# Research: user-level containers with overlayfs
|
||||
|
||||
Measured on this machine: Ubuntu, kernel 7.0.0-38, AppArmor 5.0.2, slirp4netns 1.3.3, uid 1000, no root at runtime.
|
||||
|
||||
## What works unprivileged
|
||||
|
||||
1. `clone(CLONE_NEWUSER|NEWNS|NEWPID|NEWUTS|NEWIPC[|NEWNET])`, then the parent writes `setgroups=deny`, `uid_map`, `gid_map` (single entry, own uid). No setuid helpers (`newuidmap`) needed.
|
||||
2. overlayfs mounts inside the userns (kernel >= 5.11) with the `userxattr` option. Upper and work dirs must be on a filesystem with user xattrs (ext4, tmpfs >= 6.6 verified for ours).
|
||||
3. Mounts that work inside: tmpfs, proc (needs own pidns), devpts (new instance, no `gid=` since gid 5 is unmapped), bind mounts of host `/dev/{null,zero,full,random,urandom,tty}` (no `mknod` in a userns), read-only remount of `/proc` subpaths (must copy locked flags from `statvfs`).
|
||||
4. `pivot_root(".", ".")` plus lazy unmount of the old root.
|
||||
|
||||
## What does not
|
||||
|
||||
- Writing mapped uid ranges beyond own uid needs `newuidmap` + `/etc/subuid`. Skipped: single mapping keeps the design dumb. Consequence: no chown/su to other uids inside, so `apt install` as non-root users does not work.
|
||||
- cgroups: no memory/cpu/pid limits without systemd delegation. Not implemented (gap).
|
||||
- Ubuntu 24.04+: `kernel.apparmor_restrict_unprivileged_userns=1` lets any binary create a userns but strips capabilities inside it. Measured: uid_map write succeeds, first `mount` fails with EPERM. Fix is an AppArmor profile granting `userns` to the binary (`apparmor/doos`, install once with sudo). Turning the sysctl off is global and weaker.
|
||||
|
||||
## Networking options
|
||||
|
||||
| Option | Result |
|
||||
|---|---|
|
||||
| slirp4netns (chosen default) | Works unprivileged. Needs only the netns of the child pid. `--disable-host-loopback` blocks the container from reaching host 127.0.0.1 (measured: blocked). DNS via 10.0.2.3 works (measured). |
|
||||
| pasta | Installed here but not used: slirp4netns suffices, one dependency. |
|
||||
| veth + bridge | Needs CAP_NET_ADMIN in the host netns. Not possible unprivileged. |
|
||||
| host netns | Works, zero isolation. Offered as explicit `--net host`. |
|
||||
|
||||
## Host safety design
|
||||
|
||||
- No host paths writable: overlay lower dirs are only reachable through overlay (writes copy up to the container upper). Verified: write to `/usr` and `/etc` inside leaves host untouched.
|
||||
- Only `/usr /etc /opt` and compat dirs are exposed read-through. `/home`, `/var`, `/sys`, `/root` of the host are not present.
|
||||
- Old root detached after pivot, `no_new_privs`, `/proc` hardened, nosuid/nodev on tmpfs/devpts/overlay.
|
||||
- Residual exposure (gaps): host `/etc` is readable inside (any world-readable secret in it); abstract unix sockets are shared in `--net host`; no resource cgroups, so a container can fill the disk through its upper dir or fork-bomb within the user's `RLIMIT_NPROC`; kernel attack surface of userns is that of the host kernel.
|
||||
|
||||
## Measurements (this machine, 5 sequential `attach -- true`)
|
||||
|
||||
| Mode | Per attach |
|
||||
|---|---|
|
||||
| slirp | ~26 ms |
|
||||
| none | ~6 ms |
|
||||
|
||||
Single run set, one machine; no other hardware measured.
|
||||
Reference in New Issue
Block a user