###2016/07/01:要想限制容器里用户的权限,有两种方法:linux
具体的就是,指定容器里用户的uid:gid,使得容器里压根不存在root用户。docker
$ docker run -it -u 1000:1000 ubuntu groups: cannot find name for group ID 1000 #这个错误不要紧 I have no name!@fcaadb40ddd0:/$ id #执行id命令看看结果。 uid=1000 gid=1000 groups=1000
(这里的uid:gid和主机的不同,具体的怎么关联的不太清楚。通常来讲这个就足够了,可是也许会有什么应用须要root权限,这时就须要下一步要说的方法来限制权限了)json
就算容器里有个孙悟空突破了限制作了玉皇大帝,那也翻不出如来佛的手掌。 具体的就是,把容器里的root等用户映射成主机那边的指定的一片uid:gid。ubuntu
###2017/01/20:突然想起来看看,容器里以root运行的进程,在外面看来究竟是什么?是一个进程。那是什么用户身份呢?也是root,只是capabilities受到不少限制,理论上依然危险。app
在docker里以root身份运行sleep 12345ssh
docker@somehost:~$ docker run -it busybox / # id uid=0(root) gid=0(root) groups=10(wheel) / # sleep 12345
在容器外面查看这个sleep是什么进程,什么用户身份?也是root。tcp
docker@somehost:~$ ps -ef |grep 12345 root 1997 1980 0 09:44 pts/1 00:00:00 sleep 12345
查看该进程的权限信息,就可以发现capabilities是受限制的,可是理论上仍是能够钻漏洞影响到容器外的。ide
docker@somehost:~$ cat /proc/1997/status |grep Cap ... CapEff: 00000000a80425fb ...
用capsh工具查看00000000a80425fb就明白意思。这个root收到了限制。工具
最近用的docker-machine版本是0.8.2,docker 1.12.5。发现docker-machine里面已经默认建立好了dockremap这个用户了,连/etc/subuid /etc/subgid里都准备好了。结果,只要修改活着建立/etc/docker/daemon.json,加上{"userns-remap":"default"}就能够了,重启动docker-machine就能够生效。ui
确认
docker@somehost:~$ cat /etc/subuid dockremap:165536:65536 docker@somehost:~$ cat /etc/subgid dockremap:165536:65536
准备
docker@somehost:~$ cat /etc/docker/daemon.json { "userns-remap": "default" }
若是还不存在dockremap用户,那么就运行这个命令生成用户dockremap:
sudo adduser --system dockremap
重启动
docker-machine restart somehost docker-machine ssh somehost
在docker里以root身份运行sleep 12345
docker@somehost:~$ docker run -it busybox / # id uid=0(root) gid=0(root) groups=10(wheel) / # sleep 12345
在容器外面查看这个sleep是什么进程,什么用户身份
docker@somehost:~$ ps -ef |grep 12345 165536 2360 2344 0 09:36 ? 00:00:00 sleep 12345
就是这个165536,说明生效了,用户身份不是之前的0(root)了。
####2016/?/?: 我要体验的就是第2种功能,刚出来半年,由于uid映射只能手动作,并且是针对docker daemon设定的,因此默认是不开启的,也没法从普通的docker run命令里指定。
参照了docker-for-your-users-introducing-user-namespace。
主要是docker daemon加个选项 --userns-remap=test_user:test_group and add /etc/subuid
/etc/subgid
若是按照docker官方文档说的--userns-remap=default(就是让docker daemon建立dockremap
用户),也会报错说找不到用户,据有的用户反映是tiny core linux里的adduser和普通的linux发行版不同,我没仔细查。
$ docker-machine ssh rethink # rethink is my vm name, please change it to yours. ... docker@rethink:~$ sudo vi /var/lib/boot2docker/profile ... EXTRA_ARGS=' --label provider=virtualbox --userns-remap=test_user:test_group #####this is what i add##### ' ... docker@rethink:~$ exit
then restart by docker-machine restart rethink
, cause same error Maximum number of retries (10) exceeded
(看/var/lib/boot2docker/docker.log能看到错误是说用户找不到), docker daemon is not started,
then add user/group,
docker@rethink:~$ sudo addgroup -g 20 test_group docker@rethink:~$ sudo adduser -G test_group -SDHu 501 test_user
then prepare uid/gid range for container
docker@rethink:~$ sudo -c "echo test_user:100000:65536 > /etc/subuid" docker@rethink:~$ sudo -c "echo test_group:200000:65536 > /etc/subgid"
then start docker daemon
docker@rethink:~$ sudo /usr/local/bin/docker daemon -D -g "/var/lib/docker" -H unix:// -H tcp://0.0.0.0:2376 --label provider=virtualbox \ --userns-remap=test_user:test_group --tlsverify --tlscacert=/var/lib/boot2docker/ca.pem --tlscert=/var/lib/boot2docker/server.pem --tlskey=/var/lib/boot2docker/server-key.pem -s aufs ... INFO[0000] User namespaces: ID ranges will be mapped to subuid/subgid ranges of: test_user:test_group DEBU[0000] Creating user namespaced daemon root: /mnt/sda1/var/lib/docker/100000.200000 ...
Then i run docker container. There are strange thing here: previously used docker image will be treated as "not exist", get downloaded again.
$ docker run -it -v /bin:/xxx busybox Unable to find image 'busybox:latest' locally latest: Pulling from library/busybox 8ddc19f16526: Pull complete Digest: sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6 Status: Downloaded newer image for busybox:latest / # id uid=0(root) gid=0(root) groups=10(wheel) / # ls /xxx VBoxClient cat dd echo gunzip ln mount printenv ... ... / # echo hi > /xxx/a sh: can't create /xxx/a: Permission denied
很好, container里的root只能老老实实的以host os里的test_user身份运行了。
不过一旦重启动就泡汤了(仍是老错误说用户找不到), 出现问题后,请进去把/var/lib/boot2docker/profile里的改动给恢复就好了。
重启动致使的问题很好理解,八成是由于docker-machine的VM是从关盘(boot2docker.iso)里启动的,我作的修改大部分都是在iso的内存盘里作的,并没保存到iso里,这是docker-machine的一个问题,有人提了建议了。