Nota perev. : O original deste artigo foi publicado no blog oficial da Kubernetes e escrito por Andrew Martin, um dos fundadores da jovem empresa britânica Control Plane, especializada em segurança para aplicativos nativos da nuvem em execução no K8s.
A segurança em Kubernetes percorreu um longo caminho desde a chegada do projeto, mas ainda existem armadilhas. Oferecemos uma lista de recomendações úteis sobre como proteger clusters e aumentar sua estabilidade em caso de hackers: começaremos com o plano de controle, continuaremos com cargas de trabalho e segurança de rede e terminaremos com uma avaliação da segurança futura.
Parte 1: Plano de Controle
O plano de controle é o cérebro de Kubernetes. Ele tem uma idéia geral de cada contêiner e pod em execução no cluster, pode planejar novos pods (que podem conter contêineres com acesso root aos seus nós pais) e pode ler todos os segredos armazenados no cluster. Este é um componente muito importante que precisa de proteção constante contra vazamento acidental de dados e ações maliciosas: tanto quando é acessado, quando nada acontece, como quando os dados são transmitidos pela rede.
1. TLS onipresente
Para cada componente que suporta TLS, ele deve estar ativado - para impedir a detecção de tráfego, a verificação de identidade do servidor e (no caso do Mutual TLS) a verificação de identidade do cliente."Observe que alguns componentes e métodos de instalação podem ativar portas locais para HTTP, portanto, os administradores precisam se familiarizar com as configurações de cada componente para identificar possíveis caminhos para tráfego inseguro".
Da documentação do Kubernetes
O diagrama de rede abaixo de
Lucas Käldström mostra onde o TLS é idealmente necessário: entre cada componente no assistente e entre o Kubelet e o servidor da API. O clássico
Kelsey Hightower Kubernetes The Hard Way e a
documentação de segurança no etcd oferecem instruções detalhadas para alcançar esses objetivos.

Historicamente, o dimensionamento automático dos nós do Kubernetes não era fácil, pois cada nó exigia uma chave TLS para conectar-se ao mestre e manter segredos em imagens básicas é uma prática recomendada.
O bootstrapping TLS do Kubelet permite que o novo Kubelet crie uma solicitação de assinatura de certificado para que os certificados sejam gerados no momento da inicialização:

2. Privilégios mínimos no RBAC, desativando o ABAC, monitorando o log
O RBAC (Controle de Acesso Baseado em Função) fornece gerenciamento de política refinado, pelo qual os usuários acessam recursos como espaços para nome.
O ABAC (Controle de Acesso Baseado em Atributos) no Kubernetes foi substituído pelo RBAC desde o K8s 1.6 e não deve ser ativado no lado do servidor da API. Use o RBAC:
--authorization-mode=RBAC
(ou este sinalizador para GKE:
--no-enable-legacy-authorization
).
Existem muitos
bons exemplos de políticas RBAC para vários serviços em um cluster, além de
documentação . Mas não pare por aí: configurações competentes para políticas RBAC podem ser obtidas usando
audit2rbac nos logs de
audit
.
Políticas de RBAC incorretas ou excessivamente permissivas são um risco de segurança se a lareira estiver comprometida. Manter as regras do RBAC com privilégios mínimos, auditando-as constantemente e melhorando-as deve fazer parte da “higiene técnica da dívida” que as equipes aplicam no ciclo de vida do desenvolvimento.
O log de auditoria (beta no Kubernetes 1.10) oferece uma API de log personalizada para cargas de trabalho (como solicitação e resposta) e no nível de metadados. O nível de log pode ser configurado de acordo com a política de segurança da organização - o
GKE aplica valores padrão razoáveis para aqueles que estão começando a trabalhar com ele.
Para solicitações de leitura como
get ,
list e
watch , apenas o objeto solicitado é armazenado nos logs de auditoria, sem um objeto de resposta. Para consultas que envolvam dados confidenciais como
Secret ou
ConfigMap , apenas os metadados são exportados. Para todas as outras solicitações, os dois objetos são registrados nos logs de auditoria: a solicitação e a resposta.
Não se esqueça: armazenar esses logs dentro do cluster é um risco de segurança em caso de comprometimento. Esses logs, como quaisquer outros sensíveis à segurança, devem ser colocados fora do cluster para evitar consequências negativas em caso de vulnerabilidade.
3. Use autenticação de terceiros para o API Server
A centralização da autenticação e autorização para toda a organização (ou seja, Logon Único) ajuda nos processos de aceitação e saída de novos funcionários, garantindo direitos de acesso consistentes.A integração do Kubernetes com provedores de autenticação de terceiros (como Google ou GitHub) fornece garantias de identidade de uma plataforma remota (com proteção como autenticação de dois fatores) e elimina a necessidade de administradores reconfigurar o servidor de API no Kubernetes para adicionar / remover usuários.
Dex é um provedor OIDC (OpenID Connect Identity) e OAuth 2.0 com plug-ins. O Pusher foi ainda mais longe, fornecendo
ferramentas personalizáveis , além das quais existem
outros auxiliares focados em outros aplicativos.
4. Separe e coloque seu cluster etcd atrás do firewall
O etcd armazena informações sobre o status e os segredos do Kubernetes, é um componente crítico dos K8s - deve ser protegido separadamente do resto do cluster.O acesso de gravação ao etcd no servidor da API é equivalente à emissão de direitos de root para todo o cluster, e até o acesso de leitura pode ser facilmente usado para aumentar os privilégios.
O planejador do Kubernetes no etcd procura definições de pod que não possuem um nó. Em seguida, ele envia todos os pods encontrados para o Kubelet disponível para planejamento. A validação desses pods é feita pelo servidor da API antes de gravá-los no etcd; portanto, os invasores que gravam diretamente no etcd podem ignorar muitos mecanismos de segurança - por exemplo,
PodSecurityPolicies
.
O etcd deve ser configurado com
os certificados TLS (
cliente e
par ) e distribuído para nós dedicados. Para reduzir o risco de roubo e uso de chaves privadas de nós de trabalho, você também pode limitar o firewall do cluster do API Server.
5. Rotação das chaves de criptografia
A rotação regular de chaves e certificados de segurança é a melhor prática de segurança que permite limitar o "raio de destruição" quando a chave é comprometida.O Kubernetes
alternará automaticamente alguns certificados (em particular, certificados de cliente e servidor Kubelet) criando novos CSRs depois que os atuais expirarem.
No entanto, as
chaves simétricas usadas pelo servidor da API para criptografar valores etcd não são giradas automaticamente - isso deve ser
feito manualmente . Esta operação requer acesso mestre, portanto, serviços gerenciados (como GKE e AKS) ocultam o problema do usuário.
Parte 2: cargas de trabalho
Com segurança mínima no nível do plano de controle, o cluster já pode funcionar com segurança. No entanto, como em um navio com carga potencialmente perigosa, os contêineres de tal navio devem proteger a carga em caso de acidente ou vazamento imprevisto. O mesmo vale para as cargas de trabalho do Kubernetes (
pods ,
implantações ,
tarefas ,
conjuntos etc.) - elas podem ser confiáveis no momento da implantação, mas se forem acessíveis externamente, sempre haverá o risco de serem exploradas posteriormente pelos [invasores]. Esse risco pode ser atenuado executando cargas de trabalho com privilégios mínimos e sua configuração segura.
6. Use os recursos de segurança do Linux e o PodSecurityPolicies
O kernel do Linux possui muitas extensões de segurança parcialmente sobrepostas (recursos, SELinux, AppArmor, seccomp-bpf) que podem ser configuradas para conceder privilégios mínimos aos aplicativos.Utilitários como
bane o ajudarão a gerar perfis para o AppArmor, e o
docker-slim o ajudará a gerar perfis seccomp, mas tenha cuidado: para identificar todos os efeitos colaterais da aplicação dessas políticas, você precisa de um conjunto de testes abrangente que verifique todo o código do aplicativo.
PodSecurityPolicies regem o uso dessas extensões de segurança, bem como outras diretivas de segurança do Kubernetes. Eles são responsáveis pelos requisitos mínimos que devem ser atendidos para acessar o servidor da API, incluindo perfis de segurança, sinalizador de privilégios, rede host compartilhada, processos ou espaços de nome para IPC.
Essas diretivas são importantes porque ajudam a impedir que processos em contêineres escapem de seus limites isolados.
O exemplo do PodSecurityPolicy de Tim Allclair é muito versátil - você pode tomá-lo como base e personalizá-lo para o seu caso.
7. Execute uma análise estática do YAML
Se o PodSecurityPolicies restringir o acesso ao servidor da API, a análise estática também poderá ser usada no processo de desenvolvimento para modelar os requisitos regulatórios da organização e o apetite ao risco.Informações confidenciais não devem ser armazenadas em recursos YAML, como lares (
pods ,
implantações ,
conjuntos etc.), e
ConfigMaps e
segredos confidenciais devem ser criptografados com utilitários como o
Vault (com um operador do CoreOS),
git-crypt ,
segredos selados ou
nuvem KMS fornecedor .
A análise estática da configuração YAML pode ser usada como base para segurança durante a inicialização.
O kubesec gera avaliações de risco para recursos:
{ "score": -30, "scoring": { "critical": [{ "selector": "containers[] .securityContext .privileged == true", "reason": "Privileged containers can allow almost completely unrestricted host access" }], "advise": [{ "selector": "containers[] .securityContext .runAsNonRoot == true", "reason": "Force the running image to run as a non-root user to ensure least privilege" }, { "selector": "containers[] .securityContext .capabilities .drop", "reason": "Reducing kernel capabilities available to a container limits its attack surface", "href": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" }] } }
E o
kubetest é uma estrutura para testar as configurações do Kubernetes:
#
Esses utilitários implementam a abordagem
shift left (ou seja, eles movem a validação e a verificação para os estágios iniciais do ciclo de desenvolvimento). O teste de segurança no estágio de desenvolvimento fornece aos usuários feedback rápido sobre o código e a configuração, que podem ser posteriormente rejeitados pela verificação manual ou automatizada, além de facilitar a introdução de práticas de segurança adicionais.
8. Executar contêineres não raiz
Os contêineres executados como raiz geralmente têm muito mais direitos do que as cargas de trabalho exigem e, se comprometidos, ajudam os invasores a obter ótimos recursos.Os contêineres ainda confiam no modelo de segurança tradicional do UNIX (chamado DAC,
controle de acesso discricionário ) - tudo é um arquivo e os direitos são concedidos a usuários e grupos.
Os espaços para nome do usuário não funcionam no Kubernetes. Isso significa que a tabela de ID do usuário no contêiner é mapeada para a tabela de usuários do host e iniciar o processo com privilégios de root dentro do contêiner faz com que seja executado com privilégios de root no host. Embora mecanismos sejam adicionados a tudo isso para impedir a saída do contêiner, a execução como raiz dentro do contêiner não é recomendada.
Muitas imagens de contêineres usam o usuário root para executar o PID 1: se esse processo for comprometido, o invasor se tornará root no contêiner e, com qualquer erro de configuração, a operação do problema se tornará muito mais fácil.
O Bitnami
fez um ótimo trabalho ao converter suas imagens de contêiner para
usuários regulares (não raiz) (que também é o requisito padrão do OpenShift), o que também pode simplificar sua migração para imagens não raiz.
Este fragmento PodSecurityPolicy impede que os processos raiz sejam executados no contêiner e escalados para o root:
# Required to prevent escalations to root. allowPrivilegeEscalation: false runAsUser: # Require the container to run without root privileges. rule: 'MustRunAsNonRoot'
Os contêineres que não usam raiz não podem ocupar portas privilegiadas, ou seja, até 1024 (o recurso correspondente no kernel do Linux -
CAP_NET_BIND_SERVICE
é responsável por isso), no entanto, o uso dos
Serviços ajuda a contornar essa limitação. Aqui está um exemplo para o aplicativo MyApp, que ocupa a porta 8443 no contêiner, mas o
Service o disponibiliza na porta 443, solicitando proxy para
targetPort
:
kind: Service apiVersion: v1 metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 443 targetPort: 8443
A necessidade de executar cargas de trabalho sem usar raiz permanecerá até que o espaço de nome do usuário ou
o tempo de operação para iniciar contêineres sem raiz sejam incluídos no tempo de execução do contêiner.
9. Use políticas de rede
Por padrão, a rede Kubernetes permite todo o tráfego entre os pods. Essa configuração pode ser limitada pela política de rede - NetworkPolicy .
Os serviços tradicionais são limitados a firewalls que usam endereços IP estáticos e intervalos de portas para cada serviço. Como esses endereços IP mudam muito raramente, historicamente têm sido usados como uma forma de autenticação. Os contêineres raramente têm IPs estáticos - sua natureza implica a possibilidade de uma queda e recriação rápidas, pois eles usam a descoberta de serviços em vez de endereços IP estáticos. Esses recursos complicam bastante a configuração e a verificação de firewalls.
Como o Kubernetes armazena todos os dados sobre o estado do sistema no etcd, é possível configurar um firewall dinâmico - se houver o suporte necessário no plug-in da rede CNI. Calico, Cilium, kube-router, Romana e Weave Net - todos esses plugins suportam políticas de rede.
É importante observar que as políticas funcionam com base no princípio de falha fechada, ou seja, a ausência de um
podSelector
aqui por padrão é igual a todos os valores possíveis (curinga):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector:
A seguir, é apresentado um exemplo de
NetworkPolicy , que proíbe tudo da saída, exceto o UDP 53 (DNS), que também impede conexões de entrada para o aplicativo.
NetworkPolicies são políticas
com estado , portanto o aplicativo ainda receberá respostas para conexões de saída.
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: myapp-deny-external-egress spec: podSelector: matchLabels: app: myapp policyTypes: - Egress egress: - ports: - port: 53 protocol: UDP - to: - namespaceSelector: {}
As diretivas de rede do Kubernetes não podem ser aplicadas aos nomes DNS. O motivo é que o DNS suporta round-robin para vários endereços IP e respostas dinâmicas dependentes do IP de acesso; portanto, as políticas de rede se aplicam apenas a endereços IP fixos ou
podSelector
(para endereços IP dinâmicos do Kubernetes).
A melhor prática é começar banindo todo o tráfego para o espaço para nome e adicionando passo a passo as rotas exigidas pelo aplicativo para passar no teste de aceitação. O processo pode ser difícil, então a ControlPlane desenvolveu o
netassert , um utilitário para testar a segurança da rede em scripts DevSecOps com o nmap altamente paralelo:
k8s: # used for Kubernetes pods deployment: # only deployments currently supported test-frontend: # pod name, defaults to `default` namespace test-microservice: 80 # `test-microservice` is the DNS name of the target service test-database: -80 # `test-frontend` should not be able to access test-database's port 80 169.254.169.254: -80, -443 # AWS metadata API metadata.google.internal: -80, -443 # GCP metadata API new-namespace:test-microservice: # `new-namespace` is the namespace name test-database.new-namespace: 80 # longer DNS names can be used for other namespaces test-frontend.default: 80 169.254.169.254: -80, -443 # AWS metadata API metadata.google.internal: -80, -443 # GCP metadata API
Uma API com metadados de um provedor de nuvem é uma fonte constante de escalada em potencial (demonstrada
pela recente
recompensa de bugs do Shopify ); portanto, testes especiais que confirmam que a API está bloqueada na rede de contêineres ajudam a proteger contra erros de configuração.
10. Digitalize imagens e execute IDS
Servidores da Web são um trampolim para atacar as redes às quais estão conectados. A verificação dos arquivos instalados nas imagens permite verificar se não há vulnerabilidades conhecidas que um invasor possa usar para obter acesso remoto ao contêiner. Os sistemas de detecção de intrusões (IDS) registram esses eventos se eles ocorrerem.O Kubernetes permite envios ao cluster por meio de um conjunto de verificações de controle (no
controlador de admissão ), que se aplicam não apenas aos pods, mas também a outros recursos, como
implantações . Neles, cada sub pode ser validado para admissão ou seu conteúdo pode ser alterado, além de quais webhooks no lado de back-end agora também são suportados.

Esses webhooks podem ser usados pelas ferramentas de varredura de imagem do contêiner para verificar as imagens antes de serem implantadas no cluster. Imagens que falham na validação não receberão a aprovação do controlador.
A verificação de imagens de contêiner em busca de vulnerabilidades conhecidas ajuda a reduzir o tempo que um invasor pode tirar proveito de um CVE aberto. Para evitar o lançamento de imagens com vulnerabilidades críticas no pipeline de implantação, você pode usar utilitários gratuitos como
Clair do CoreOS e
Micro Scanner do Aqua.
Ferramentas como o
Grafeas permitem armazenar metadados de imagem para verificações contínuas de conformidade e vulnerabilidade usando uma assinatura de contêiner exclusiva (ou hash de
endereçamento de conteúdo especial). A digitalização de uma imagem de contêiner usando esse hash equivale à digitalização de imagens implantadas na produção e pode ser executada continuamente, sem a necessidade de acesso aos ambientes de produção.
As vulnerabilidades desconhecidas do dia 0 sempre existirão, portanto o Kubernetes deve implantar um sistema de detecção de intrusões como o
Twistlock ,
Aqua ou
Sysdig Secure . O IDS detecta um comportamento incomum no contêiner e o interrompe ou mata.
O Falco de Sysdig é um mecanismo de regras de código aberto e o ponto de partida para esse ecossistema.
Parte 3: O Futuro
O próximo estágio de segurança na “evolução do nativo da nuvem” parece ser a malha de serviço, embora sua adoção não ocorra imediatamente: essa migração exige a mudança da complexidade dos aplicativos para a infraestrutura de malha, e as organizações precisam realizar essa melhor prática.

11. Inicie a malha de serviço
O Service Mesh é uma rede de conexões criptografadas persistentes feitas entre "lado conectado" (semelhante ao "sidecar") , proxies de alto desempenho como Envoy e Linkerd. Traz gerenciamento de tráfego, monitoramento e políticas - tudo sem alterações nos microsserviços.A transferência de segurança e código relacionado à rede de microsserviços para um conjunto de bibliotecas compartilhadas e testadas em batalha já era possível com o
Linkerd , e o advento do
Istio do Google, IBM e Lyft trouxe uma alternativa para esse espaço. Com a adição do
SPIFFE para a identidade criptográfica de cada pod e muitos outros recursos, o Istio pode simplificar a implantação da segurança de rede da próxima geração.
Em redes de “confiança zero”, pode não haver necessidade de um firewall tradicional ou políticas de rede Kubernetes, pois cada interação ocorre usando mTLS (TLS mútuo), que não apenas garante a segurança da interação, mas também confirma a identidade de ambos os serviços. .
Essa mudança das abordagens de rede tradicionais para os princípios de segurança do mundo do Cloud Native não será fácil para quem tem uma mentalidade de segurança tradicional. Como introdução a esse novo mundo, recomendamos
o livro Zero Trust Networking de
Evan Gilman, da SPIFFE.
Atualmente, o
Istio 0.8 LTS está disponível e o projeto está se aproximando rapidamente de seu lançamento 1.0. A versão do projeto em termos de estabilidade é realizada de maneira semelhante ao modelo Kubernetes: um kernel estável com APIs separadas para as quais seu status alfa ou beta é indicado usando espaços de nomes. Espere ver o Istio expandir nos próximos meses.
Conclusão
Os aplicativos Cloud Native têm um conjunto mais detalhado de primitivas de segurança leves que ajudam a proteger cargas de trabalho e infraestrutura. O poder e a flexibilidade dessas ferramentas são uma bênção e uma maldição: sem automação suficiente [para seu uso], a exposição de aplicativos não seguros para ir além do contêiner ou seu modelo de isolamento tornou-se ainda mais fácil.
Os utilitários de proteção estão mais acessíveis do que nunca, no entanto, para reduzir o potencial de ataque e o potencial de configurações incorretas, você deve usá-los com cuidado.
Se a segurança diminuir a velocidade da organização na entrega de alterações, nunca será uma prioridade. O uso dos princípios de Entrega Contínua em relação à cadeia de suprimentos de software permite que a organização alcance conformidade regulamentar, auditoria contínua e gerenciamento aprimorado, sem afetar o desempenho dos negócios.
O aprimoramento rápido e incremental da segurança é a maneira mais fácil com um conjunto de testes abrangente. Continuous Security — pipeline', , , .
PS do tradutor
Leia também em nosso blog: