Pode executar seus containers como root?

Standard

Tenho visto ultimamente muitas pessoas preocupadas com questões de segurança do Docker. Isso é algo muito louvável e até mesmo esperado para uma tecnologia que parece se consolidar rapidamente em nosso mercado, mas como todo processo de consolidação, acho que temos alguns equívocos em como esse cuidado de segurança é aplicado.

Caso discorde da minha opinião, por favor comente. Vamos iniciar um debate franco sobre esse assunto.

0812.sdt-docker

O modelo de disponibilização do Docker tem como prerrogativa ser ágil, ou seja, evitar que seu tempo seja consumido por detalhes de baixa importância. Perceba que isso não quer dizer segurança não é importante, como muitas pessoas infelizmente ainda insistem em dizer. Eu quero dizer que a segurança precisa ser algo a serviço da infraestrutura e se o modelo proporcionar métodos ágeis para viabilizar essa segurança, devemos usar sem medo.

Cada processo executado dentro de um container Docker não pode visualizar processos, disco, espaço de memória e pilha de rede fora desse ambiente isolado.É esperado que cada container execute apenas um processo, ou seja, naquele ambiente segregado não existirá qualquer compartilhamento de informações com outra instância.

Com base nessas premissas, qual real necessidade de se executar um processo de um container com um usuário diferente de root? Qual ganho teríamos ao evitar que uma falha de segurança viabilize o uso do root dentro de um container que teria apenas um processo em execução?

Na situação de um container executando com usuário “não-root”, tudo importante do container deveria ser acessível pelo usuário do processo, que por sua vez a exploração de uma falha teria o mesmo impacto, pois o invasor teria acesso aos mesmos dados importantes e controle da instância.

Pelo fato do Docker compartilhar o uso do mesmo kernel para todos os containers, existem algumas suspeitas que ao utilizar o root dentro do container seria possível que alguma falha proporcione a manipulação de recursos exteriores ao container. Perceba que esse é o mesmo risco que se corre ao utilizar o usuário convencional, pois com posse de uma falha de kernel é possível a escalada de privilégio.

É importante atentar que segurança é como uma balança, que é usada para medir a melhor proporção entre praticidade e controle de riscos, pois quanto maior o rigor ao tratar os riscos, pior ficará sua praticidade e vice-versa. Levando em consideração que o maior ganho do Docker é sua praticidade, não vejo motivos para pânico na gerência de usuários root dentro do container.

Minha opinião até o presente momento é: Use usuário root dentro dos containers sem problema. Lembre-se de tomar as precauções convencionais com o host, ou seja, mantenha-o sempre atualizado, realize hardening e afins.

  • Gustavo Chaves

    Entendo o argumento mas ainda assim creio que haja razões para limitar as permissões de acesso do processo principal do container aos arquivos do mesmo.

    Por exemplo, quando você instala um servidor web como o nginx numa máquina Ubuntu, o processo é executado como usuário “www-data”, mas tanto o diretório de configuração (/etc/nginx) quanto o diretório raiz das páginas HTML (/usr/share/nginx/html) pertencem à “root”, exatamente pra que o processo não tenha acesso de escrita a eles. Deste modo, um malfeitor que consiga indevidamente controlar remotamente o processo do servidor web não conseguirá modificar sua configuração e nem suas páginas web sem que consiga também escalar seus privilégios. Se aqueles diretórios pertencessem ao mesmo usuário “www-data”, um malfeitor que conseguisse meramente controlar o processo, conseguiria desfigurar o sistema (defacing).

    O usuário root não é sugeito às restrições de acesso impostas pelas permissões do sistema de arquivos e não nos permite segregar direitos de acesso como o configurado no exemplo anterior. Portanto, creio que para garantir esta possibilidade seja mais interessante usar por default um usuário não privilegiado para executar os processos dos conteineres.

    • Gomex

      Gustavo,

      Essa é uma situação ótima para se precisar realmente de um usuário diferente, pois você não teria trabalho para implementar isso, uma vez que o usuário distinto não precisa de permissão de escrita no arquivo, ou seja, não afeta sua praticidade e ainda adiciona uma boa camada extra de segurança.

      Obrigado pelo comentário. Agregou muito ao debate. 🙂

  • Pingback: Pode executar seus containers como root? - Peguei do()

  • Alessandro Silva

    Meus 0,01 centavo de contribuição:

    Acho que o que deve ser destacado é:

    1. Os containers independentemente se o usuário tem acesso root ou não, são isolados pelo SELINUX. Este recurso vao proteger os containers uns dos outros e o o HostOs dos containers;

    2. Isso faz com que uma app rodando em container seja inclusive mais segura que no ambiente tradicional (se estivesse sendo executada como root)

    3. A motivação é que caso alguma vulnerabilidade sej explorada, que apenas o container seja comprometido, da mesma forma que nos serviços isolados dentro de uma jaula chroot.

    4. Entregar um container com permissão full dá agilidade para quem recebe (DEV) instalar e configurar como desejar, e a infra vais e preocupar apenas com a parte dela.

    Abraços,

    • Gomex

      Alessandro,

      Obrigado pela excelente adição ao debate. Vale salientar apenas que a segurança do SELinux se dá automaticamente apenas na RedHat e em seus derivados, onde o template tanto do Apparmor como SELinux são distribuídos por padrão. Nas outras distros, a garantia de segurança normalmente é apenas via namespace mesmo, o que já é muita coisa na minha opinião. 🙂

  • Rafael,

    Achei interessante o post e resolvi comentar aqui!

    Em qualquer ambiente, aquela regra geral do “dê o mínimo de permissões necessárias para que alguma coisa funcione corretamente” sempre se aplica e muito frequentemente salva vidas! 🙂

    No caso do Docker, o daemon do Docker em si ainda tem que ser executado como root por limitações no funcionamento dele até o momento (alguns recursos que ele precisa acessar só podem ser acessados pelo root). Porém, isso vai mudar no futuro com certeza (como os próprios desenvolvedores vêm dizendo a algum tempo). Deixar o Docker rodando como root quebra a regra que mencionei no parágrafo anterior e deixa o sistema inteiro vulnerável caso qualquer falha um pouco mais séria seja descoberta.

    Agora, considerando os processos que são executados dentro de um container do Docker, a mesma regra continua sendo aplicada. Executar qualquer processo (dentro de um container do Docker ou dentro de um CHRoot, que seja) expõe o sistema a muito risco – e pior: risco desnecessário. Escalação de privilégios é só um dos problemas, você também deveria considerar outros ataques também bastante sérios como uma execução remota de código.

    Imagine se alguém consegue executar código remotamente no seu servidor web dentro de um container do Docker e este servidor está rodando como root. Ele vai poder alterar absolutamente qualquer coisa dentro do seu container. Inclusive, poderia alterar as configurações para fazer com que o seu servidor web passe a distribuir malware, por exemplo.

    Inclusive, a própria documentação menciona isso:
    “Docker containers are, by default, quite secure; especially if you take care of running your processes inside the containers as non-privileged users (i.e., non-root).”

    Traduzindo:
    “Containers do Docker são, por padrão, bastante seguros; especialmente se você tomar o cuidado de executar os processos dentro dos containeres como usuários não-privilegiados (ou seja, não-root).”

    Limitar as permissões do usuário de um processo é sim importante para a segurança do sistema, dentrou ou fora do Docker. Juntando isso com o hardening do software que você usa (os guias do CIS são uma excelente base pra você fazer esse hardening) e do sistema operacional do host, você consegue ter funcionalidade e segurança.

    Apenas meus 2 cents! Parabéns pelo blog, cara! 🙂

    []’s
    Pedro Pereira