Skip to main content

Implicações de segurança dos operadores do Kubernetes

Escrito por
Headshot of Chris Laux

Chris Laux

Snyk logo overlapping with Kubernetes logo

14 de fevereiro de 2022

0 minutos de leitura

Gerenciar recursos nas primeiras versões do Kubernetes era simples: bastava definir os recursos com marcação YAML e enviar essas definições ao cluster. Mas esse processo exigia trabalho manual demais e atuava em um nível muito baixo.

A etapa seguinte na evolução do Kubernetes foi o uso de charts do Helm. Às vezes chamado de “gerenciador de pacotes do Kubernetes”, o Helm permitiu que desenvolvedores compartilhassem configurações completas de aplicações usando uma linguagem de templates. Isso facilitou o compartilhamento de configurações e permitiu implantar charts com um único comando.

Mas o Helm é um complemento externo, e seus recursos se limitam ao que podemos implementar por meio da API existente do Kubernetes. Assim, a próxima etapa natural foi estender a API do Kubernetes usando operadores. Isso nos permitiu adicionar funcionalidades personalizadas diretamente no cluster.

Os operadores do Kubernetes usam loops de controle para executar tarefas que antes ficavam a cargo de operadores humanos. Para criar um operador do Kubernetes, o desenvolvedor define um código personalizado que interage com a API do Kubernetes e gerencia automaticamente o ciclo de vida da aplicação. Esse código geralmente é executado em um ou mais pods no cluster, mas também pode interagir com o cluster externamente, desde que use a autenticação adequada.

Você está pensando que essa configuração pode abrir espaço para vulnerabilidades? E pode mesmo. Como sempre, novas abstrações trazem novos problemas de segurança do Kubernetes.

Neste artigo, vamos mostrar exemplos de como definir corretamente o escopo das permissões dos operadores, explicar os papéis complementares de quem cria e de quem usa operadores para garantir a segurança e apresentar algumas maneiras de usar operadores para tornar os serviços do Kubernetes mais seguros.

Segurança do Kubernetes com RBAC

Se vamos implantar um operador do Kubernetes em um cluster, devemos considerar as práticas gerais de segurança do Kubernetes como base para os cuidados específicos com operadores. Primeiro, vamos analisar essas considerações gerais.

O principal sistema de permissões do Kubernetes é o controle de acesso baseado em função (RBAC), que precisa estar habilitado quando o cluster é iniciado. Ele oferece recursos adicionais para gerenciar permissões: Roles e RoleBindings, que se aplicam apenas ao namespace em que são definidos; e ClusterRolesand ClusterRoleBindings, que se aplicam a todo o cluster (e só devem ser usados quando necessário).

As Roles definem como agentes privilegiados podem acessar recursos, e os RoleBindings associam agentes humanos ou componentes de software às Roles. Assim como nas práticas gerais de segurança de sistemas operacionais, é importante conceder apenas as permissões estritamente necessárias e revisar regularmente as permissões concedidas para confirmar se ainda são necessárias.

Veja um exemplo de função que permite acesso de leitura aos recursos de pod no namespace especificado:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: my-webserver
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

O valor vazio de apiGroups indica a API principal. Para corresponder a essa configuração, podemos definir um vínculo de função que atribua essa função a uma conta de usuário específica:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
Metadata:
  namespace: my-webserver
  name: read-pods
subjects:
- kind: User
  name: emilio
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

As implantações de operadores geralmente incluem seus próprios conjuntos de funções e vínculos. O usuário deve conferir esses recursos e a documentação para entender exatamente quais permissões um terceiro está concedendo no cluster.

Escopos e permissões

A segurança dos operadores do Kubernetes envolve uma cadeia de confiança. Ela começa com os autores do operador e seu repositório, e inclui a forma como o operador é entregue ao cluster do usuário, entre outros aspectos. Assim como no sistema RBAC, faz sentido restringir ao máximo as permissões do operador. Infelizmente, a maioria dos operadores do Kubernetes precisa de privilégios bastante amplos para funcionar. Por isso, os desenvolvedores precisam encontrar um equilíbrio cuidadoso entre segurança e utilidade.

Assim como as funções e os vínculos de função, os operadores podem ter seu escopo limitado a um namespace (com escopo de namespace) ou operar em todos os namespaces do cluster (com escopo de cluster). Aplicações do Kubernetes podem ficar em namespaces separados para serem isoladas umas das outras e do sistema Kubernetes.

Sempre que possível, os desenvolvedores de operadores devem escolher variantes com escopo de namespace. Isso evita que problemas se espalhem para outras implantações no mesmo cluster. Se um operador precisa fornecer serviços a todas as implantações de um cluster, é necessário usar operadores com escopo de cluster. Um exemplo conhecido é uma implantação que provisiona certificados automaticamente para aplicações.

Uma forma de impedir que pods e contêineres manipulem o restante do sistema Kubernetes é usar securityContexts, que também podem ser aplicados aos contêineres dos operadores. Veja um exemplo de trecho YAML que limita as permissões de um pod:

securityContext:
  privileged: false
  allowPrivilegeEscalation: false
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  readOnlyRootFilesystem: true

Neste exemplo, partimos do princípio de que o contêiner está em execução no cluster do Kubernetes em que opera. Com esse trecho, impedimos que os processos obtenham privilégios de root e modifiquem o sistema de arquivos raiz. Se o operador for comprometido por algum motivo, o invasor terá sua capacidade de agir no sistema host limitada.

A próxima etapa é definir restrições de segurança para pods em todo o cluster. Antes da versão 1.21 do Kubernetes, fazíamos isso com o objeto PodSecurityPolicy (PSP), que agora foi descontinuado. Seu sucessor, PodSecurityAdmission (PSA), é um recurso beta no Kubernetes versão 1.23.

Infelizmente, essa nova PSA não permite o mesmo nível de controle personalizado e detalhado que o YAML do exemplo anterior. Em vez disso, escolhemos entre três níveis de política recém-definidos — privilegiado, básico e restrito — para aplicar a cada namespace.

apiVersion: v1
kind: Namespace
metadata:
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/warn: restricted

Neste exemplo, nosso namespace está configurado para aplicar o nível intermediário de segurança básico e emitir avisos no nível restrito, como o nome sugere. As definições exatas dessas políticas estão na documentação do Kubernetes sobre os Padrões de segurança de pods.

Benefícios dos operadores para a segurança

Embora os operadores do Kubernetes tragam algumas considerações de segurança, eles também podem tornar um cluster mais seguro. Como vimos, os operadores do Kubernetes executam ações e configurações que normalmente ficariam a cargo de operadores humanos — que podem cometer erros e, de fato, cometem. A configuração e o controle executados por um programa são mais confiáveis e reproduzíveis do que as ações de uma pessoa.

Quando são criados corretamente, os operadores eliminam erros causados por negligência ou até mesmo por má-fé. A velocidade de resposta também é essencial para a segurança. Os operadores de software têm uma vantagem significativa sobre os humanos na resposta a problemas, tanto para alertar quanto para resolver uma ocorrência.

A maioria das implantações em um cluster se concentra nas operações diárias da aplicação, mas também é possível implantar serviços dedicados de gerenciamento de segurança diretamente no cluster. O loop de controle de um operador é a melhor forma de gerenciá-los.

Soluções para implantações seguras do Kubernetes

O desenvolvimento de operadores do Kubernetes tornou possível estender a API do Kubernetes com lógica personalizada dentro de um cluster. Se usada de forma inadequada, essa capacidade adicional pode ser explorada por agentes mal-intencionados. Mas, como desenvolvedores, podemos proteger nossas implantações do Kubernetes com regras de permissão e outras restrições. O principal recurso do Kubernetes para gerenciar permissões é o RBAC, que permite especificar privilégios.

Os operadores também podem trazer benefícios de segurança ao substituir processos manuais, que muitas vezes estão sujeitos a erros humanos. Eles permitem executar serviços dedicados de segurança, como o Snyk, dentro de um cluster.

A Snyk oferece soluções para as possíveis vulnerabilidades abordadas neste artigo e muitas outras, alertando os desenvolvedores sobre problemas de segurança assim que surgem durante a programação. Em particular, a Snyk oferece um operador do Kubernetes que podemos instalar no cluster. Depois da instalação, a Snyk identifica e informa vulnerabilidades assim que surgem em cargas de trabalho novas ou existentes no cluster.

Proteja a infraestrutura desde a origem

A Snyk automatiza a segurança e a conformidade de IaC nos fluxos de trabalho e detecta recursos com configurações divergentes ou ausentes.

Leia mais

feature customer snowflake
Article

Segurança desde o início: conheça a integração do Snyk Studio com o Snowflake Cortex Code

O Snyk Studio se integra ao Snowflake Cortex Code para detectar vulnerabilidades em código gerado por IA, dependências e contêineres durante o desenvolvimento.

blog feature pypi spoof
Article

A Snyk AI Security Platform completa, grátis para mantenedores de projetos open source

Mantenedores de projetos open source estão sobrecarregados com relatórios reais de vulnerabilidades e precisam de ajuda para priorizar, corrigir e lançar correções mais rápido. O Secure Developer Program da Snyk dá aos projetos qualificados acesso gratuito à Snyk AI Security Platform.

feature insights announcement
Blog

Comprometimento da cadeia de suprimentos do node-gyp: um worm npm que se autopropaga e se esconde em binding.gyp

Um novo worm do npm está explorando binding.gyp para acionar o node-gyp durante a instalação, permitindo que pacotes maliciosos executem código sem scripts de ciclo de vida. Ele rouba credenciais, mantém persistência no GitHub e se propaga entre contas de mantenedores.