Modelo de Ameaças em Kubernetes

Kubernetes revolucionou como deployamos aplicações, mas também introduziu nova superfície de ataque. Antes de implementar controles, e essencial entender o modelo de ameaças específico de ambientes containerizados.

94%
das organizações tiveram incidente de segurança em containers em 2025 (Red Hat State of Kubernetes Security)

Vetores de ataque comuns

  • Imagem comprometida: Vulnerabilidades em base images, dependências maliciosas
  • Escape de container: Privilégios excessivos permitem acesso ao host
  • Lateral movement: Pod comprometido ataca outros pods/services
  • Supply chain: Componentes maliciosos no build pipeline
  • Secrets exposure: Credenciais vazadas em logs, env vars, configmaps
  • API server abuse: RBAC permissivo permite escalação
  • etcd exposure: Acesso direto ao banco de dados do cluster

Camadas de segurança (Defense in Depth)

Segurança em Kubernetes deve ser implementada em múltiplas camadas:

  1. Build time: Imagens seguras, scanning, assinaturas
  2. Deploy time: Admission control, policies
  3. Runtime: Monitoramento, detecção de anomalias
  4. Infrastructure: Host hardening, network segregation

Segurança de Imagens de Container

A segurança começa bem antes do deploy - na construção da imagem.

Melhores práticas de Dockerfile

# Use base image mínima e específica (não :latest)
FROM cgr.dev/chainguard/python:latest-dev AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Multi-stage build - imagem final mínima
FROM cgr.dev/chainguard/python:latest
WORKDIR /app
COPY --from=builder /app .
COPY . .

# Usuário não-root
USER nonroot:nonroot

# Não precisa de shell para maioria das apps
ENTRYPOINT ["python", "app.py"]

Checklist de imagem segura

  • [ ] Base image mínima (distroless, alpine, chainguard)
  • [ ] Tag específica (nunca :latest em produção)
  • [ ] Multi-stage build para reduzir tamanho
  • [ ] Usuário não-root (USER nonroot)
  • [ ] Sem shell se possível
  • [ ] Sem ferramentas de debug em produção
  • [ ] COPY específico (não COPY . .)
  • [ ] Dependências pinadas com hashes

Image scanning no CI/CD

Integre scanning automático no pipeline para bloquear imagens vulneráveis:

# Exemplo: GitHub Actions com Trivy
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: '${{ env.IMAGE }}'
    format: 'sarif'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'  # Falha o build se encontrar critical/high

Assinatura e verificação de imagens

Use Sigstore/Cosign para assinar e verificar imagens:

# Assinar imagem
cosign sign --key cosign.key myregistry.io/myapp:v1.2.3

# Verificar antes de deploy (admission controller)
cosign verify --key cosign.pub myregistry.io/myapp:v1.2.3

Hardening do Cluster Kubernetes

API Server

  • Autenticação: Desabilite autenticação anonima (--anonymous-auth=false)
  • Autorização: Use RBAC, nunca AlwaysAllow
  • Audit logging: Habilite para rastrear todas as chamadas
  • TLS: Certificados válidos para todas as comunicações
  • Acesso: Não exponha API server publicamente

etcd

  • Encryption at rest: Criptografe secrets no etcd
  • TLS: Comunicação criptografada com API server
  • Acesso: Isole etcd da rede de pods
  • Backup: Backups criptografados regulares
# EncryptionConfiguration para secrets
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-key>
      - identity: {}

Kubelet

  • Autenticação: Webhook ou certificados (nunca anonimo)
  • Read-only port: Desabilite (--read-only-port=0)
  • Protect kernel defaults: --protect-kernel-defaults=true

RBAC e Controle de Acesso

RBAC (Role-Based Access Control) e fundamental para segurança em K8s. O princípio: mínimo privilégio.

Estrutura do RBAC

  • Role/ClusterRole: Define permissões (verbs em resources)
  • RoleBinding/ClusterRoleBinding: Liga roles a usuários/serviceaccounts
  • ServiceAccount: Identidade para pods
# Role restritivo para aplicação
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: myapp
  name: myapp-role
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["myapp-config"]  # Apenas configmap específico
  verbs: ["get"]
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["myapp-secret"]
  verbs: ["get"]
---
# ServiceAccount dedicada
apiVersion: v1
kind: ServiceAccount
metadata:
  name: myapp-sa
  namespace: myapp
automountServiceAccountToken: false  # Desabilitar se não precisar

RBAC anti-patterns

  • Usar cluster-admin para tudo
  • Wildcards em resources/verbs (*)
  • Bindings em namespace kube-system
  • Deixar serviceaccount default com permissões
  • Permitir escalate, bind, impersonate

Audit de RBAC

Use ferramentas para identificar permissões excessivas:

# kubectl-who-can: quem pode fazer o que
kubectl who-can create pods --all-namespaces
kubectl who-can get secrets -n production

# rbac-tool: visualizar e auditar
rbac-tool lookup --kind ServiceAccount
rbac-tool viz --outformat dot | dot -Tpng > rbac.png

Network Policies

Por padrão, todos os pods podem comunicar com todos. Network Policies implementam segmentação:

# Default deny all - ponto de partida
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# Permitir apenas tráfego necessário
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

Estratégia de implementação

  1. Comece em modo observação (log, não block)
  2. Mapeie fluxos de comunicação reais
  3. Implemente default-deny por namespace
  4. Adicione allowlists específicas
  5. Monitore e ajuste continuamente

CNI e Network Policies

Nem todo CNI suporta Network Policies. Verifique compatibilidade: Calico, Cilium e Weave suportam. Flannel não suporta nativamente. Cilium oferece L7 policies (HTTP, gRPC) além de L3/L4.

Runtime Security

Pod Security Standards (PSS)

Pod Security Standards substituiu PodSecurityPolicy (removido no K8s 1.25). Três níveis:

  • Privileged: Sem restrições (apenas para system pods)
  • Baseline: Previne escalação conhecida (mínimo para produção)
  • Restricted: Hardening máximo (recomendado)
# Aplicar PSS no namespace
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

SecurityContext no Pod

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:v1
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      resources:
        limits:
          memory: "256Mi"
          cpu: "500m"
        requests:
          memory: "128Mi"
          cpu: "100m"

Runtime detection com Falco

Falco detecta comportamentos anômalos em runtime usando regras baseadas em syscalls:

  • Shell spawned in container
  • File written to sensitive directory
  • Unexpected network connection
  • Container drift (arquivo criado que não estava na imagem)
  • Privilege escalation attempt

Gestão de Secrets

Kubernetes Secrets são base64 encoded, não criptografados por padrão. Melhores práticas:

Encryption at rest

Habilite criptografia de secrets no etcd (EncryptionConfiguration mostrado anteriormente).

External secret stores

Use secret managers externos com operadores:

# External Secrets Operator - sincroniza do AWS Secrets Manager
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-secret
  data:
    - secretKey: password
      remoteRef:
        key: production/database
        property: password

Melhores práticas de secrets

  • Monte como volume, não env var (evita logging acidental)
  • RBAC restritivo para acesso a secrets
  • Rotação automática com external stores
  • Audit logging de acesso a secrets
  • Nunca commite secrets em git (use sealed-secrets se necessário)

Ferramentas Essenciais de Segurança K8s

Trivy

Scanner de vulnerabilidades em imagens, IaC, filesystems. Open source da Aqua.

Scanning

Falco

Runtime security e detecção de anomalias baseada em syscalls.

Runtime

OPA/Gatekeeper

Policy engine para admission control. Enforce policies como código.

Policy

Cilium

CNI com eBPF, network policies L3-L7, observabilidade.

Network

Vault

Secret management com integração nativa K8s, rotação automática.

Secrets

Kube-bench

Verifica compliance com CIS Kubernetes Benchmark.

Compliance

Sigstore/Cosign

Assinatura e verificação de imagens e artefatos.

Supply Chain

Kubescape

Scanner de misconfiguration, NSA/MITRE frameworks.

Scanning

Perguntas Frequentes

Managed K8s (EKS, GKE, AKS) e mais seguro que self-managed?

Control plane gerenciado elimina responsabilidade de hardening de API server, etcd e kubelet master. Porém, segurança de workloads (pods, images, RBAC, network policies) continua sua responsabilidade. Managed facilita, mas não resolve tudo automaticamente.

Service mesh (Istio/Linkerd) e necessário para segurança?

Service mesh adiciona mTLS automático entre pods, authorization policies e observabilidade. E valioso para zero trust interno, mas adiciona complexidade significativa. Para muitos casos, Network Policies + RBAC adequado são suficientes. Avalie se a complexidade adicional justifica.

Como lidar com imagens de terceiros sem controle?

Mantenha registry interno e faça proxy/cache de imagens externas. Scan todas as imagens antes de permitir no cluster. Use admission controllers para bloquear imagens não verificadas. Para imagens críticas, considere rebuild com sua própria base image e verificação de supply chain.

Conclusão

Segurança em Kubernetes requer abordagem em camadas - não existe bala de prata. Da construção de imagens ao runtime, cada etapa oferece oportunidades de hardening e pontos de falha potenciais.

Comece pelo básico: imagens mínimas, RBAC restritivo, Network Policies com default-deny, Pod Security Standards restricted. Estas medidas eliminam a maioria dos vetores de ataque comuns. Depois, adicione camadas como runtime security (Falco), policy enforcement (OPA), e secret management externo (Vault).

Automatize verificações de segurança no pipeline CI/CD - scanning de imagens, compliance checks, assinatura. Segurança que depende de processo manual não escala e falha silenciosamente.

Por fim, trate segurança K8s como processo contínuo. O ecossistema evolui rapidamente, novas vulnerabilidades surgem, best practices mudam. Atualize clusters regularmente, acompanhe CVEs de componentes, e revise configurações periodicamente.

Precisa de Ajuda com Kubernetes Security?

Oferecemos assessment de segurança de clusters, implementação de hardening e integração de ferramentas de segurança em pipelines.

Falar com Especialista
Inteligência Brasil

Inteligência Brasil

Consultoria especializada em DevSecOps, Cloud Security e Segurança de Containers.