diff --git a/_data/toc.yaml b/_data/toc.yaml index 816aa06dfb..8dad56c2b8 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -336,6 +336,8 @@ guides: title: Seccomp security profiles for Docker - path: /engine/security/userns-remap/ title: Isolate containers with a user namespace + - path: /engine/security/rootless/ + title: Run the Docker daemon as a non-root user (Rootless mode) - sectiontitle: Scale your app section: - path: /engine/swarm/ diff --git a/_includes/install-script.md b/_includes/install-script.md index 326ebc7879..645b86e26a 100644 --- a/_includes/install-script.md +++ b/_includes/install-script.md @@ -66,6 +66,13 @@ Docker Engine - Community is installed. It starts automatically on `DEB`-based d `systemctl` or `service` command. As the message indicates, non-root users can't run Docker commands by default. +> **Note**: +> +> To install Docker without root privileges, see +> [Run the Docker daemon as a non-root user (Rootless mode)](/engine/security/rootless.md). +> +> Rootless mode is currently available as an experimental feature. + #### Upgrade Docker after using the convenience script If you installed Docker using the convenience script, you should upgrade Docker diff --git a/engine/security/index.md b/engine/security/index.md index ae57c4ac9c..6856581ff4 100644 --- a/engine/security/index.md +++ b/engine/security/index.md @@ -17,3 +17,7 @@ This section discusses the security features you can configure and use within yo * You can configure secure computing mode (Seccomp) policies to secure system calls in a container. For more information, see [Seccomp security profiles for Docker](seccomp.md). * An AppArmor profile for Docker is installed with the official *.deb* packages. For information about this profile and overriding it, see [AppArmor security profiles for Docker](apparmor.md). + +* You can map the root user in the containers to a non-root user. See [Isolate containers with a user namespace](userns-remap.md). + +* You can also run the Docker daemon as a non-root user. See [Run the Docker daemon as a non-root user (Rootless mode)](rootless.md). \ No newline at end of file diff --git a/engine/security/rootless.md b/engine/security/rootless.md new file mode 100644 index 0000000000..6ec89fa149 --- /dev/null +++ b/engine/security/rootless.md @@ -0,0 +1,278 @@ +--- +description: Run the Docker daemon as a non-root user (Rootless mode) +keywords: security, namespaces, rootless +title: Run the Docker daemon as a non-root user (Rootless mode) +--- + +Rootless mode allows running the Docker daemon and containers as a non-root +user, for the sake of mitigating potentail vulnerabilities in the daemon and +the container runtime. + +Rootless mode does not require root privileges even for installation of the +Docker daemon, as long as [the prerequisites](#prerequiresites) are satisfied. + +Rootless mode was introduced in Docker Engine 19.03. + +> **Note**: +> Rootless mode is an experimental feature and has [limitations](#known-limitations). + +## How it works +Rootless mode executes the Docker daemon and containers inside a user namespace. +This is very similar to [`userns-remap` mode](userns-remap.md), except that +with `userns-remap` mode, the daemon itself is running with root privileges, whereas in +rootless mode, both the daemon and the container are running without root privileges. + +Rootless mode does not use binaries with SETUID bits or file capabilities, +except `newuidmap` and `newgidmap`, which are needed to allow multiple +UIDs/GIDs to be used in the user namespace. + +## Prerequisites + +- `newuidmap` and `newgidmap` need to be installed on the host. These commands + are provided by the `uidmap` package on most distros. + +- `/etc/subuid` and `/etc/subgid` should contain at least 65,536 subordinate + UIDs/GIDs for the user. In the following example, the user `testuser` has + 65,536 subordinate UIDs/GIDs (231072-296607). + +```console +$ id -u +1001 +$ whoami +testuser +$ grep ^$(whoami): /etc/subuid +testuser:231072:65536 +$ grep ^$(whoami): /etc/subgid +testuser::231072:65536 +``` + +### Distribution-specific hint + +> Note: Using Ubuntu kernel is recommended. + +#### Ubuntu +- No preparation is needed. + +- `overlay2` storage driver is enabled by default + ([Ubuntu-specific kernel patch](https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/commit/fs/overlayfs?id=3b7da90f28fe1ed4b79ef2d994c81efbc58f1144)). + +- Known to work on Ubuntu 16.04 and 18.04. + +#### Debian GNU/Linux +- Add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or + `/etc/sysctl.d`) and run `sudo sysctl --system`. + +- To use the `overlay2` storage driver (recommended), run + `sudo modprobe overlay permit_mounts_in_userns=1` + ([Debian-specific kernel patch, introduced in Debian 10](https://salsa.debian.org/kernel-team/linux/blob/283390e7feb21b47779b48e0c8eb0cc409d2c815/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch)). + Put the configuration to `/etc/modprobe.d` for persistence. + +- Known to work on Debian 9 and 10. + `overlay2` is only supported since Debian 10 and needs `modprobe` + configuration described above. + +#### Arch Linux +- Add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or + `/etc/sysctl.d`) and run `sudo sysctl --system` + +#### openSUSE +- `sudo modprobe ip_tables iptable_mangle iptable_nat iptable_filter` is required. + This is might be required on other distros as well depending on the configuration. + +- Known to work on openSUSE 15. + +#### Fedora 31 and later +- Fedora 31 uses cgroup v2 by default, which is not yet supported by the containerd runtime. + Run `sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"` + to use cgroup v1. + +#### Fedora 30 +- No preparation is needed + +#### CentOS 8 +- No preparation is needed + +#### CentOS 7 +- Add `user.max_user_namespaces=28633` to `/etc/sysctl.conf` (or + `/etc/sysctl.d`) and run `sudo sysctl --system`. + +- `systemctl --user` does not work by default. + Run the daemon directly without systemd: + `dockerd-rootless.sh --experimental --storage-driver vfs` + +- Known to work on CentOS 7.7. Older releases require extra configuration + steps. + +- CentOS 7.6 and older releases require [COPR package `vbatts/shadow-utils-newxidmap`](https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/) to be installed. + +- CentOS 7.5 and older releases require running + `sudo grubby --update-kernel=ALL --args="user_namespace.enable=1"` and reboot. + +## Known limitations + +- Only `vfs` graphdriver is supported. However, on Ubuntu and Debian 10, + `overlay2` and `overlay` are also supported. + +- Following features are not supported: + - Cgroups (including `docker top`, which depends on the cgroups) + - AppArmor + - Checkpoint + - Overlay network + - Exposing SCTP ports + +- To use `ping` command, see [Routing ping packets](#routing-ping-packets) + +- To expose privileged TCP/UDP ports (< 1024), see [Exposing privileged ports] + (#exposing-privileged-ports) + +## Install + +The installation script is available at https://get.docker.com/rootless . + +```console +$ curl -fsSL https://get.docker.com/rootless | sh +``` + +Make sure to run the script as a non-root user. + +The script will show the environment variables that are needed to be set: + +```console +$ curl -fsSL https://get.docker.com/rootless | sh +... +# Docker binaries are installed in /home/testuser/bin +# WARN: dockerd is not in your current PATH or pointing to /home/testuser/bin/dockerd +# Make sure the following environment variables are set (or add them to ~/.bashrc): + +export PATH=/home/testuser:/bin:$PATH +export PATH=$PATH:/sbin +export DOCKER_HOST=unix:///run/user/1001/docker.sock + +# +# To control docker service run: +# systemctl --user (start|stop|restart) docker +# +``` + +To install the binaries manually without using the installer, extract +`docker-rootless-extras-.tar.gz` along with `docker-.tar.gz`: +https://download.docker.com/linux/static/stable/x86_64/ + +## Usage + +### Daemon + +Use `systemctl --user` to manage the lifecycle of the daemon: + +```console +$ systemctl --user start docker +``` + +To launch the daemon on system startup, enable systemd lingering: + +```console +$ sudo loginctl enable-linger $(whoami) +``` + +To run the daemon directly without systemd, you need to run +`dockerd-rootless.sh` instead of `dockerd`: + +```console +$ dockerd-rootless.sh --experimental --storage-driver vfs +``` + +As Rootless mode is experimental, currently you always need to run +`dockerd-rootless.sh` with `--experimental`. +You also need `--storage-driver vfs` unless using Ubuntu or Debian 10 kernel. +You don't need to care these flags if you manage the daemon using systemd, as +these flags are automatically added to the systemd unit file. + +Remarks about directory paths: +- The socket path is set to `$XDG_RUNTIME_DIR/docker.sock` by default. + `$XDG_RUNTIME_DIR` is typically set to `/run/user/$UID`. +- The data dir is set to `~/.local/share/docker` by default. +- The exec dir is set to `$XDG_RUNTIME_DIR/docker` by default. +- The daemon config dir is set to `~/.config/docker` (not `~/.docker`, which is + used by the client) by default. + +Other remarks: +- The `dockerd-rootless.sh` script executes `dockerd` in its own user, mount, + and network namespaces. You can enter the namespaces by running + `nsenter -U --preserve-credentials -n -m -t $(cat $XDG_RUNTIME_DIR/docker.pid)`. +- `docker info` shows `rootless` in `SecurityOptions` +- `docker info` shows `none` as `Cgroup Driver` + +### Client + +You need to set the socket path explicitly. + +```console +$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock +$ docker run -d nginx +``` + +## Tips + +### Rootless Docker in Docker + +To run Rootless Docker inside "rootful" Docker, use `docker:-dind-rootless` +image instead of `docker:-dind` image. + +```console +$ docker run -d --name dind-rootless --privileged docker:19.03-dind-rootless --experimental +``` + +`docker:-dind-rootless` image runs as a non-root user (UID 1000). +However, `--privileged` is required for disabling seccomp, AppArmor, and mount +masks. + +### Expose Docker API socket via TCP + +To expose the Docker API socket via TCP, you need to launch `dockerd-rootless.sh` +with `DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp"`. + +```console +$ DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" \ + dockerd-rootless.sh --experimental \ + -H tcp://0.0.0.0:2376 \ + --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem +``` + +### Routing ping packets + +`ping` command does not work by default. + +Add `net.ipv4.ping_group_range = 0 2147483647` to `/etc/sysctl.conf` (or +`/etc/sysctl.d`) and run `sudo sysctl --system` to allow using `ping`. + +### Exposing privileged ports + +To expose privileged ports (< 1024), set `CAP_NET_BIND_SERVICE` on `rootlesskit` binary. + +```console +$ sudo setcap cap_net_bind_service=ep $HOME/bin/rootlesskit +``` + +Or add `net.ipv4.ip_unprivileged_port_start=0` to `/etc/sysctl.conf` (or +`/etc/sysctl.d`) and run `sudo sysctl --system`. + +### Limiting resources + +Currently rootless mode ignores cgroup-related `docker run` flags such as +`--cpus` and `memory`. + +However, traditional `ulimit` and [`cpulimit`](https://github.com/opsengine/cpulimit) +can be still used, though they work in process-granularity rather than in container-granularity. + +### Changing network stack + +`dockerd-rootless.sh` uses [slirp4netns](https://github.com/rootless-containers/slirp4netns) +(if installed) or [VPNKit](https://github.com/moby/vpnkit) as the network stack +by default. + +These network stacks run in userspace and might have performance overhead. +See [RootlessKit documentation](https://github.com/rootless-containers/rootlesskit/tree/v0.7.0#network-drivers) for further information. + +Optionally, you can use `lxc-user-nic` instead for the best performance. +To use `lxc-user-nic`, you need to edit [`/etc/lxc/lxc-usernet`](https://github.com/rootless-containers/rootlesskit/tree/v0.7.0#--netlxc-user-nic-experimental) +and set `$DOCKERD_ROOTLESS_ROOTLESSKIT_NET=lxc-user-nic`. diff --git a/engine/security/security.md b/engine/security/security.md index 1b26ee2992..c451d61d6d 100644 --- a/engine/security/security.md +++ b/engine/security/security.md @@ -79,8 +79,8 @@ started in 2006, and initially merged in kernel 2.6.24. Running containers (and applications) with Docker implies running the Docker daemon. This daemon requires `root` privileges unless you opt-in -to [Rootless mode](https://github.com/docker/engine/blob/v19.03.0-rc3/docs/rootless.md) -(experimental), and you should therefore be aware of some important details. +to [Rootless mode](rootless.md) (experimental), and you should therefore +be aware of some important details. First of all, **only trusted users should be allowed to control your Docker daemon**. This is a direct consequence of some powerful Docker diff --git a/install/linux/linux-postinstall.md b/install/linux/linux-postinstall.md index 117839a8c3..649c852163 100644 --- a/install/linux/linux-postinstall.md +++ b/install/linux/linux-postinstall.md @@ -27,6 +27,13 @@ creates a Unix socket accessible by members of the `docker` group. > [*Docker Daemon Attack Surface*](/engine/security/security.md#docker-daemon-attack-surface). {: .warning} +> **Note**: +> +> To run Docker without root privileges, see +> [Run the Docker daemon as a non-root user (Rootless mode)](/engine/security/rootless.md). +> +> Rootless mode is currently available as an experimental feature. + To create the `docker` group and add your user: 1. Create the `docker` group.