シリーズ2回めです。今回もベースは自分のためのまとめであり、調査不足な点はぜひ突っ込んでください...。
前回:
今回から、User Namespace の各コンテナでの対応状況を見ていく。
コンテナの非特権に対する対応
前提として、前回のUser Namespaceが解決する課題を再掲する。
主に以下の二つの課題が解決できる。
- もし特権を付与したコンテナをunjailされた場合等に、ホストのファイルシステムを操作されるなどの被害を最低限にしたい
- 一般ユーザで、なるべく安全にコンテナを作成したい
前者と後者は、関連してはいるが実現方法が少し異なることは留意すべき。rootless Dockerや一般ユーザでのlxc-startは後者に、LXDによるUser Namespaceの分離は前者に属すると考えられそう。その辺りを踏まえて、各種コンテナランタイムでの対応状況をまとめておく。
Docker (rootless mode)
現在のDocker(Moby)には、experimentalという扱いだがrootless modeがある。公式のブログに詳しい:
インストールするとそのユーザーに紐づくsystemdサービスとしてdockerd-rootless.shが立ち上がる。関連する環境変数を設定して、スッと使える。スッとrootlessな環境に入った様子です。
$ export PATH=/home/vagrant/bin:$PATH $ export DOCKER_HOST=unix:///run/user/1000/docker.sock $ docker run -ti debian:stretch-slim bash root@daa6c479988c:/# ls -l total 64 drwxr-xr-x 2 root root 4096 Feb 4 00:00 bin drwxr-xr-x 2 root root 4096 Jan 22 13:47 boot drwxr-xr-x 5 root root 360 Feb 27 10:31 dev drwxr-xr-x 1 root root 4096 Feb 27 10:31 etc drwxr-xr-x 2 root root 4096 Jan 22 13:47 home drwxr-xr-x 8 root root 4096 Feb 4 00:00 lib drwxr-xr-x 2 root root 4096 Feb 4 00:00 lib64 drwxr-xr-x 2 root root 4096 Feb 4 00:00 media drwxr-xr-x 2 root root 4096 Feb 4 00:00 mnt drwxr-xr-x 2 root root 4096 Feb 4 00:00 opt dr-xr-xr-x 143 nobody nogroup 0 Feb 27 10:31 proc drwx------ 2 root root 4096 Feb 4 00:00 root drwxr-xr-x 3 root root 4096 Feb 4 00:00 run drwxr-xr-x 2 root root 4096 Feb 4 00:00 sbin drwxr-xr-x 2 root root 4096 Feb 4 00:00 srv dr-xr-xr-x 13 nobody nogroup 0 Feb 27 07:44 sys drwxrwxrwt 2 root root 4096 Feb 4 00:00 tmp drwxr-xr-x 10 root root 4096 Feb 4 00:00 usr drwxr-xr-x 11 root root 4096 Feb 4 00:00 var
細かいところ
- 中央のデーモン含めて全てユーザ権限でセットアップできる
/proc
/sys
などはnobodyの所属になる(その下の/proc/1/*
などは当然rootとして見える)- cgroupはruncのcgroup v2対応待ちだそう 。今だと
--cpu-period=100000 --cpu-quota=30000
のようなオプションでコンテナを立ち上げても無視される。現在の/proc/$PID/cgroup
の様子。
vagrant@ubuntu-bionic:~$ cat /proc/3916/cgroup 12:devices:/user.slice 11:memory:/user.slice 10:cpu,cpuacct:/user.slice 9:freezer:/ 8:pids:/user.slice/user-1000.slice/user@1000.service 7:rdma:/ 6:net_cls,net_prio:/ 5:perf_event:/ 4:hugetlb:/ 3:blkio:/user.slice 2:cpuset:/ 1:name=systemd:/user.slice/user-1000.slice/user@1000.service/docker.service/6ad64d532692c26bce327e278b7dc8882b606072dba9cb2d184165c60b250c77 0::/user.slice/user-1000.slice/user@1000.service/docker.service
LXC の非特権コンテナ
Ubuntu Bionic(lxc-3.0.3)においては結構前準備が多いのでそれも合わせて。
/home/vagrant/.config/lxc/default.conf
を以下のように編集する。idmapの値は、ちゃんと /etc/sub{u,g}id
とあっているか確認すること。
lxc.net.0.type = veth lxc.net.0.link = lxcbr0 lxc.net.0.flags = up lxc.net.0.hwaddr = 00:16:3e:11:22:33 lxc.idmap = u 0 165536 65536 lxc.idmap = g 0 165536 65536
## 確認の例 $ grep vagrant /etc/sub{u,g}id /etc/subuid:vagrant:165536:65536 /etc/subgid:vagrant:165536:65536
/etc/lxc/lxc-usernet
も編集する。
# USERNAME TYPE BRIDGE COUNT vagrant veth lxcbr0 10
/etc/pam.d/common-session{,-noninteractive}
に pam_cgfs.so
の行が含まれるか確認する。入っていない、もしくは有効でないとLXC 3.0.3の場合SEGVしてしまう。場合により再ログインする。
そうしたらようやく lxc-create -t download -n ippanjin-1 -- -d ubuntu -r bionic -a amd64
な感じでイメージを作成できる。
Setting up the GPG keyring Downloading the image index Downloading the rootfs Downloading the metadata The image cache is now ready Unpacking the rootfs --- You just created an Ubuntu bionic amd64 (20190227_07:42) container. To enable SSH, run: apt install openssh-server No default root or user password are set by LXC.
コンテナに入った様子。
$ lxc-start -n ippanjin-1 -F -- bash bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell root@ippanjin-1:/# ls -l / total 64 drwxr-xr-x 2 root root 4096 Feb 27 08:11 bin drwxr-xr-x 2 root root 4096 Apr 10 2014 boot drwxr-xr-x 4 root root 400 Feb 27 12:05 dev drwxr-xr-x 66 root root 4096 Feb 27 11:54 etc drwxr-xr-x 3 root root 4096 Feb 27 08:12 home drwxr-xr-x 12 root root 4096 Feb 27 08:11 lib drwxr-xr-x 2 root root 4096 Feb 27 08:10 lib64 drwxr-xr-x 2 root root 4096 Feb 27 08:07 media drwxr-xr-x 2 root root 4096 Apr 10 2014 mnt drwxr-xr-x 2 root root 4096 Feb 27 08:07 opt dr-xr-xr-x 144 nobody nogroup 0 Feb 27 12:05 proc drwx------ 2 root root 4096 Feb 27 11:55 root drwxr-xr-x 3 root root 4096 Feb 27 11:53 run drwxr-xr-x 2 root root 4096 Feb 27 08:11 sbin drwxr-xr-x 2 root root 4096 Feb 27 08:07 srv dr-xr-xr-x 13 nobody nogroup 0 Feb 27 07:44 sys drwxrwxrwt 2 root root 4096 Feb 27 08:08 tmp drwxr-xr-x 10 root root 4096 Feb 27 08:07 usr drwxr-xr-x 12 root root 4096 Feb 27 08:10 var
細かいところ
- こちらも一部設定ファイル以外は一般ユーザで動作させられることが分かる。
- /proc /sys の所有者問題はここにも残る。
- cgroup は使える。 see also: http://gihyo.jp/admin/serial/01/linux_containers/0036
vagrant@ubuntu-bionic:~$ cat /proc/13621/cgroup 12:devices:/user.slice 11:memory:/user/vagrant/0/lxc/ippanjin-1 10:cpu,cpuacct:/user.slice 9:freezer:/user/vagrant/0/lxc/ippanjin-1 8:pids:/user.slice/user-1000.slice/session-43.scope 7:rdma:/ 6:net_cls,net_prio:/ 5:perf_event:/ 4:hugetlb:/ 3:blkio:/user.slice 2:cpuset:/ 1:name=systemd:/user.slice/user-1000.slice/session-43.scope/lxc/ippanjin-1 0::/user.slice/user-1000.slice/session-43.scope
時間切れ。次回予告は以下。