Linux-native "fake root" for implementing rootless containers
Linux-native "fake root" for implementing rootless containers
RootlessKit is a Linux-native implementation of "fake root" using user_namespaces(7).
The purpose of RootlessKit is to run Docker and Kubernetes as an unprivileged user (known as "Rootless mode"), so as to protect the real root on the host from potential container-breakout attacks.
RootlessKit creates user_namespaces(7) and mount_namespaces(7),
and executes newuidmap(1)/newgidmap(1) along with subuid(5) and subgid(5).
RootlessKit also supports isolating network_namespaces(7) with userspace NAT using "slirp".
Kernel-mode NAT using SUID-enabled lxc-user-nic(1) is also experimentally supported.
Tools based on LD_PRELOAD (not enough to run rootless containers and yet lacks support for static binaries):
Tools based on ptrace(2) (not enough to run rootless containers and yet slow):
Tools based on user_namespaces(7) (as in RootlessKit, but without support for --copy-up, --net, ...):
Container engines:
Container image builders:
docker build backendKubernetes distributions:
$HOME.Run make && sudo make install .
The following binaries will be installed:
/usr/local/bin/rootlesskit/usr/local/bin/rootlessctl/usr/local/bin/rootlesskit-docker-proxy (DEPRECATED; Only required for Docker prior to v28)newuidmap and newgidmap need to be installed on the host. These commands are provided by the uidmap package on most distributions.
/etc/subuid and /etc/subgid should contain more than 65536 sub-IDs. e.g. penguin:231072:65536. These files are automatically configured on most distributions.
$ id -u
1001
$ whoami
penguin
$ grep "^$(whoami):" /etc/subuid
penguin:231072:65536
$ grep "^$(whoami):" /etc/subgid
penguin:231072:65536See also https://rootlesscontaine.rs/getting-started/common/subuid/
Old distros may require setting up sysctl such as kernel.unprivileged_userns_clone=1:
See .
On Ubuntu 24.04 or later, the rootlesskit binary is expected to be exactly under /usr/bin.
To install rootlesskit on other paths such as /usr/local/bin, you need to install a custom AppArmor profile.
See .
Inside rootlesskit bash, your UID is mapped to 0 but it is not the real root:
(host)$ rootlesskit bash
(rootlesskit)# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
(rootlesskit)# ls -l /etc/shadow
-rw-r----- 1 nobody nogroup 1050 Aug 21 19:02 /etc/shadow
(rootlesskit)# cat /etc/shadow
cat: /etc/shadow: Permission deniedEnvironment variables are kept untouched:
(host)$ rootlesskit bash
(rootlesskit)# echo $USER
penguin
(rootlesskit)# echo $HOME
/home/penguin
(rootlesskit)# echo $XDG_RUNTIME_DIR
/run/user/1001Filesystems can be isolated from the host with --copy-up:
(host)$ rootlesskit --copy-up=/etc bash
(rootlesskit)# rm /etc/resolv.conf
(rootlesskit)# vi /etc/resolv.confYou can even create network namespaces with Slirp:
(host)$ rootlesskit --copy-up=/etc --copy-up=/run --net=slirp4netns --disable-host-loopback bash
(rootleesskit)# ip netns add foo
...…The following files will be created in the state directory, which can be specified with --state-dir:
lock: lock filechild_pid: decimal PID text that can be used for nsenter(1).api.sock: REST API socket. See ./docs/api.md and ./docs/port.md.netns (since v2.0.0): Detached NetNS. Created only with --detach-netns. Valid only in the child mount namespace.resolv.conf (since v2.0.0): resolv.conf file. Bind-mounted to /etc/resolv.conf unles --detach-netns is specified.hosts (since v2.0.0): hosts file. Bind-mounted to /etc/hosts unless --detach-netns is specified.If --state-dir is not specified, RootlessKit creates a temporary state directory on /tmp and removes it on exit.
Undocumented files are subject to change.
The following environment variables will be set for the child process:
ROOTLESSKIT_STATE_DIR (since v0.3.0): absolute path to the state dirROOTLESSKIT_PARENT_EUID (since v0.8.0): effective UIDROOTLESSKIT_PARENT_EGID (since v0.8.0): effective GIDUndocumented environment variables are subject to change.
./docs/network.md: Networking (--net, --mtu, --cidr, --disable-host-loopback, --slirp4netns-*, ...)./docs/port.md: Port forwarding (--port-driver, -p, ...)./docs/mount.md: Mount (--propagation, ...)./docs/process.md: Process (--pidns, --reaper, --cgroupns, --evacuate-cgroup2, ...)./docs/api.md: REST API./docs/subid.md: Sub UIDs and sub GIDsNo open issues yet, or sync has not completed.