BLOG

Noções básicas de segurança de contêineres: Orquestração

  Jordan Zebor

  Lori MacVittie

Publicado em 24 de julho de 2019

Se você está começando a ler esta série agora, talvez seja melhor começar do começo: 
Noções básicas de segurança de contêineres: Introdução
Noções básicas de segurança de contêineres: Gasoduto

De acordo com o relatório State of Container Security de 2019 da Tripwire , apenas uma em cada três (32%) organizações opera atualmente mais de 100 contêineres em produção. Uma porcentagem menor (13%) opera mais de 500. E 6% dos adotantes realmente ansiosos estão atualmente gerenciando mais de 1.000. Existem poucas organizações operando contêineres em escala sem um sistema de orquestração para auxiliá-las.

A camada de orquestração da segurança de contêineres se concentra no ambiente responsável pela operação diária dos contêineres. Pelos dados disponíveis hoje, se você estiver usando contêineres, é quase certo que esteja aproveitando o Kubernetes como orquestrador.

É importante observar que existem outros orquestradores, mas a maioria deles também aproveita componentes e conceitos derivados do Kubernetes. Portanto, vamos nos concentrar na segurança do Kubernetes e seus componentes.

O ambiente Kubernetes

Há várias partes móveis que compõem o Kubernetes. Isso torna a proteção mais desafiadora não apenas devido ao número de componentes envolvidos, mas também à maneira como esses componentes interagem. Alguns se comunicam via API. Outros via sistema de arquivos host. Todos são pontos potenciais de entrada no ambiente de orquestração que devem ser abordados. 

ambiente básico do kubernetes

Ambiente básico do Kubernetes

Uma rápida visão geral dos principais componentes que requerem atenção:

  • Servidor API e Kubelet
  • Cápsulas
  • etc.

Isso significa que você deve pegar uma xícara de café, pois esta vai levar um pouco mais de tempo para terminar.

1. A autenticação não é opcional

Leitores atentos perceberão que isso soa familiar. Você pode ter ouvido falar dela como Regra de Segurança Dois, também conhecida como Tranque a porta. É um tema comum que continuaremos a repetir porque muitas vezes é ignorado. Uma autenticação forte é essencial. Observamos que o número de incidentes de segurança devido a práticas de segurança precárias em relação a contêineres continua aumentando. E uma das fontes comuns é a falha no uso da autenticação, geralmente quando implantada na nuvem pública.

Exija credenciais fortes e faça rodízio com frequência. O acesso ao servidor de API (por meio de consoles não seguros) pode levar a uma situação de “fim de jogo” porque todo o ambiente de orquestração pode ser controlado por meio dele. Isso significa implantar pods, alterar configurações e parar/iniciar contêineres. Em um ambiente Kubernetes, o servidor de API é a “única API para governar todos” que você deseja manter fora das mãos de malfeitores.

Como proteger o servidor de API e o Kubelet

É importante observar que essas recomendações são baseadas no modelo de autorização atual do Kubernetes. Consulte sempre a documentação mais recente da versão que você está usando.

  • Habilitar mTLS em todos os lugares
    - Dedique um CA por serviço – k8s, etcd, aplicações
    - Gire os certificados e tome cuidado com as permissões de chave privada no disco
  • Vincule somente a endereços seguros
    - Cuidado com a configuração da API “insecure-bind-address” e “insecure-port”
    - Aplique isso a _todos_ os serviços (SSH, Vault, etcd)
  • Desabilitar “Autenticação Anônima”
    - “Autenticação anônima” parece uma boa ideia?
    - Padrão desabilitado a partir da versão 1.5, habilitado manualmente com “--anonymous-auth=True”
  • Habilitar autorização
    - Não use “--authorization-mode=AlwaysAllow”
    - O servidor API deve ter “--authorization-mode=RBAC,Node”
    - Kubelet deve ter “--authorization-mode=Webhook”
    - Restrinja o Kubelet para ter acesso apenas aos recursos em seu próprio nó.

É importante observar que essas recomendações são baseadas no modelo de autorização atual do Kubernetes. Consulte sempre a documentação mais recente para a versão que você está usando. 

2. Pods e Privilégios 

Pods são uma coleção de contêineres. Eles são o menor componente do Kubernetes e, dependendo do plugin Container Network Interface (CNI), todos os pods podem se comunicar por padrão. Existem plugins CNI que podem usar “Políticas de Rede” para implementar restrições a esse comportamento padrão. É importante observar isso porque os pods podem ser agendados em diferentes nós do Kubernetes (que são análogos a um servidor físico). Os pods também costumam montar segredos, que podem ser chaves privadas, tokens de autenticação e outras informações confidenciais. Daí a razão pela qual são chamados de "segredos".

Isso significa que há diversas preocupações com pods e segurança. Na F5, sempre presumimos um pod comprometido quando iniciamos a modelagem de ameaças. Isso ocorre porque os pods são onde as cargas de trabalho dos aplicativos são implantadas. Como as cargas de trabalho de aplicativos são as mais propensas a serem expostas a acesso não confiável, elas são o ponto mais provável de comprometimento. Essa suposição leva a quatro perguntas básicas a serem feitas para planejar como mitigar ameaças potenciais. 

  1. O que um invasor poderia ver ou fazer com outros pods se tivesse acesso a um pod?
  2. Um invasor pode acessar outros serviços no cluster?
  3. Quais segredos são montados automaticamente?
  4. Quais permissões foram concedidas à conta de serviço do pod?

As respostas a essas perguntas expõem riscos que podem ser explorados se um invasor obtiver acesso a um pod dentro do cluster. Mitigar as ameaças de comprometimento de pods requer uma abordagem multifacetada envolvendo opções de configuração, controle de privilégios e restrições em nível de sistema. Lembre-se de que vários pods podem ser implantados no mesmo nó (físico ou virtual) e, portanto, compartilhar o acesso ao sistema operacional – geralmente um sistema operacional Linux.

Como mitigar ameaças de Pod
O Kubernetes inclui um recurso de Política de Segurança de Pod que controla aspectos confidenciais de um pod. Ele permite que os operadores definam as condições sob as quais um pod deve operar para ser permitido no sistema e impõe uma linha de base para o contexto de segurança do pod. Nunca assuma que os padrões são seguros. Implemente linhas de base seguras e verifique as expectativas para se proteger contra ameaças de pod.

Opções específicas para uma Política de Segurança de Pod devem abordar o seguinte:

  • Evite contêineres privilegiados
    • Procure a configuração “—allow-privileged” no kube-api e/ou kubelet
    • Procure por “privileged: true” na especificação do pod.
    • Reduza o risco de segurança com “--allow-privileged=false”
  • O usuário padrão do contêiner com Docker é root
    • Evite executar qualquer carga de trabalho como root
    • A política de segurança do Pod pode usar “runAsUser”, “runAsGroup” e “runAsNonRoot: true”
    • Opções semelhantes podem ser definidas em um Dockerfile
  • Não permitir escalonamento de privilégios dentro de um contêiner
    • “allowPrivilegeEscalation: falso”
  • Usar SELinux / AppArmor
    • O SELinux fará uso do Multi Category Security para confinar os contêineres uns dos outros
    • Deixe ativado e trabalhe nas negações
    • Desabilitar ou mudar para o modo permissivo reduz severamente a segurança
  • Prevenir ataques de link Sym / ponto de entrada
    • Os invasores podem sobrescrever o binário do ponto de entrada ou criar links simbólicos ruins
    • Evite isso definindo “readOnlyRootFilesystem: true”
  • Evite opções de configuração host*
    • Os invasores com acesso aos recursos do host têm maior probabilidade de comprometer ainda mais o host e/ou os contêineres adjacentes
    • Evite opções como hostPID, hostIPC, hostNetwork, hostPorts
  • montagens hostPath somente leitura
    • Se for necessário configurar leitura/gravação no host, tenha cuidado com a implantação e certamente não torne isso uma prática padrão
    • Use “readOnly” em todos os HostPaths permitidos para evitar ataques
  • Perfis Seccomp
    • Reduza a superfície de ameaça limitando as chamadas de sistema permitidas
    • O Docker padrão reduzirá alguns, mas é um perfil genérico
    • Perfis específicos de aplicação fornecerão o maior benefício de segurança

3. etc.

Etcd é o armazenamento para configuração e segredos. O comprometimento aqui pode permitir a extração de dados confidenciais ou a injeção de dados maliciosos. Nenhuma das duas é boa. Mitigar ameaças ao etcd significa controlar o acesso. Isso é melhor conseguido aplicando o mTLS . Os segredos são armazenados pelo Kubernetes no etcd como codificados em base64. Considere o uso de um recurso alfa, “provedor de criptografia” , para opções mais fortes ao armazenar segredos confidenciais ou considere usar o HashiCorp Vault.