尝试使用[Docker]无特权Docker
无根 Docker 是什么
根無しモード(Rootless mode)は、Dockerデーモンとコンテナをroot以外のユーザが実行できるようにすることで、デーモンやコンテナランタイムに存在する可能性のあるセキュリティ上の脆弱性を回避します。
这次的环境
- Ubuntu Server 20.04 on VMware ESXi
挑战现在开始
首先,需要进行事前准备。
引入 uidmap
在主机上必须安装 newuidmap 与 newgidmap。
根据说明,我会安装它。
$ sudo apt install -y uidmap
如果没有安装这个,你在安装 Docker 的时候需要安装它。
# Installing stable version 19.03.12
# Missing system requirements. Please run following commands to
# install the requirements and run this installer again.
# Alternatively iptables checks can be disabled with SKIP_IPTABLES=1
cat <<EOF | sudo sh -x
apt-get install -y uidmap
EOF
因为被说了所以要记得不要忘记放进去。(个人经历)
确认用户标识/组标识 (UID/GID)
/etc/subuid 和/etc/subgid应该至少包含65,536个子用户UID/GID。
因为这是这样的,我们最好确认一下。
$ grep ^$(whoami): /etc/subuid
dev:100000:65536
$ grep ^$(whoami): /etc/subgid
dev:100000:65536
如果两个数量中都包含了65536,那就是可以的。
安装
可以像普通的Docker一样很容易地进行一行代码引入。
$ curl -fsSL get.docker.com/rootless | sh
# Installing stable version 19.03.12
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 57.9M 100 57.9M 0 0 18.0M 0 0:00:03 0:00:03 --:--:-- 18.0M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 18.3M 100 18.3M 0 0 6245k 0 0:00:03 0:00:03 --:--:-- 6245k
# starting systemd service
● docker.service - Docker Application Container Engine (Rootless)
Loaded: loaded (/home/dev/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
Active: active (running) since Sat 2020-07-25 08:07:23 UTC; 21ms ago
Docs: https://docs.docker.com
Main PID: 45635 (rootlesskit)
CGroup: /user.slice/user-1000.slice/user@1000.service/docker.service
tq45635 rootlesskit --net=vpnkit --mtu=1500 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run /home/dev/bin/dockerd-rootless.sh --experimental --storage-driver=overlay2
tq45647 /proc/self/exe --net=vpnkit --mtu=1500 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run /home/dev/bin/dockerd-rootless.sh --experimental --storage-driver=overlay2
mq45656 newgidmap 45647 0 1000 1 1 100000 65536
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + which slirp4netns
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + [ -z ]
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + which vpnkit
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + net=vpnkit
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + [ -z ]
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + mtu=1500
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + [ -z ]
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + _DOCKERD_ROOTLESS_CHILD=1
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + export _DOCKERD_ROOTLESS_CHILD
Jul 25 08:07:23 docker dockerd-rootless.sh[45635]: + exec rootlesskit --net=vpnkit --mtu=1500 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run /home/dev/bin/dockerd-rootless.sh --experimental --storage-driver=overlay2
Client: Docker Engine - Community
Version: 19.03.12
API version: 1.40
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:42:53 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.12
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:49:35 2020
OS/Arch: linux/amd64
Experimental: true
containerd:
Version: v1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
# Docker binaries are installed in /home/dev/bin
# WARN: dockerd is not in your current PATH or pointing to /home/dev/bin/dockerd
# Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/home/dev/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock
#
# To control docker service run:
# systemctl --user (start|stop|restart) docker
#
环境变量将被添加以使得能够使用docker命令,虽然已经完成了安装但是这样无法使用docker命令,因为它并没有安装在PATH路径下。
$ export PATH=/home/dev/bin:$PATH
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
让我们实际确认一下。
$ docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 19.03.12
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: false
Logging Driver: json-file
Cgroup Driver: none
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
rootless
Kernel Version: 5.4.0-42-generic
Operating System: Ubuntu 20.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 7.774GiB
Name: docker
ID: NURI:7LP5:IHUJ:VSSV:6E5W:VMLS:4D52:X5EJ:CB24:CDJ2:OMAO:LMWB
Docker Root Dir: /home/dev/.local/share/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
确认了可以使用docker命令,以及Security Options中包含rootless的点。
试着使用一下
先试试运行Nginx吧。
$ docker run -dP --name nginx nginx
11cd14bb3bf8d4b99aa46be825bfd7f51143bc578e68ef265f3add1baa0b19ed
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11cd14bb3bf8 nginx "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 0.0.0.0:32768->80/tcp nginx
$ curl -s localhost:32768 | head -n 5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
我确认了端口转发正常工作。
$ ps -aux | grep docker
dev 1519 0.0 0.0 112232 6856 ? Ssl 10:18 0:00 rootlesskit --net=vpnkit --mtu=1500 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run /home/dev/bin/dockerd-rootless.sh --experimental --storage-driver=overlay2
dev 1528 7.4 0.1 112872 12060 ? Sl 10:18 0:05 /proc/self/exe --net=vpnkit --mtu=1500 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run /home/dev/bin/dockerd-rootless.sh --experimental --storage-driver=overlay2
dev 1562 20.5 0.8 1638352 67892 ? Sl 10:18 0:14 dockerd --experimental --storage-driver=overlay2
dev 1583 1.1 0.2 1241920 23784 ? Ssl 10:18 0:00 containerd --config /run/user/1000/docker/containerd/containerd.toml --log-level info
dev 1875 0.0 0.0 106976 4780 ? Sl 10:19 0:00 /home/dev/bin/rootlesskit-docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.2 -container-port 80
dev 1880 0.0 0.0 103372 2364 ? Sl 10:19 0:00 docker-proxy -container-ip 172.17.0.2 -container-port 80 -host-ip 127.0.0.1 -host-port 32768 -proto tcp
dev 1891 0.0 0.0 108872 4604 ? Sl 10:19 0:00 containerd-shim -namespace moby -workdir /home/dev/.local/share/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/2f657a2a65b754ff9bd59254f1cd36b745c3f2679aa795c474e6ba29ead4e560 -address /run/user/1000/docker/containerd/containerd.sock -containerd-binary /home/dev/bin/containerd -runtime-root /run/user/1000/docker/runtime-runc
dev 1976 0.0 0.0 5192 740 pts/0 S+ 10:20 0:00 grep --color=auto docker
而且,我也确认了它是由dev用户而不是root用户执行的。