Os namespaces do usuário são oficialmente adicionados ao Docker ver. 1.10, que permite ao sistema host mapear o seu próprio uid
e gid
para alguns processos diferentes uid
e gid
para 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-machine
comando (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, /etc
do 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/docker
e adicione --userns-remap=default
próximo a /usr/local/bin/docker daemon
este:
$ 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
- Os namespaces de usuário chegaram ao Docker!
- Melhorias de segurança do Docker Engine 1.10
- Docker e –userns-remap, como gerenciar as permissões de volume para compartilhar dados entre o host e o contêiner?
- O Docker não inicia contêineres no CentOS quando os namespaces do usuário são ativados
- O que vem por aí para contêineres? Namespaces de usuário