Saltar para o conteúdo principal
Versão 3.0

Segurança - Apache Ozone

ChartVersion3.0.1TypeapplicationAppVersion2.0.0
CompatibilidadeKubernetes1.32+OpenShift4.19+Rancher2.10.x+
Padrões gerais de segurança

Para conceitos transversais a todos os componentes TDP — como gerenciamento de Secrets, rotação de credenciais, NetworkPolicy, rate limiting e auditoria — consulte Segurança — Padrões Gerais.

Visão geral

O S3 Gateway do Apache Ozone no TDP usa autenticação AWS Signature Version 4 em modo simples, sem Kerberos. Nesse modo, os clientes assinam cada requisição com um access key e um secret key, e o chart injeta as credenciais no S3 Gateway por meio de Secret Kubernetes.

A segurança efetiva combina quatro controles: credenciais por aplicação ou usuário técnico, TLS quando houver tráfego fora do cluster, restrição de rede com NetworkPolicy ou controles equivalentes e auditoria operacional por logs.

Arquitetura de segurança

┌─────────────────────────┐
│ Cliente │
│ (AWS CLI / SDK / Spark)│
└──────────┬──────────────┘
│ AWS Signature v4
│ (Access Key + Secret Key)

┌──────────────────────────┐
│ S3 Gateway (porta 9878) │
│ - Valida assinatura │
│ - Verifica credenciais │
└──────────┬───────────────┘


┌──────────────────────────┐
│ Ozone Manager │
│ (Autorização) │
└──────────────────────────┘

AWS Signature v4 sem Kerberos

Níveis de segurança disponíveis

NívelDescriçãoUso recomendado
NoneSem autenticaçãoDesenvolvimento isolado apenas
SimpleAWS Signature v4 sem KerberosProdução (recomendado)
KerberosSegurança Ozone completaAmbientes enterprise com Kerberos existente

Configuração no values.yaml

ozone:
s3g:
auth:
enabled: true
type: simple
secretName: ozone-s3-credentials
env:
- name: OZONE-SITE.XML_ozone.s3g.authentication
value: "simple"
- name: OZONE-SITE.XML_ozone.security.enabled
value: "false"
- name: OZONE-SITE.XML_ozone.s3g.secret.http.enabled
value: "false"
ParâmetroDescriçãoPadrão
ozone.s3g.auth.enabledHabilita autenticação S3 no S3 Gatewaytrue
ozone.s3g.auth.secretNameSecret com as chaves aws_access_key_id e aws_secret_access_keyozone-s3-credentials

Com autenticação habilitada, clientes como AWS CLI, SDKs, Spark S3A e Trino precisam usar a mesma região, endpoint e credenciais esperadas pelo S3 Gateway. Use us-east-1 como região padrão quando não houver outra convenção no ambiente.

Desenvolvimento apenas

Use ozone.s3g.auth.enabled: false somente em ambientes de desenvolvimento ou laboratório isolado. Em ambientes compartilhados ou produtivos, mantenha autenticação habilitada e proteja o endpoint S3 REST com TLS e controle de rede.

Modelo de credenciais

Crie credenciais separadas por aplicação, pipeline ou usuário técnico sempre que possível. Evite compartilhar a mesma credencial entre consumidores com perfis de acesso diferentes.

Terminal input
kubectl -n <NAMESPACE> create secret generic ozone-s3-credentials \
--from-literal=aws_access_key_id="<AWS_ACCESS_KEY_ID>" \
--from-literal=aws_secret_access_key="<AWS_SECRET_ACCESS_KEY>"

O Secret deve existir no namespace em que o Ozone é instalado e deve ser referenciado pelo valor ozone.s3g.auth.secretName:

ozone:
s3g:
auth:
enabled: true
secretName: ozone-s3-credentials

Não versionar credenciais reais em repositórios Git, arquivos de valores, notebooks ou DAGs. Distribua credenciais para os consumidores por Secrets Kubernetes, variáveis de ambiente gerenciadas ou mecanismos equivalentes do componente.

Gerenciamento de usuários S3

Quando o ambiente usa credenciais separadas por pessoa, aplicação ou serviço técnico, padronize um fluxo operacional para criar, listar e remover usuários S3.

Criação via script

O script scripts/generate-s3-credentials.sh fica dentro do chart tdp-ozone. Para usá-lo, execute o comando a partir da raiz do chart, ou ajuste o caminho para o local onde o chart foi extraído. O utilitário gera pares de access key e secret key e os registra como Secrets Kubernetes:

Terminal input
NAMESPACE=<NAMESPACE> ./scripts/generate-s3-credentials.sh create <APPLICATION_NAME>

Saída esperada:

AWS_ACCESS_KEY_ID=a1b2c3d4e5f6g7h8i9j0
AWS_SECRET_ACCESS_KEY=aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890ABCD

Criação manual

Se preferir criar as credenciais manualmente sem o script:

Terminal input
ACCESS_KEY=$(openssl rand -hex 10)
SECRET_KEY=$(openssl rand -base64 32)

kubectl create secret generic ozone-s3-credentials-<APPLICATION_NAME> \
--from-literal=aws_access_key_id="$ACCESS_KEY" \
--from-literal=aws_secret_access_key="$SECRET_KEY" \
-n <NAMESPACE>

Após criar o Secret, registre o accessId no Ozone Manager para associá-lo a um usuário do tenant — sem este passo, as credenciais existem no Kubernetes mas não são reconhecidas pelo S3 Gateway:

Terminal input
kubectl exec -n <NAMESPACE> <RELEASE_NAME>-om-0 -- \
ozone sh tenant assignusertoaccessid \
--accessid="$ACCESS_KEY" --tenant-id=default --user-principal=<APPLICATION_NAME>

Listagem

Terminal input
./scripts/generate-s3-credentials.sh list

Para listar os Secrets do S3 Gateway diretamente no cluster:

Terminal input
kubectl get secrets -n <NAMESPACE> -l app.kubernetes.io/component=s3g

Remoção

Terminal input
./scripts/generate-s3-credentials.sh delete <APPLICATION_NAME>

Para auditoria operacional, mantenha registro de qual Secret Kubernetes distribui cada credencial e quais workloads consomem esse Secret.

Controle de acesso (ACLs)

O Ozone oferece ACLs em nível de volume e bucket. Use o CLI ozone sh para definir e consultar permissões:

Terminal input
# Definir ACL de bucket (alice com leitura/escrita, bob somente leitura)
kubectl exec -n <NAMESPACE> <RELEASE_NAME>-om-0 -- \
ozone sh bucket setacl \
--acl user:alice:rw,user:bob:r \
/volume1/bucket1
Terminal input
# Consultar ACLs de um bucket
kubectl exec -n <NAMESPACE> <RELEASE_NAME>-om-0 -- \
ozone sh bucket getacl /volume1/bucket1

Rotação e revogação

Para rotacionar credenciais, atualize ou recrie o Secret e reinicie os pods que consomem essas variáveis ou arquivos. Isso inclui o S3 Gateway e os clientes que mantêm credenciais em memória.

Terminal input
kubectl -n <NAMESPACE> rollout restart statefulset/<RELEASE_NAME>-s3g

A revogação prática em modo simples é operacional: remover ou trocar Secrets dos namespaces consumidores, reiniciar workloads e bloquear caminhos de rede quando necessário.

LDAP/AD sem Kerberos

LDAP ou Active Directory podem ser usados como referência de ciclo de vida e nomenclatura de contas, por exemplo para padronizar usuários técnicos.

Limitação importante

Com ozone.security.enabled=false (sem Kerberos), desabilitar uma conta no LDAP/AD não revoga automaticamente credenciais S3 já distribuídas. As chaves S3 são credenciais de cliente que você distribui — a revogação é responsabilidade operacional.

Processo recomendado para gestão de ciclo de vida com LDAP/AD:

  1. Mantenha um identificador estável por conta (ex.: uid do LDAP ou sAMAccountName do AD).
  2. Para cada conta LDAP, gere um par de chaves S3 e armazene como Kubernetes Secret.
  3. Injete o Secret nos workloads que precisam de acesso (env vars ou arquivos montados).
  4. Quando uma conta for desativada no LDAP, remova o Secret Kubernetes correspondente de todos os namespaces e reimplante os workloads.
  5. Rotacione chaves periodicamente ou imediatamente após comprometimento.

Controles compensatórios recomendados:

  • Restrinja o acesso ao endpoint S3 com NetworkPolicy ou security groups
  • Use TLS para o tráfego S3
  • Crie service accounts separados (chaves distintas) por aplicação
  • Habilite audit logging no Ozone

TLS e exposição do S3 REST

Use TLS para qualquer acesso ao S3 Gateway REST fora do cluster ou em redes compartilhadas. O TLS normalmente é terminado no Ingress Controller ou no Gateway configurado para o hostname https://<OZONE_S3_REST_HOSTNAME>.

tdp-ozone:
ingress:
s3g:
rest:
enabled: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: <OZONE_S3_REST_HOSTNAME>
paths:
- path: /
pathType: Prefix
tls:
- secretName: ozone-s3-rest-tls
hosts:
- <OZONE_S3_REST_HOSTNAME>

Exponha OM, SCM e S3 Web UI apenas para redes administrativas. O S3 Gateway REST é plano de dados e exige atenção adicional a TLS, autenticação S3, DNS e políticas de rede.

Rate limiting

Para proteger o endpoint S3 REST contra uso abusivo, configure limites de requisição no Ingress Controller NGINX:

tdp-ozone:
ingress:
s3g:
rest:
annotations:
nginx.ingress.kubernetes.io/limit-rps: "100"
nginx.ingress.kubernetes.io/limit-connections: "10"

NetworkPolicy e segurança de rede

Restrinja quem pode alcançar o Service <RELEASE_NAME>-s3g-rest na porta 9878. Em clusters com NetworkPolicy, permita somente namespaces e ServiceAccounts dos consumidores autorizados, como Spark, Trino, Hive Metastore, Airflow, NiFi ou Jupyter quando aplicável.

Também revise exposição externa: se todos os consumidores estão dentro do cluster, prefira Service interno em vez de Ingress para o S3 REST.

Auditoria e logs

Habilite o audit logging no values.yaml:

ozone:
s3g:
env:
- name: OZONE-SITE.XML_ozone.audit.enabled
value: "true"
- name: OZONE-SITE.XML_ozone.audit.log.file
value: "/var/log/ozone/s3-audit.log"

Para consultar entradas de auditoria nos logs do S3 Gateway:

Terminal input
kubectl logs -n <NAMESPACE> statefulset/<RELEASE_NAME>-s3g | grep AUDIT

Use logs do S3 Gateway e dos consumidores para investigar acessos, falhas de assinatura e erros de autorização. Quando o audit logging estiver habilitado, direcione esses logs para a solução de observabilidade adotada pelo TDP.

Checklist de produção

Antes de expor o S3 Gateway REST para usuários ou integrações fora do cluster, valide:

  • Credenciais padrão substituídas por credenciais próprias do ambiente
  • TLS habilitado para o hostname público do S3 REST
  • Anotação cert-manager ou certificado provisionado manualmente
  • Política de rotação definida para credenciais S3
  • Procedimento de revogação e recuperação de credenciais documentado
  • NetworkPolicy, regras de firewall ou controles equivalentes restringindo o acesso ao endpoint
  • Rate limiting configurado no Ingress (se exposto externamente)
  • Audit logging habilitado e logs direcionados para observabilidade
  • Teste de criação, leitura, gravação e remoção de objetos com as credenciais finais

Migração de acesso aberto para autenticado

Se o ambiente está migrando de uma instalação sem autenticação (auth.enabled: false) para autenticação habilitada:

  1. Crie as credenciais antes de habilitar a autenticação:

    Terminal input
    NAMESPACE=<NAMESPACE> ./scripts/generate-s3-credentials.sh create <APPLICATION_NAME>
  2. Atualize o values.yaml habilitando ozone.s3g.auth.enabled: true e referenciando o Secret criado.

  3. Aplique a atualização do chart:

    Terminal input
    helm upgrade <RELEASE_NAME> oci://registry.tecnisys.com.br/tdp/charts/tdp-ozone \
    --namespace <NAMESPACE> \
    -f values.yaml
  4. Atualize todos os consumidores (Spark, Trino, Airflow, etc.) com as novas credenciais antes ou imediatamente após o upgrade.

  5. Verifique que todas as aplicações estão operando com as novas credenciais antes de remover o acesso aberto.

Teste de acesso

Verifique a autenticação com e sem credenciais:

Terminal input
# Sem credenciais — deve retornar erro de autenticação
curl http://<RELEASE_NAME>-s3g-rest.<NAMESPACE>.svc.cluster.local:9878/
Terminal input
# Com credenciais — deve retornar lista de buckets
aws configure set aws_access_key_id <AWS_ACCESS_KEY_ID>
aws configure set aws_secret_access_key <AWS_SECRET_ACCESS_KEY>
aws configure set region us-east-1
aws s3 ls --endpoint-url=http://<RELEASE_NAME>-s3g-rest.<NAMESPACE>.svc.cluster.local:9878

Solução de problemas

SignatureDoesNotMatch

  1. Verifique que as credenciais no Secret estão corretas:

    Terminal input
    kubectl get secret ozone-s3-credentials-<APPLICATION_NAME> -n <NAMESPACE> -o jsonpath='{.data}'
  2. Confirme que o relógio do nó está sincronizado (AWS Signature v4 é sensível a desvio de tempo).

  3. Verifique que o endpoint usado pelo cliente é exatamente o mesmo usado na assinatura.

  4. Confirme que a região está configurada como us-east-1.

Credenciais não reconhecidas (AccessDenied ou 403)

Terminal input
./scripts/generate-s3-credentials.sh create <APPLICATION_NAME>

Reinicie os pods consumidores após recriar o Secret.

Conexão recusada

  1. Verifique se o Ingress está configurado corretamente.

  2. Teste resolução DNS interna:

    Terminal input
    kubectl exec -it <POD_NAME> -n <NAMESPACE> -- nslookup <RELEASE_NAME>-s3g-rest.<NAMESPACE>.svc.cluster.local
  3. Teste via port-forward:

    Terminal input
    kubectl port-forward -n <NAMESPACE> svc/<RELEASE_NAME>-s3g-rest 9878:9878
    aws s3 ls --endpoint-url=http://localhost:9878

AccessDenied com credencial válida

Verifique ACLs do volume ou bucket:

Terminal input
kubectl exec -n <NAMESPACE> <RELEASE_NAME>-om-0 -- \
ozone sh bucket getacl /<VOLUME_NAME>/<S3_BUCKET>

Ajuste permissões conforme necessário com ozone sh bucket setacl.

SintomaCausa provávelCorreção
SignatureDoesNotMatchCredencial incorreta, endpoint divergente, região errada ou clock driftConfira Secret, URL exata, região us-east-1 e sincronização de horário
AccessDenied ou 403Credenciais não reconhecidas ou política do cliente inconsistenteValide o Secret e reinicie pods consumidores
AccessDenied com credencial válidaACL de volume ou bucket não permite a operaçãoVerifique ACLs com ozone sh bucket getacl
Cliente conecta por HTTP mas falha por HTTPSCertificado, CA ou truststore ausente no consumidorConfigure CA/truststore e use o mesmo esquema da URL publicada
Funciona via port-forward, falha via IngressDNS, TLS, IngressClass ou regra de rota incorretaVerifique hostname, certificado, Ingress e logs do controller
Consumidor interno não alcança o endpointNetworkPolicy ou namespace bloqueando tráfegoLibere o tráfego necessário para <RELEASE_NAME>-s3g-rest:9878

Referências