Como proibir o Daemon Docker de montar o sistema de arquivos raiz do host no contêiner

Eu tenho a seguinte configuração de contêiner.

Em um servidor bare metal, dois Daemons Docker estão instalados e em execução.

  1. Daemon Principal Do Docker Executa meus contêineres de aplicativos expondo 80/443 ao mundo exterior.
  2. Plugin Docker Daemon Executa alguns contêineres fornecidos pelo cliente que se comunicam com meu aplicativo via 80/443.

Eu gostaria de dar ao cliente acesso à API (2376) do Plugin Docker Daemon para que o cliente possa implantar / iniciar / parar seus próprios contêineres. O cliente só terá acesso à API e não ao Host (SSH).

O problema que enfrento atualmente é, e se os clientes executarem um contêiner que faça algo inseguro como docker run -v /:/host/root Ubuntu rm -rf /host/root.

Minha pergunta é o que posso fazer para evitar o Plugin Docker Daemon da raiz de montagem / ou qualquer outro diretório fora /home/user/,

  • É uma opção para iniciar o Daemon Docker em /home/user/?
  • Posso usar alguns LSM (Linux security Modules SELinux/Apparmor) magic para evitar que o daemon docker monte alguns ou todos os caminhos do host, exceto users home ou var/docker/libs?
  • Poder --userns-remap ajude-me a alcançar meu objetivo?
  • Existem outras opções disponíveis, exceto VMs?

O servidor pertence inteiramente a um único cliente. Portanto, a segurança ou vazamento de dados não é minha principal preocupação. O que eu realmente quero evitar é que alguém em Plugin Daemon está fazendo algo estúpido, que influencia meus contêineres que funcionam em Daemon Principal Do Docker. Eu gostaria de manter o Lean e manter o fluxo de trabalho apenas do docker e não vou configurar um fluxo de trabalho extra para a criação de VM.

SELinux impedirá que qualquer coisa não rotulada corretamente seja montada como um volume dentro de um contêiner docker, como prova, aqui usando um único arquivo, a mesma política se aplica aos diretórios:

$ sestatusSELinux status:                 enabledSELinuxfs mount:                /sys/fs/selinuxSELinux root directory:         /etc/selinuxLoaded policy name:             targetedCurrent mode:                   enforcingMode from config file:          enforcingPolicy MLS status:              enabledPolicy deny_unknown status:     allowedMax kernel policy version:      30

Usando o arquivo de amostra:

$ cat sample_script.sh echo 'Hello, world'

Seu contexto de segurança padrão é:

$ ls -lrtZ sample_script.sh -rw-------. 1 david david unconfined_u:object_r:user_home_t:s0 20 Oct  3 17:18 sample_script.sh

Tentar usar esse arquivo dentro de um contêiner falha conforme o esperado:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.shbash: sample_script.sh: Permission denied

E uma negação AVC será registrada:

$ sudo ausearch -m avc -ts recenttime->Mon Oct  3 17:39:28 2016type=AVC msg=audit(1475512768.444:784): avc:  denied  { read } for  pid=28720 comm="bash" name="sample_script.sh" dev="dm-13" ino=101062112 scontext=system_u:system_r:svirt_lxc_net_t:s0:c457,c992 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

Depois de alterar o contexto de segurança para um Docker pode usar:

$ sudo chcon -Rt svirt_sandbox_file_t sample_script.sh$ ls -lrtZ sample_script.sh -rw-------. 1 david david unconfined_u:object_r:svirt_sandbox_file_t:s0 20 Oct  3 17:18 sample_script.sh 

O contêiner agora tem acesso ao arquivo:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.shHello, world

Mais informações sobre Docker e SELinux no documentação oficial da Red Hat e artigo por Dan Walsh.

Sim, SELinux impede esse ataque. Mostrar que não funciona faz uma boa demonstração. Use o Docker em uma distro baseada em Red Hat para obter acesso à proteção SELinux. Em distros baseadas em Debian, SELinux historicamente não foi bem mantido.

E o Apparmor também é possível lá?

Não acredito. Eu nunca ouvi falar de AppArmor ser capaz de fazer algo assim. É uma tecnologia bastante diferente e muito menos segura, você sabe.