CiberLab
Logotipo Ciência Embarcada Ciência Embarcada

Hardening de Contêineres e Kubernetes

Da Construção de Imagens Seguras à Blindagem de Clusters e Microsserviços

Sumário

  1. 1.Introdução e fundamentos do isolamento em contêineres
  2. 2.Construção de imagens seguras e redução da superfície de ataque
  3. 3.Execução non-root e mitigação de escape de contêineres
  4. 4.Isolamento em nível de kernel: Linux Capabilities, Seccomp e AppArmor
  5. 5.Segurança na cadeia de suprimentos: SBOM e assinatura com Cosign
  6. 6.Arquitetura defensiva e superfície de ataque no Kubernetes
  7. 7.Autenticação, RBAC e privilégio mínimo no cluster
  8. 8.Blindagem do Control Plane e conformidade com CIS Benchmarks
  9. 9.Controle de admissão com Pod Security Standards e Kyverno
  10. 10.Microssegmentação de rede leste-oeste com NetworkPolicies
  11. 11.Gestão avançada de segredos e integração com cofres corporativos
  12. 12.Observabilidade de segurança em tempo de execução
  13. 13.Conclusão
  14. Glossário
  15. Referências
  16. Apêndice A, checklist operacional de auditoria e validação técnica

1. Introdução e fundamentos do isolamento em contêineres

A consolidação dos contêineres como padrão dominante para empacotamento e execução de microsserviços transformou a arquitetura de sistemas operacionais e redes corporativas. Contudo, essa ampla adoção gerou uma das falhas conceituais mais perigosas da engenharia de infraestrutura: a crença de que contêineres funcionam como máquinas virtuais isoladas.

Em uma máquina virtual tradicional, a barreira de isolamento é sustentada por um hipervisor de hardware, com cada sistema operacional executando seu próprio kernel autônomo, sua própria tabela de páginas de memória e seus próprios drivers. Em contrapartida, um contêiner é apenas um processo comum do espaço de usuário, executado diretamente sobre o kernel compartilhado do hospedeiro, contido por um conjunto de primitivas lógicas do sistema operacional Linux.

1.1 O tripé do isolamento: Namespaces, Cgroups e LSM

O confinamento de processos em ambientes OCI (Open Container Initiative), padronizado por runtimes como Docker, containerd e CRI-O, depende fundamentalmente de três mecanismos providos pelo kernel Linux:

Namespaces
Responsáveis por particionar a visão dos recursos globais do sistema operacional. O Linux fornece namespaces para identificadores de processos (PID), redes e interfaces (NET), pontos de montagem e sistemas de arquivos (MNT), comunicação entre processos (IPC), nomes de host e nós de rede (UTS) e identidades de usuários e grupos (USER). Um processo restrito em um namespace enxerga exclusivamente os recursos alocados à sua própria árvore de execução.
Control Groups (Cgroups v1 e v2)
Mecanismo responsável por medir, limitar e restringir o consumo de recursos físicos finitos, como tempo de CPU (Central Processing Unit), consumo de memória RAM (Random Access Memory), operações de entrada e saída em disco (I/O) e descritores de processos (PIDs limit). A ausência de limites estritos em cgroups permite que um contêiner comprometido esgote a memória do nó físico hospedeiro, acionando o OOM (Out Of Memory) Killer do kernel e derrubando serviços vizinhos essenciais.
Módulos de Segurança do Linux (LSM)
Camada de mediação compulsória que inclui SELinux (Security-Enhanced Linux) e AppArmor. Esses módulos inspecionam as ações operacionais do processo contra uma matriz formal de políticas, impedindo que o processo acesse nós de dispositivos do sistema operacional, soquetes internos do kernel ou caminhos sensíveis em /proc e /sys, mesmo que o processo em questão esteja executando com privilégios de superusuário.
A segurança de contêineres não começa no cluster em produção, mas na higiene da imagem base, na redução drástica da superfície de ataque e na recusa inegociável de privilégios de superusuário.
O mito da fronteira de segurança padrão

A configuração padrão da maioria dos runtimes de contêiner não cria uma fronteira de segurança impenetrável. Um processo rodando como UID 0 (root) dentro de um contêiner sem mapeamento de user namespaces é, diante das chamadas de sistema (syscalls) do kernel, o próprio superusuário do hospedeiro. Se o processo encontrar uma brecha em drivers, no sistema de arquivos compartilhado ou em capabilities desnecessárias, o escape para o nó físico é imediato.

1.2 O modelo de defesa em profundidade

O endurecimento operacional (hardening) de infraestruturas baseadas em contêineres exige uma abordagem em múltiplas camadas independentes. A violação de uma única camada não pode expor os dados da organização nem conceder acesso irrestrito ao restante da infraestrutura corporativa.

A engenharia defensiva para contêineres e clusters orquestrados é estruturada em quatro domínios de controle rigorosos, ilustrados a seguir:

1. Imagem e Supply Chain Bases distroless, compilação multi-stage, escaneamento de CVEs e assinatura Cosign 2. Runtime de Contêiner e Isolamento de Kernel Execução non-root, drop de capabilities, filtragem Seccomp e perfis AppArmor 3. Orquestração e Políticas de Cluster Pod Security Standards no modo Restricted, RBAC restrito e controle Kyverno 4. Rede Leste-Oeste e Gestão Criptográfica Microssegmentação com NetworkPolicies (default-deny), mTLS e cofre de segredos
Figura 1 · Modelo de defesa em profundidade da infraestrutura de contêineres e orquestração.

2. Construção de imagens seguras e redução da superfície de ataque

Toda vulnerabilidade presente na imagem de contêiner é transferida diretamente para o ambiente de produção. O hábito comum de basear imagens corporativas em distribuições completas de uso geral, como Ubuntu ou Debian padrão, injeta centenas de megabytes de código supérfluo e utilitários que jamais serão executados pela aplicação, mas que servem perfeitamente a um invasor em caso de comprometimento.

2.1 A ameaça dos utilitários administrativos residuais

Se uma aplicação web sofrer uma vulnerabilidade de injeção remota de comandos (RCE, Remote Code Execution), o sucesso da exploração depende criticamente dos binários disponíveis no sistema de arquivos local. A presença de utilitários como curl, wget, nc (netcat), python, apt, bash ou interpretadores Perl fornece as ferramentas exatas que o atacante necessita para baixar artefatos adicionais, estabelecer uma conexão reversa (reverse shell) e iniciar a varredura da rede interna.

A prática recomendada consiste no uso de imagens mínimas especializadas, conhecidas como imagens distroless ou imagens baseadas em scratch e Alpine reduzida. Imagens distroless contêm exclusivamente o binário da aplicação compilada e suas dependências de tempo de execução (como bibliotecas C dinâmicas e certificados de AC raiz), eliminando completamente gerenciadores de pacotes, interpretadores e shells interativos.

2.2 Compilação em múltiplos estágios (Multi-Stage Builds)

A metodologia de compilação em múltiplos estágios separa rigorosamente as ferramentas necessárias para compilar o código-fonte (como compiladores Go, SDKs Java, Node.js completo e cabeçalhos de compilação) do ambiente que recebe o artefato final para execução. O código-fonte bruto e os compiladores permanecem isolados nas camadas intermediárias de build, descartadas ao término do processo.

O exemplo técnico a seguir ilustra a construção segura de um microsserviço com compilação multi-stage, criação de usuário não privilegiado com identificador estático e descarte total de ferramentas de desenvolvimento:

# -----------------------------------------------------------------------------
# Estágio 1: Ambiente de compilação temporário (Build Stage)
# -----------------------------------------------------------------------------
FROM golang:1.24-bookworm AS builder

WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download

COPY . .
# Compilação estática: desativa dependência de bibliotecas C dinâmicas (CGO)
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-w -s" -o /bin/app ./cmd/server

# -----------------------------------------------------------------------------
# Estágio 2: Imagem final mínima para execução em produção
# -----------------------------------------------------------------------------
FROM gcr.io/distroless/static-debian12:nonroot

WORKDIR /app
# Copia exclusivamente o binário compilado a partir do estágio anterior
COPY --from=builder /bin/app /app/server

# Execução obrigatória sob o UID não privilegiado (65532:nonroot no distroless)
USER 65532:65532

EXPOSE 8080
ENTRYPOINT ["/app/server"]

A tabela a seguir compara o impacto das diferentes abordagens de construção de imagens de contêiner em relação à área de exposição a vulnerabilidades conhecidas (CVEs, Common Vulnerabilities and Exposures):

Tabela 1 · Comparação da superfície de exposição entre imagens base típicas
Tipo de Imagem Base Tamanho Médio Presença de Shell Gerenciador de Pacotes CVEs Médias em Repouso
Distribuição Completa (ex: Ubuntu 22.04) 78 MB a 150 MB Sim (bash, sh) Sim (apt, dpkg) Alta (25 a 80 vulnerabilidades)
Distribuição Mínima (ex: Alpine Linux) 7 MB a 12 MB Sim (/bin/sh via busybox) Sim (apk) Baixa (geralmente 0 a 5)
Distroless Estático (ex: Distroless Nonroot) 2 MB a 18 MB Não (ausente) Não (ausente) Mínima (geralmente zero)
Imagem Vazia (scratch) Apenas o binário Não (ausente) Não (ausente) Zero vulnerabilidades de SO
Fixação de dependências por hash criptográfico (Digest Pinning)

Tags mutáveis como latest, alpine:3.20 ou bookworm podem ser sobrescritas nos registros públicos de contêineres, introduzindo quebras de compatibilidade ou componentes adulterados. Em ambientes produtivos regulados, declare as imagens base referenciando o digest SHA-256 imutável: FROM golang@sha256:726354.... Essa prática garante a reprodutibilidade absoluta do processo de compilação.

3. Execução non-root e mitigação de escape de contêineres

Executar contêineres como superusuário (UID 0) é a causa direta da severidade crítica da maioria das vulnerabilidades de escape documentadas nos últimos anos. Se a aplicação não define explicitamente um usuário de menor privilégio na diretiva USER do Dockerfile ou na especificação do Pod, o runtime adota o root como padrão de execução.

3.1 A mecânica do Container Escape

O escape de contêiner ocorre quando um invasor, tendo obtido execução de código no espaço do contêiner, explora privilégios mal configurados para interagir diretamente com o sistema operacional hospedeiro. Vetores clássicos de escape incluem:

3.2 User Namespaces: desacoplando o UID do contêiner do host

O isolamento provido pelo namespace de usuários (User Namespaces) permite mapear uma faixa de UIDs e GIDs virtuais de dentro do contêiner para uma faixa completamente desprovida de privilégios no sistema operacional hospedeiro. Dessa forma, mesmo que a aplicação execute internamente como UID 0 (root virtual), para o kernel do host esse processo é reconhecido como um identificador arbitrário inofensivo, como o UID 100000.

Caso o processo consiga burlar as restrições do sistema de arquivos e alcançar o hospedeiro, ele não possuirá permissões para ler arquivos confidenciais em /etc/shadow, nem para enviar sinais de término a outros processos do sistema.

A flag no-new-privileges

Por padrão, executáveis com bits SUID ativados (como sudo ou passwd) podem elevar os privilégios do chamador durante a execução. O runtime de contêiner deve ser configurado com o parâmetro de segurança --security-opt=no-new-privileges:true (no Docker/Podman) ou allowPrivilegeEscalation: false (no Kubernetes). Essa restrição impede que qualquer processo filho ganhe privilégios adicionais por meio de binários setuid/setgid ou transições de capabilities.

4. Isolamento em nível de kernel: Linux Capabilities, Seccomp e AppArmor

O modelo de permissões clássico do Unix era binário: um processo executava com privilégios de superusuário (UID 0) e podia realizar qualquer operação, ou operava como usuário comum e sofria bloqueios universais. Para mitigar esse risco estrutural, o kernel Linux fracionou o poder absoluto do superusuário em unidades atômicas granulares conhecidas como Linux Capabilities.

4.1 Princípio do privilégio mínimo em Capabilities

A configuração padrão dos runtimes OCI concede cerca de 14 capabilities automáticas para cada novo contêiner (incluindo CAP_NET_RAW, CAP_CHOWN, CAP_DAC_OVERRIDE e CAP_FOWNER). A ampla maioria dos serviços de microsserviços modernos, como servidores web e APIs REST, necessita de zero privilégios especiais de kernel.

A postura defensiva obrigatória consiste em descartar compulsória e universalmente todas as capabilities através da instrução drop: ["ALL"], reintroduzindo exclusivamente aquelas cuja ausência comprovadamente inviabilize o funcionamento do serviço:

# Exemplo de especificação de segurança em Pod do Kubernetes
securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 10001
  runAsGroup: 10001
  capabilities:
    drop:
      - ALL
    add:
      - NET_BIND_SERVICE # Permite escutar em portas abaixo de 1024, se indispensável
Tabela 2 · Capabilities perigosas que devem ser terminantemente banidas em produção
Linux Capability Operação Habilitada Risco de Segurança em Caso de Comprometimento
CAP_SYS_ADMIN Montagem de sistemas de arquivos, manipulação de namespaces, debug Equivalente a root total; vetor direto para escape de contêiner.
CAP_SYS_PTRACE Rastreamento de processos via syscall ptrace Permite ler a memória de processos vizinhos e extrair segredos/tokens.
CAP_NET_ADMIN Configuração de interfaces de rede, tabelas de roteamento e firewall Permite desativar regras defensivas e capturar tráfego de outros pods.
CAP_NET_RAW Criação de pacotes RAW e pacotes ICMP personalizados Permite forjar cabeçalhos IP (IP Spoofing) e ataques ARP spoofing.
CAP_SYS_MODULE Carregamento e descarregamento de módulos de kernel (LKM) Permite injetar rootkits diretamente no núcleo do sistema hospedeiro.
CAP_DAC_OVERRIDE Ignora restrições de permissões de leitura, escrita e execução em arquivos Anula o controle de acesso discricionário tradicional do sistema.

4.2 Filtragem de chamadas de sistema com Seccomp

O kernel Linux implementa mais de 450 chamadas de sistema (syscalls). Um microsserviço típico em Go, Rust ou Node.js raramente precisa de mais de 50 syscalls ativas para cumprir sua função de negócios. Syscalls arcaicas, experimentais ou destinadas à depuração e gerenciamento de hardware representam superfícies de ataque que facilitam a exploração de vulnerabilidades de corrupção de memória no próprio kernel.

O Seccomp (Secure Computing Mode) intercepta as chamadas de sistema efetuadas pelas threads do contêiner antes que alcancem o núcleo do sistema operacional. Caso uma instrução proibida seja disparada, o Seccomp pode abortar a chamada com erro (EPERM) ou terminar o processo infrator imediatamente (SIGKILL).

O Kubernetes introduziu o perfil padrão RuntimeDefault, que deve ser habilitado compulsória e globalmente em todos os pods do cluster através da configuração:

securityContext:
  seccompProfile:
    type: RuntimeDefault

4.3 Sistema de arquivos raiz em modo somente leitura (Read-Only Root FS)

A técnica de forçar o sistema de arquivos do contêiner para o modo somente leitura (readOnlyRootFilesystem: true) neutraliza classes inteiras de ataques pós-exploração. Se um invasor obtiver execução remota de código, ele não conseguirá gravar binários maliciosos, modificar scripts de inicialização, alterar arquivos de configuração em /etc nem baixar ferramentas em /tmp.

Se a aplicação necessitar de diretórios temporários transitórios para cache de escrita ou processamento de arquivos em trânsito, esses caminhos específicos devem ser montados isoladamente como volumes emptyDir baseados em memória RAM (medium: Memory) com limites estritos de tamanho, mantendo o restante da árvore de arquivos imutável.

5. Segurança na cadeia de suprimentos: SBOM e assinatura com Cosign

Proteger o ambiente de execução em tempo real é ineficaz se o código ou as dependências que compõem a imagem forem adulterados antes da implantação. Incidentes cibernéticos contemporâneos atingem prioritariamente a cadeia de suprimentos de software (Software Supply Chain), inserindo cavalos de Troia em bibliotecas de código aberto populares ou comprometendo chaves de esteiras de integração contínua (CI/CD, Continuous Integration and Continuous Delivery).

5.1 Inventário de componentes com SBOM

Um SBOM (Software Bill of Materials) é a relação formal, estruturada e legível por máquina de todos os pacotes, dependências transitivas, bibliotecas e metadados que integram um artefato de software. Os padrões internacionais consolidados para geração de SBOMs são o SPDX (Software Package Data Exchange) e o CycloneDX.

A geração contínua do SBOM durante o processo de build do contêiner permite que a organização responda com agilidade a alertas emergenciais de vulnerabilidades críticas recém-descobertas (Zero-Day). Em vez de varrer servidores e clusters em produção buscando manualmente a presença de uma biblioteca vulnerável, a equipe de segurança consulta o repositório central de SBOMs e identifica em segundos todos os contêineres e versões afetadas.

5.2 Assinatura e verificação criptográfica com Cosign

O ecossistema Sigstore fornece o utilitário cosign, padronizando a assinatura digital de artefatos OCI e o armazenamento das assinaturas diretamente no registro de contêineres corporativo, sem a necessidade de manter infraestruturas proprietárias complexas.

A garantia de autenticidade da imagem baseia-se em uma regra inegociável: o orquestrador Kubernetes deve recusar terminantemente a inicialização de qualquer contêiner cuja imagem não apresente uma assinatura criptográfica válida, emitida pela chave privada oficial da esteira institucional de CI/CD.

# Geração do par de chaves assimétricas para a esteira
cosign generate-key-pair

# Assinatura digital do artefato recém-compilado no registro seguro
cosign sign --key cosign.key ciberlab-registry.local/apps/payment-service:v2.1.0

# Anexação do arquivo de SBOM formal (formato SPDX ou CycloneDX) à imagem
cosign attach sbom --sbom ./sbom.spdx.json ciberlab-registry.local/apps/payment-service:v2.1.0

# Assinatura criptográfica do atestado de proveniência e do SBOM anexado
cosign sign --key cosign.key ciberlab-registry.local/apps/payment-service:v2.1.0
Varredura de vulnerabilidades com bloqueio automatizado

Integre analisadores de vulnerabilidades estáticas de código e contêineres (como Trivy ou Grype) diretamente na esteira de integração. Estabeleça uma política rígida que interrompa automaticamente a compilação (retornando exit code 1) diante da detecção de falhas classificadas com severidade CRITICAL ou HIGH que já possuam correções disponíveis (--ignore-unfixed desativado).

6. Arquitetura defensiva e superfície de ataque no Kubernetes

O Kubernetes é um sistema distribuído de alta complexidade projetado primariamente para elasticidade e orquestração em escala. Quando implantado com configurações padrão de fábrica, o cluster apresenta uma superfície de ataque exposta em múltiplos componentes do plano de controle (Control Plane) e dos nós de processamento (Worker Nodes).

6.1 Superfície de ataque do Control Plane

O Control Plane hospeda o cérebro da infraestrutura. A violação de qualquer um de seus componentes concede controle irrestrito sobre todas as cargas de trabalho da organização:

6.2 Superfície de ataque dos nós de trabalho (Worker Nodes)

Em cada nó de trabalho, o agente kubelet opera com privilégios de superusuário no sistema operacional, gerenciando o ciclo de vida dos contêineres e comunicando-se com o runtime através da CRI (Container Runtime Interface):

7. Autenticação, RBAC e privilégio mínimo no cluster

O mecanismo de RBAC (Role-Based Access Control) do Kubernetes é responsável por regular o acesso à API do cluster, definindo com precisão quem pode executar quais verbos operacionais sobre quais recursos em cada namespace.

7.1 Princípios fundamentais para um RBAC resiliente

O erro de modelagem mais comum em operações de Kubernetes é a concessão negligente de cluster-admin a usuários e contas de serviço, ou o uso excessivo de coringas (verbs: ["*"], resources: ["*"]) em manifestos de configuração para contornar problemas de permissão durante o desenvolvimento.

Diretrizes compulsórias para desenho de papéis de segurança:

Prevalência de RoleBindings sobre ClusterRoleBindings
Um RoleBinding confina a validade das permissões a um único namespace específico. O uso de ClusterRoleBinding estende o privilégio por todos os namespaces do cluster, expondo recursos sensíveis e pods administrativos de outros sistemas.
Banimento de coringas operacionais
Declare explicitamente os verbos necessários (["get", "list", "watch"]) e os recursos exatos (["pods", "services"]). Jamais use o asterisco para facilitar a implantação.
Proteção contra escalonamento indireto de privilégios
A permissão para criar ou editar recursos como pods, deployments ou daemonsets permite que um usuário crie um pod com montagem do sistema de arquivos raiz do host, escalando privilégios até root da máquina física. De forma similar, o verbo bind ou escalate sobre roles não pode ser concedido a usuários não administradores.

7.2 Higiene e restrição de ServiceAccounts

Por padrão, todo namespace cria automaticamente uma conta de serviço chamada default. Em versões históricas do Kubernetes, o token JWT (JSON Web Token) associado a essa conta era injetado silenciosa e automaticamente em cada pod criado no diretório /var/run/secrets/kubernetes.io/serviceaccount/token.

Se a aplicação for comprometida, o invasor extrai esse token e ganha acesso imediato à API do Kubernetes com as permissões daquela ServiceAccount. A prática mandatória para aplicações de negócios que não realizam gestão programática do cluster consiste em desativar explicitamente o automount do token:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: payment-processor-sa
  namespace: finance
# Desativa a injeção compulsória do token JWT nos contêineres do Pod
automountServiceAccountToken: false

8. Blindagem do Control Plane e conformidade com CIS Benchmarks

O CIS (Center for Internet Security) publica o CIS Kubernetes Benchmark, referência internacional consagrada que define mais de 100 controles técnicos para auditoria e endurecimento operacional de clusters corporativos.

8.1 Parâmetros críticos de configuração do kube-apiserver

O arquivo de manifesto do kube-apiserver (comumente localizado em /etc/kubernetes/manifests/kube-apiserver.yaml em instalações baseadas em nós autônomos) deve ser parametrizado com as seguintes diretivas obrigatórias:

8.2 Criptografia em repouso no etcd (Encryption at Rest)

Por padrão, o etcd persiste todos os recursos em formato de texto claro desprotegido. A obtenção de um backup desprotegido do etcd ou o acesso físico aos discos do servidor expõe imediatamente todos os segredos corporativos, certificados e chaves de API da instituição.

A blindagem exige a criação de uma EncryptionConfiguration, associada ao kube-apiserver através da flag --encryption-provider-config. O provedor recomendado para ambientes de alta segurança é a integração com um KMS (Key Management Service) externo via plugin gRPC, garantindo que as chaves de criptografia sejam rotacionadas periodicamente fora do ambiente do cluster:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
      - configmaps
    providers:
      - kms:
          apiVersion: v2
          name: corporate-kms-provider
          endpoint: unix:///run/kms/kms.sock
      - aescbc:
          keys:
            - name: primary-key
              secret: dGVzdGUtc2VncmVkby1mb3J0ZS1jaWJlcmxhYi0yNTY=
      - identity: {} # Permite a leitura de dados legados durante a migração

8.3 Blindagem do Kubelet nos Worker Nodes

No arquivo de configuração /var/lib/kubelet/config.yaml presente em cada nó de trabalho, os seguintes parâmetros do CIS Benchmark devem ser confirmados:

authentication:
  anonymous:
    enabled: false # Proíbe acesso sem credenciais na porta 10250
  webhook:
    enabled: true
authorization:
  mode: Webhook # Força validação das permissões de quem chama contra o API Server
protectKernelDefaults: true # Aborta a inicialização se os parâmetros de sysctl divergirem
readOnlyPort: 0 # Desativa a porta legada não autenticada 10255

9. Controle de admissão com Pod Security Standards e Kyverno

A barreira mais eficaz para impedir que manifestos perigosos sejam aceitos pelo cluster é o controle de admissão (Admission Control). Os controladores de admissão interceptam requisições já autenticadas e autorizadas no kube-apiserver antes que qualquer modificação seja persistida no etcd.

1. Requisição kubectl apply 2. Auth & RBAC Verificação TLS 3. Mutating Injeção segura 4. Validating Kyverno / PSS 5. etcd Persistência
Figura 2 · Fluxo arquitetural de admissão, validação de políticas e persistência no Kubernetes.

9.1 Pod Security Standards (PSS) nativo

Com a depreciação e remoção do antigo mecanismo de PodSecurityPolicies (PSP), o Kubernetes padronizou os Pod Security Standards (PSS), implementados nativamente pelo controlador Pod Security Admission (PSA). O PSS define três perfis de conformidade:

Privileged
Nenhuma restrição aplicada. Reservado exclusivamente para agentes de infraestrutura crítica do sistema (como plugins CNI de rede e drivers de armazenamento CSI).
Baseline
Impede escalonamento de privilégios óbvios, proibindo o uso de hostNetwork, hostPID, hostIPC e a montagem direta de volumes hostPath desprotegidos.
Restricted
O perfil corporativo de máxima segurança. Exige obrigatoriamente execução como non-root, drop de todas as capabilities com retenção seletiva estrita, sistema de arquivos raiz em modo somente leitura (read-only) e ativação de perfis Seccomp.

Para aplicar o perfil restrito de forma compulsória em um namespace corporativo, utilizam-se labels de controle no próprio manifesto do namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: billing
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/audit: restricted

9.2 Governança declarativa avançada com Kyverno

Embora o PSS nativo seja indispensável, organizações corporativas demandam regras de governança customizadas que vão além da especificação básica de pods. O Kyverno é um mecanismo nativo do Kubernetes que executa políticas como código utilizando YAML declarativo tradicional, sem exigir o aprendizado de linguagens complexas adicionais.

O manifesto abaixo ilustra uma política do Kyverno que bloqueia a inicialização de qualquer contêiner cuja imagem provenha de repositórios públicos não autorizados ou que utilize tags genéricas mutáveis como latest:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: enforce-trusted-registry-and-tags
spec:
  validationFailureAction: Enforce
  rules:
    - name: validate-registry-source
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Imagens devem ser originadas exclusivamente do registro seguro corporativo ciberlab-registry.local."
        pattern:
          spec:
            containers:
              - image: "ciberlab-registry.local/*"
    - name: disallow-latest-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "O uso da tag mutável :latest é terminantemente proibido em produção."
        pattern:
          spec:
            containers:
              - image: "!*:latest"

10. Microssegmentação de rede leste-oeste com NetworkPolicies

Por especificação de design original, o modelo de rede do Kubernetes adota a premissa de conectividade total irrestrita (Flat Network): qualquer pod em qualquer namespace pode comunicar-se diretamente com qualquer outro pod em qualquer outro namespace por padrão.

10.1 O perigo da rede plana e o tráfego leste-oeste

Em uma rede plana desprotegida, caso um atacante obtenha sucesso explorando uma vulnerabilidade em um serviço web exposto ao público (tráfego norte-sul), ele pode iniciar imediatamente o reconhecimento interno e movimentação lateral (tráfego leste-oeste). Sem barreiras de isolamento, o servidor web comprometido conecta-se livremente a bancos de dados privados, filas de mensagens e APIs internas de outros departamentos.

A engenharia defensiva exige a aplicação do princípio do Default Deny (bloqueio padrão). Cada namespace deve possuir uma política inicial que feche integralmente todo o tráfego de entrada (Ingress) e todo o tráfego de saída (Egress):

# Política mandatória de isolamento total inicial do namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-traffic
  namespace: finance
spec:
  podSelector: {} # Aplica-se a 100% dos pods no namespace finance
  policyTypes:
    - Ingress
    - Egress

10.2 Liberação cirúrgica de fluxos legítimos

Após a imposição do bloqueio universal, a equipe de engenharia cria manifestos adicionais de NetworkPolicy liberando cirurgicamente apenas os fluxos de rede indispensáveis para o serviço. Uma API de pagamentos, por exemplo, deve aceitar conexões exclusivamente na porta TCP 8443 a partir de pods rotulados como role: api-gateway, e emitir tráfego externo exclusivamente para o banco de dados institucional na porta TCP 5432 e para o serviço de DNS do cluster:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-gateway-and-egress-db
  namespace: finance
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-system
          podSelector:
            matchLabels:
              role: api-gateway
      ports:
        - protocol: TCP
          port: 8443
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres-database
      ports:
        - protocol: TCP
          port: 5432
    - to: # Liberação obrigatória de resolução DNS interna
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
Exigência de CNI com suporte a políticas

O Kubernetes API Server aceita e armazena manifestos de NetworkPolicy independentemente da infraestrutura subjacente. Contudo, o componente responsável por fiscalizar e aplicar efetivamente as regras de bloqueio é o plugin de rede CNI (Container Network Interface). Plugins legados básicos (como Flannel sem canalização de extensão) ignoram silenciosamente as políticas sem emitir mensagens de erro. Utilize sempre CNIs corporativas com suporte nativo a eBPF e filtragem estrita, como Cilium ou Calico.

11. Gestão avançada de segredos e integração com cofres corporativos

O recurso nativo Secret do Kubernetes é frequentemente incompreendido. Seus campos de dados não são protegidos por criptografia intrínseca na especificação do manifesto; são apenas codificados em Base64 simples (um método de representação reversível em fração de segundo sem qualquer chave secreta).

11.1 Falhas estruturais na gestão tradicional de segredos

Práticas frágeis comumente observadas que devem ser prontamente eliminadas:

11.2 O padrão moderno: Secrets Store CSI Driver

A arquitetura recomendada pela indústria para microsserviços modernos consiste na dissociação total dos segredos da base de dados do Kubernetes, integrando os nós a um cofre de chaves corporativo externo (como HashiCorp Vault, AWS Secrets Manager ou Azure Key Vault) através do Secrets Store CSI Driver.

Por meio desse padrão, os segredos são buscados no cofre em tempo real e montados como um volume de memória volátil (tmpfs) exclusivamente no momento da inicialização do Pod, sem que nenhum segredo permanente seja gravado no etcd do cluster:

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: vault-db-credentials
  namespace: finance
spec:
  provider: vault
  parameters:
    roleName: "finance-payment-role"
    vaultAddress: "https://vault.internal.ciberlab:8200"
    objects: |
      - objectName: "db-password"
        secretPath: "database/creds/payment-app"
        secretKey: "password"
---
# Montagem do segredo como arquivo no Pod da aplicação
apiVersion: v1
kind: Pod
metadata:
  name: payment-engine
  namespace: finance
spec:
  serviceAccountName: payment-processor-sa
  containers:
    - name: server
      image: ciberlab-registry.local/apps/payment-service:v2.1.0
      volumeMounts:
        - name: secrets-store-inline
          mountPath: "/mnt/secrets/database"
          readOnly: true
  volumes:
    - name: secrets-store-inline
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: "vault-db-credentials"

Essa abordagem viabiliza a rotação automatizada e transparente de credenciais sem reinicialização forçada do pod, reduzindo a validade temporal de tokens vazados.

12. Observabilidade de segurança em tempo de execução

O endurecimento operacional de contêineres e orquestração Kubernetes não constitui um evento pontual de configuração estática, mas um ciclo disciplinado e contínuo de engenharia defensiva, governança de políticas e observabilidade em tempo real.

12.1 Monitoramento comportamental com eBPF e Falco

Enquanto mecanismos estáticos como Seccomp e Pod Security Standards bloqueiam violações preventivas de configurações conhecidas, a detecção de ameaças sofisticadas em tempo de execução exige instrumentação comportamental contínua. O uso da tecnologia eBPF (Extended Berkeley Packet Filter) permite que motores de detecção como o Falco capturem todas as chamadas de sistema no núcleo do hospedeiro com sobrecarga de processamento desprezível.

O monitoramento contínuo deve gerar alertas imediatos para incidentes como:

13. Conclusão

A blindagem da infraestrutura de contêineres consolida-se através da implementação harmoniosa de três pilares estruturais:

1. Higiene na Origem

Construção de imagens com bases distroless mínimas, descarte absoluto de compiladores via multi-stage builds, geração compulsória de SBOM e assinatura criptográfica com Cosign na esteira de CI/CD.

2. Barreira no Ponto de Admissão

Aplicação compulsória de Pod Security Standards no nível Restricted, governança declarativa com Kyverno e bloqueio inegociável de contêineres root, privileged ou sem limites de recursos.

3. Blindagem de Rede e Runtime

Microssegmentação leste-oeste com políticas de default-deny, mTLS entre microsserviços, segredos fornecidos sob demanda via cofre externo e telemetria de detecção baseada em eBPF.

Engenharia, disciplina de configuração e automação de conformidade constituem as únicas salvaguardas reais para sustentar sistemas digitais seguros, resilientes e escaláveis.

Glossário

Cgroups (Control Groups)
Primitiva do kernel Linux que isola, limita e monitora o uso de recursos físicos de hardware (CPU, memória RAM, operações de I/O em disco e contagem de processos) alocados a uma árvore de execução.
CIS (Center for Internet Security)
Organização sem fins lucrativos reconhecida globalmente pelo desenvolvimento de guias de melhores práticas e benchmarks rigorosos de configuração defensiva para sistemas operacionais, nuvens e Kubernetes.
CNI (Container Network Interface)
Especificação padronizada do ecossistema de contêineres que define como plugins de rede (como Cilium, Calico e Flannel) devem provisionar conectividade, alocação de IPs e aplicação de políticas de tráfego entre pods.
Cosign
Ferramenta do projeto aberto Sigstore desenvolvida para assinar digitalmente, validar e verificar artefatos de contêiner OCI e atestados de conformidade diretamente em registros de imagens.
CRI (Container Runtime Interface)
Interface de plug-in de chamada de procedimento remoto (gRPC) que permite ao kubelet interagir de forma intercambiável com diferentes runtimes de contêiner (como containerd e CRI-O).
CSI (Container Storage Interface)
Especificação padrão para viabilizar a integração entre provedores de armazenamento externos (e cofres de credenciais) e os orquestradores de contêineres.
Distroless
Categoria de imagem de contêiner extremamente enxuta que inclui exclusivamente a aplicação compilada e suas dependências diretas de tempo de execução, descartando shells, utilitários Unix e gerenciadores de pacotes.
eBPF (Extended Berkeley Packet Filter)
Tecnologia revolucionária do kernel Linux que permite executar programas seguros e verificados diretamente no núcleo do sistema operacional sem alterar o código-fonte do kernel nem carregar módulos adicionais.
IMDS (Instance Metadata Service)
Ponto de extremidade HTTP de endereço local (típico IP 169.254.169.254) disponibilizado por provedores de computação em nuvem para fornecer credenciais e metadados à máquina virtual em execução.
KMS (Key Management Service)
Serviço seguro e centralizado para geração, guarda, rotação e utilização de chaves criptográficas corporativas de alta segurança.
LSM (Linux Security Module)
Estrutura flexível do kernel Linux que permite a módulos de controle de acesso mandatório (como SELinux e AppArmor) inspecionar e mediar operações antes que sejam processadas.
mTLS (Mutual Transport Layer Security)
Protocolo de comunicação segura no qual cliente e servidor realizam autenticação recíproca apresentando e validando seus respectivos certificados digitais X.509.
Namespaces
Recurso nativo do kernel Linux que isola e particiona recursos globais do sistema operacional (como processos, rede, sistemas de arquivos e usuários) para proporcionar a ilusão de um ambiente independente.
OCI (Open Container Initiative)
Consórcio de governança tecnológica que padroniza os formatos abertos de imagens de contêiner (Image Spec) e de runtimes de execução (Runtime Spec).
OIDC (OpenID Connect)
Camada de identidade simples e aberta implementada sobre o protocolo de autorização OAuth 2.0, amplamente utilizada para autenticação segura de usuários no Kubernetes API Server.
PSA / PSS (Pod Security Admission / Pod Security Standards)
Mecanismo e especificação oficial nativa do Kubernetes para classificação e aplicação compulsória de diretivas de segurança em pods (Privileged, Baseline e Restricted).
RBAC (Role-Based Access Control)
Modelo de governança de segurança que restringe a capacidade de realizar ações no sistema de acordo com papéis funcionais estritos associados aos usuários ou processos autorizados.
RCE (Remote Code Execution)
Vulnerabilidade crítica de segurança que concede ao atacante a capacidade de executar comandos arbitrários no sistema alvo a partir de uma conexão remota.
SBOM (Software Bill of Materials)
Documento formal legível por máquina contendo a lista completa de componentes, bibliotecas, módulos e dependências que formam um produto ou artefato de software.
Seccomp (Secure Computing Mode)
Recurso de segurança do kernel Linux que permite filtrar e interceptar chamadas de sistema efetuadas por um processo, restringindo sua liberdade operacional a uma lista controlada.
SUID / SGID (Set User ID / Set Group ID)
Permissões especiais de arquivos no Unix/Linux que permitem que um executável rode com os privilégios do proprietário ou grupo do arquivo, e não com os do usuário que o chamou.

Referências

Apêndice A, checklist operacional de auditoria e validação técnica

Este checklist resume os controles essenciais de conformidade técnica abordados nesta cartilha. Ele deve ser utilizado por administradores de infraestrutura, arquitetos de nuvem e auditores de segurança para validar a prontidão operacional de novos contêineres e clusters antes da sua liberação para produção.

Tabela 3 · Checklist de validação de segurança e conformidade técnica para contêineres e Kubernetes
Domínio de Controle Requisito Técnico Critério de Conformidade Status
Construção de Imagens Uso de Imagens Mínimas Imagens baseadas em Distroless ou scratch; ausência total de gerenciadores de pacotes e interpretadores. [   ]
Construção de Imagens Compilação Multi-Stage Ferramentas de build e código-fonte descartados no primeiro estágio; somente artefatos binários na imagem final. [   ]
Cadeia de Suprimentos Geração e Verificação de SBOM Arquivo SBOM gerado em formato SPDX/CycloneDX e armazenado junto ao artefato no registro OCI corporativo. [   ]
Cadeia de Suprimentos Assinatura Digital com Cosign Imagens assinadas criptograficamente na esteira de CI/CD; controle de admissão bloqueia imagens sem assinatura. [   ]
Runtime de Contêiner Execução como Non-Root Diretiva runAsNonRoot: true declarada e UID fixado explicitamente acima de 10000; root desativado. [   ]
Runtime de Contêiner Bloqueio de Elevação de Privilégio Flag allowPrivilegeEscalation: false aplicada compulsória em todos os contêineres de todos os pods. [   ]
Isolamento de Kernel Descarte de Linux Capabilities Diretiva drop: ["ALL"] declarada; reintrodução apenas cirúrgica e justificada tecnicamente. [   ]
Isolamento de Kernel Filtragem com Seccomp Perfil RuntimeDefault ativado nativamente em 100% dos pods do ambiente. [   ]
Isolamento de Kernel Sistema de Arquivos Read-Only Parâmetro readOnlyRootFilesystem: true ativo; escrita restrita a volumes voláteis emptyDir. [   ]
Orquestração K8s Pod Security Standards Namespaces corporativos rotulados com modo enforce: restricted. [   ]
Orquestração K8s Governança com Kyverno Políticas de cluster aplicadas para banir tags mutáveis (latest) e registros públicos não homologados. [   ]
Controle de Acesso Privilégio Mínimo em RBAC Uso de RoleBinding no lugar de ClusterRoleBinding; ausência total de coringas de permissão (*). [   ]
Controle de Acesso Restrição de ServiceAccounts Diretiva automountServiceAccountToken: false ativada em pods que não dialogam com a API do cluster. [   ]
Blindagem do Nó Segurança da API do Kubelet Acesso anônimo desativado na porta 10250; autorização em modo Webhook; porta somente leitura desativada. [   ]
Control Plane Criptografia de Dados no etcd Provedor de criptografia em repouso ativo no kube-apiserver para objetos secrets e configmaps. [   ]
Rede e Firewall Políticas de Default-Deny NetworkPolicy padrão de bloqueio total de Ingress e Egress aplicada em cada namespace corporativo. [   ]
Rede e Firewall Liberação Granular de Tráfego Comunicação leste-oeste liberada exclusivamente entre pods homologados com restrição estrita de portas TCP/UDP. [   ]
Gestão de Segredos Isolamento com Cofre Externo Utilização do Secrets Store CSI Driver integrado ao HashiCorp Vault; eliminação de senhas em variáveis de ambiente. [   ]
Observabilidade Detecção de Anomalias com eBPF Instrumentação com Falco em tempo de execução para alertar spawn de shells interativos e acessos não conformes. [   ]

Cartilha CiberLab · Ciência Embarcada · Lucas Rayan Guerra