Usando namespaces de usuário no Docker

Os namespaces do usuário são oficialmente adicionados ao Docker ver. 1.10, que permite ao sistema host mapear o seu próprio uide gidpara alguns processos diferentes uide gidpara os contêineres. Esta é uma grande melhoria na segurança do Docker. Vou mostrar um exemplo do problema que os namespaces de usuário podem resolver e, a seguir, mostrar como ativá-lo.

Criação de uma máquina Docker

Se você já tem uma máquina docker para experimentar o Namaspaces do usuário, pode pular esta etapa. Estou usando o Docker Toolbox no meu Macbook, então simplesmente crio uma Docker Machine no VirutalBox com o docker-machinecomando (por exemplo, hostname = host1):

# Create host1
$ docker
-machine create --driver virtualbox host1

# Login to host1
$ docker
-machine ssh host1

Compreender o que um usuário não root pode fazer se os namespaces do usuário não estiverem habilitados

Antes de configurar os namespaces do usuário, vamos ver qual é o problema. O que havia de errado com o Docker? Em primeiro lugar, um dos grandes benefícios de usar o Docker é que o usuário pode ter privilégios de root em contêineres para que possa instalar facilmente os pacotes de software. Mas isso é como uma faca de dois gumes na tecnologia de contêiner Linux. Com um pequeno toque, o usuário não root pode obter acesso root, por exemplo, /etcdo sistema host. Veja como fazer.

# Run a container and mount host1's /etc onto /root/etc
$ docker run
--rm -v /etc:/root/etc -it ubuntu

# Make some change on /root/etc/hosts
root@34ef23438542
:/# vi /root/etc/hosts

# Exit from the container
root@34ef23438542
:/# exit

# Check /etc/hosts
$ cat
/etc/hosts

Como você pode ver, é surpreendentemente fácil e é óbvio que o Docker não foi projetado para computadores compartilhados. Mas agora, com os namespaces de usuário, o Docker permite que você evite esse problema.

Habilitando namespaces de usuário

# Create a user called "dockremap"
$ sudo adduser dockremap


# Setup subuid and subgid
$ sudo sh
-c 'echo dockremap:500000:65536 > /etc/subuid'
$ sudo sh
-c 'echo dockremap:500000:65536 > /etc/subgid'

E então, abra /etc/init.d/dockere adicione --userns-remap=defaultpróximo a /usr/local/bin/docker daemoneste:


$ sudo vi
/etc/init.d/docker
:
:
/usr/local/bin/docker daemon --userns-remap=default -D -g "$DOCKER_DIR" -H unix:// $DOCKER_HOST $EXTRA_ARGS >> "$DOCKER_LOGFILE" 2>&1 &
:
:

E reinicie o Docker:

$ sudo /etc/init.d/docker restart

Isso é tudo!

Nota: Se você estiver usando o CentOS 7, há duas coisas que você precisa saber.

1. Os namespaces de usuário não estão habilitados no kernel por padrão. Você pode habilitá-lo executando o seguinte comando e reiniciar o sistema.

sudo grubby --args="user_namespace.enable=1" 
--update-kernel=/boot/vmlinuz-3.10.0-XXX.XX.X.el7.x86_64

2. CentOS 7 usa systemctl para gerenciar serviços, então o arquivo que você precisa editar é ./usr/lib/systemd/system/docker.service

Verificar se os namespaces do usuário estão funcionando corretamente

Se tudo estiver configurado corretamente, você não poderá editar o host1 de um contêiner. Então, vamos dar uma olhada./etc

# Create a container and mount host1's /etc to container's /root/etc
$ docker run
--rm -v /etc:/root/etc -it ubuntu

# Check the owner of files in /root/etc, which should be "nobody nogroup".
root@d5802c5e670a
:/# ls -la /root/etc
total
180
drwxr
-xr-x 11 nobody nogroup 1100 Mar 21 23:31 .
drwx
------ 3 root root 4096 Mar 21 23:50 ..
lrwxrwxrwx
1 nobody nogroup 19 Mar 21 23:07 acpi -> /usr/local/etc/acpi
-rw-r--r-- 1 nobody nogroup 48 Mar 10 22:09 boot2docker
drwxr
-xr-x 2 nobody nogroup 60 Mar 21 23:07 default
:
:

# Try creating a file in /root/etc
root@d5802c5e670a
:/# touch /root/etc/test
touch
: cannot touch '/root/etc/test': Permission denied

# Try deleting a file
root@d5802c5e670a
:/# rm /root/etc/hostname
rm
: cannot remove '/root/etc/hostname': Permission denied

Certo, ótimo. É assim que os namespaces de usuário funcionam.

Referências