Protegendo Docker

Devido ao mau uso de ferramentas que utilizam containers, diversas aplicações e hosts estão se tornando vulneráveis. Vários fabricantes tem soluções usando containers e eles estão tentando mudar o jogo colocando a segurança como um dos principais argumentos para a adoção desta tecnologia.

Containers são basicamente duas tecnologias do kernel Linux (cgroups e namespaces) com um filesystem mais sofisticado. Eles são uma forma de criar isolamento entre processos e garantir um controle de recursos usando tecnologias já fornecidas pelo kernel, portanto o objetivo desta tecnologia tem uma relação clara com segurança.

Contudo, com a popularização dos containers principalmente devido à ferramenta Docker, os principais ganhos que a maioria dos usuários notaram não foram em segurança e sim na forma como Docker traz reprodutibilidade, fácil rollback e a simplicidade de orquestrar e escalar aplicações.

O Docker já tem diversas features para melhorar a segurança como a possibilidade de restringir capabilities, utilizar SELinux, AppArmor e seccomp. Estas opções são bem simples de aprender e ajudam bastante no isolamento do seu container.

De maneira geral, um usuário root tem acesso a todas as Linux capabilities podendo criar arquivos, configurar permissões, montar file systems, etc. Por padrão, o Docker vem com algumas capabilities configuradas como cap_chown, cap_dac_override, entre outras. É impossível achar um padrão ótimo para todas as aplicações: o melhor do ponto de vista de segurança é deixar somente o necessário para sua aplicação executar de forma normal.

Outro mecanismo para aumentar a segurança ao usar containers é o SELinux. Este é um sistema de marcação de labels, onde todo processo, arquivos e diretórios tem uma label. Basicamente, existem várias políticas e regras de controle entre um processo e um objeto do sistema e o kernel garante que as políticas serão cumpridas. O Docker gerencia todas as labels automaticamente se estiver configurado no daemon “ — selinux-enabled”.

Mais uma forma aumentar a segurança é usando AppArmor: ele é um LSM (Linux Security Module) semelhante ao SELinux, com a diferença que ele não utiliza labels e sim o caminho para o diretório ou arquivo. O AppArmor utiliza profiles que são carregados no kernel. O Docker tem um profile específico para os containers. Para utilizar o AppArmor com o Docker basta adicionar “ — security-opt apparmor=docker-default” ao executar o docker run.

Temos também uma maneira de filtrar as system calls que um processo pode utilizar usando seccomp. Seccomp é bem simples e basta criar um arquivo no formato json com a system call e ação que será tomada. Além disso, ele permite configurar uma ação padrão, podendo ser permitir ou bloquear todas as system calls. Desde a versão 1.12 do Docker, este vem com um profile padrão podendo ser alterado na execução do docker run passando o seguinte argumento “ — security-opt seccomp:custom.json”.

Docker tem uma outra feature importante que é a opção “read-only” ao iniciar um container: com isto garantimos que nada vai ser alterado da imagem padrão após o container iniciar.

Além disso, a Docker recomenda a utilização do grsecurity que é uma série de patches de segurança para o kernel Linux.

Lembrando também que é muito importante remover binários que não serão utilizados pelo programa em execução, uma vez que vários exploits utilizam o setuid para escalar privilégios. Também é importante lembrar de evitar utilizar o usuário root, preferindo a utilização de usuários não privilegiados e escalar somente quando for estritamente necessário.

Alguns cuidados precisam ser tomados ao utilizar imagens de terceiros de repositórios públicos, e sempre é importante analisar as imagens para verificar se estas não têm algum tipo de vulnerabilidade e se as mesmas estão utilizando as fontes oficiais para o download dos arquivos necessários. Dois scanners bastante utilizados e open source são OpenSCAP e o clair.

Dependendo da criticidade do ambiente, vale a pena manter um repositório privado de imagens. Não obstante, é importante sempre assinar as imagens geradas garantindo sua veracidade além de construir um pipeline com testes frequentes em busca de novas vulnerabilidades.

Essas são algumas dicas para aumentar a proteção de sistemas que utilizam Docker. No futuro é bem provável que o Docker seja ainda mais seguro, visto que alguns componentes chaves como runc estão focando bastante em diminuir os privilégios necessários para executar containers. Com isso, é bem provável que não seja necessário executar o daemon do Docker como root, ou pelo menos tenha uma opção com algumas restrições para executar o Docker com modo usuário.