Preste Atenção em suas Notificações

Preste Atenção em suas Notificações


Três situações. A mesma infraestrutura. Três respostas diferentes. O mesmo problema: como monitorar sua cloud?

Há diversas maneiras e protocolos para se assegurar que tudo em sua cloud está rodando como você espera, mas o mais básico, e muitas vezes ignorado, são as notificações de alerta disparadas pela própria plataforma onde tudo está hospedado.

A OCI tem um conjunto de serviços que funcionam como um sistema nervoso para a sua tenancy quando configurados corretamente: o Monitoring mede, os Events observam ações e as Notifications avisam. Cada um tem o seu lugar nessa história. O Monitoring trabalha com métricas de recursos em tempo real. O Events reage a ações específicas na API da OCI, como a criação de usuários ou alteração de policies. As Notifications são o canal de entrega: email, Slack, PagerDuty, ou qualquer endpoint HTTPS.

Nenhum dos três resolve nada sozinho, mas conectados podem transformar um incidente silencioso num alerta que chega antes do problema virar uma emergência.

Vamos analisar três cenários, como configurá-los e como reagir depois de receber uma notificação.

 

Configuração inicial: o canal de notificações

Antes de apresentar os cenários, é preciso ajustar uma configuração comum aos três: um tópico no OCI Notifications e uma assinatura de email.

No OCI Notifications, um tópico funciona como uma central de distribuição de mensagens, apesar dele não enviar nada sozinho. O tópico recebe mensagens de várias fontes, seja um alarme do Monitoring ou uma regra do Events, e repassa para quem estiver inscrito no tópico. Funciona como uma lista de distribuição: qualquer mensagem que chega ao tópico vai para todos os assinantes cadastrados.

Uma assinatura define quem recebe e por qual canal. O OCI dá suporte a email, Slack, PagerDuty, SMS e endpoints HTTPS arbitrários. Para esse artigo, vamos focar em email, mas a mesma configuração funciona se você quiser adicionar um webhook depois: é só criar outra assinatura no mesmo tópico, sem mexer em nada que já existe.

# Criar o tópico
oci ons topic create \
  --compartment-id $COMPARTMENT_ID \
  --name "alertas-operacionais" \
  --description "Canal central de alertas"

# Guardar o topicId retornado
export TOPIC_ID=$(oci ons topic list \
  --compartment-id $COMPARTMENT_ID \
  --name "alertas-operacionais" \
  --query "data[0].\"topic-id\"" \
  --raw-output)

# Criar assinatura de email
oci ons subscription create \
  --compartment-id $COMPARTMENT_ID \
  --topic-id $TOPIC_ID \
  --protocol EMAIL \
  --subscription-endpoint "ops@suaempresa.com"

Depois de criar o tópico e a assinatura, você receberá um email de confirmação. Ao confirmar, as mensagens começam a chegar.

 

Cenário 1: bucket de produção com volume anormal de acessos

A situação

Um bucket no Object Storage armazena artefatos de build e assets estáticos usados pela aplicação em produção. No ambiente de testes, o mesmo bucket é acessível por todo o time. Na correria do dia a dia, é a solução mais simples.

Num fim de tarde qualquer, o volume de requisições ao bucket sobe de algumas centenas para dezenas de milhares por hora. Todo mundo já foi embora e no fim das contas, ninguém percebe o estrago, afinal, a aplicação não quebrou. O custo de egress começa a subir. Só no fim do mês vão perceber quando estranharem os valores da fatura.

O perigo

Bucket com acesso público exposto é um dos vetores mais comuns de vazamento de dados na nuvem. Um link compartilhado internamente, um objeto com uma URL pré-autenticada sem expiração, ou mesmo um bucket criado como público para um teste rápido e que nunca foi corrigido ou apagado. Quando o volume de acessos dispara, pode ser um scraper automatizado varrendo o conteúdo, um link que chegou a lugares errados, ou até mesmo uma ameaça mais séria.

Configurando o alarme

O OCI Monitoring captura métricas do Object Storage no namespace oci_objectstorage. A métrica GetRequests conta as leituras de objetos. Para filtrar especificamente o bucket de produção, é preciso incluir a dimensão bucketName na query. Sem ela, o alarme agrega requisições de todos os buckets do compartimento e um pico em qualquer um dos buckets vai disparar o alerta errado.

oci monitoring alarm create \
  --compartment-id $COMPARTMENT_ID \
  --display-name "bucket-acesso-anomalo" \
  --metric-compartment-id $COMPARTMENT_ID \
  --namespace "oci_objectstorage" \
  --query-string "GetRequests[5m]{bucketName=\"nome-do-bucket\"}.rate() > 500" \
  --severity "CRITICAL" \
  --destinations "[\"$TOPIC_ID\"]" \
  --is-enabled true \
  --pending-duration "PT5M" \
  --body "Volume anormal de leituras no bucket de producao. Verifique imediatamente."

O pending-duration de 5 minutos ajuda a evitar falsos positivos por picos momentâneos. O alarme só dispara se a condição se mantiver pelo prazo determinado, em nosso caso, cinco minutos.

Chegou um alerta! O que fazer primeiro.

Antes de qualquer investigação, o primeiro passo é averiguar se o bucket está público:

# Verificar configuração de acesso público
oci os bucket get \
  --bucket-name nome-do-bucket \
  --query "data.\"public-access-type\""

Se retornar ObjectRead ou ObjectReadWithoutList, o bucket está público. Corrigir o permissionamento do bucket deve ser prioridade:

oci os bucket update \
  --bucket-name nome-do-bucket \
  --public-access-type NoPublicAccess

Com o acesso bloqueado, hora de investigar a origem do tráfego. Para isso, o bucket precisa ter log de acessos habilitado. Se não tinha, habilite imediatamente e verifique o histórico via Audit:

# Habilitar logs de eventos no bucket
oci os bucket update \
  --bucket-name nome-do-bucket \
  --object-events-enabled true

# Consultar Audit para acessos recentes
oci audit event list \
  --compartment-id $COMPARTMENT_ID \
  --start-time "$(date -u -d '2 hours ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  | jq '[.data[] | 
        select(."event-type" | contains("objectstorage"))] | 
        group_by(."source-ip-address") | 
        map({ip: .[0]."source-ip-address", requests: length}) | 
        sort_by(-.requests)'

Esse comando agrupa os acessos por IP e ordena do mais para o menos frequente. Um IP único com milhares de requisições é um scraper. Centenas de IPs distintos pode ser tráfego legítimo que não era esperado, ou seja, algo pode ter sido exposto sem querer.

Proteção adicional

Se o bucket ainda precisa continuar acessível fora da rede local, uma das abordagens seria substituir o acesso público por URLs pré-autenticadas com expiração:

# Criar URL pré-autenticada com expiração de 24 horas
oci os preauth-request create \
  --bucket-name nome-do-bucket \
  --name "acesso-temporario-$(date +%Y%m%d)" \
  --access-type ObjectRead \
  --time-expires "$(date -u -d '+24 hours' +%Y-%m-%dT%H:%M:%SZ)" \
  --object-name "caminho/para/objeto.zip"

 

Cenário 2: novo usuário criado num horário suspeito

A situação

São 2h47 de um sábado. Um usuário novo é criado na tenancy. Nenhuma mudança estava planejada para o final de semana e nesse horário, dificilmente alguém da sua equipe vai estar trabalhando. Mesmo assim, não é possível dizer com certeza se foi algum colega de trabalho, um erro de automação, ou algo pior.

Configurando o Event

O OCI Events captura ações específicas na API da plataforma. Um evento de criação de usuário é uma das ações capturadas pela ferramenta, gerando o evento com.oraclecloud.identityControlPlane.CreateUser. Essa regra precisa ser criada no compartimento raiz da tenancy para capturar eventos globais de IAM.

oci events rule create \
  --compartment-id $TENANCY_ID \
  --display-name "novo-usuario-qualquer-horario" \
  --is-enabled true \
  --condition '{
    "eventType": [
      "com.oraclecloud.identityControlPlane.CreateUser"
    ]
  }' \
  --actions '{
    "actions": [{
      "actionType": "ONS",
      "topicId": "'$TOPIC_ID'",
      "isEnabled": true,
      "description": "Notificar equipe sobre novo usuario"
    }]
  }' \
  --description "Alerta imediato para qualquer criacao de usuario IAM"

O alerta chegará com o payload do evento, que inclui o nome do usuário criado, o OCID do usuário que executou a ação e o timestamp.

O alerta chegou. O que investigar antes de agir.

A primeira informação que importa é quem criou o usuário. O payload do evento tem essa informação, mas é possível confirmar via Audit:

# Identificar quem criou o usuário suspeito
oci audit event list \
  --compartment-id $TENANCY_ID \
  --start-time "2026-05-31T02:40:00Z" \
  --end-time "2026-05-31T02:55:00Z" \
  | jq '.data[] | 
    select(."event-type" == "com.oraclecloud.identityControlPlane.CreateUser") |
    {
      usuario_criado: .data."resourceName",
      criado_por: .data."additionalDetails"."principalName",
      ip_origem: ."source-ip-address",
      horario: ."event-time"
    }'

Antes de tomar qualquer medida, três detalhes podem ajudar nesse cenário:

Se for uma conta de serviço ou automação conhecida, pode ser um processo interno rodando fora do horário esperado

Um endereço interno de VPN corporativa é totalmente diferente de um IP desconhecido.

# Verificar grupos do usuário suspeito
oci iam user list-groups \
  --user-id $USUARIO_SUSPEITO_ID \
  --all \
  | jq '.data[] | {grupo: .name, id: .id}'

Usuários sem grupo não têm permissão nenhuma na OCI. Se já foram adicionados a um grupo com privilégios, o risco é imediato.

Conter sem deletar

Deletar o usuário de imediato destrói evidências e pode interromper um processo legítimo. O caminho correto é isolar o novo usuário enquanto investiga.

# Remover de todos os grupos (retira todas as permissões de acesso)
for GROUP_ID in $(oci iam user list-groups \
  --user-id $USUARIO_SUSPEITO_ID --all \
  | jq -r '.data[].id'); do
  oci iam group remove-user \
    --group-id $GROUP_ID \
    --user-id $USUARIO_SUSPEITO_ID
done

# Bloquear o usuário enquanto a investigação prossegue
oci iam user update \
  --user-id $USUARIO_SUSPEITO_ID \
  --blocked true

Com o usuário bloqueado e sem grupos, a investigação pode continuar sem pressa. Se for confirmado que era um usuário legítimo, você pode desbloqueá-lo com alguns poucos comandos e adicioná-lo aos grupos corretos. Agora, se for confirmado que o usuário é de fato suspeito, é possível deletá-lo e manter o histórico de auditoria preservado.

# Ao confirmar decisão: deletar o usuário
oci iam user delete \
  --user-id $USUARIO_SUSPEITO_ID

 

Cenário 3: Site recém lançado. Primeiro os erros, depois uma avalanche de tráfego

A situação

Um site foi para produção há duas semanas. Tráfego estável, nenhum problema. Na manhã de uma terça-feira, erros HTTP 5xx começam a aparecer. Minutos depois, o volume de conexões ativas no Load Balancer triplica. Qual seria a resposta imediata da equipe? Ataque! Mas será mesmo? Há outras leituras possíveis para a mesma situação, mas escolher a resposta errada pode transformar um incidente numa crise muito maior.

Para isso, precisamos entender a sequência dos dois alarmes, dependendo do que está acontecendo. Essa análise é uma das partes mais importantes do diagnóstico.

Configurando os dois alarmes

# Alarme 1: taxa de erros 5xx no Load Balancer
oci monitoring alarm create \
  --compartment-id $COMPARTMENT_ID \
  --display-name "site-erros-5xx" \
  --namespace "oci_lbaas" \
  --query-string "HttpResponses5xx[5m].rate() > 30" \
  --severity "CRITICAL" \
  --destinations "[\"$TOPIC_ID\"]" \
  --is-enabled true \
  --pending-duration "PT3M" \
  --body "Taxa de erros 5xx acima do normal. Pode indicar falha na aplicacao ou sobrecarga."

# Alarme 2: conexões ativas acima do normal
oci monitoring alarm create \
  --compartment-id $COMPARTMENT_ID \
  --display-name "site-trafego-incomum" \
  --namespace "oci_lbaas" \
  --query-string "ActiveConnections[5m].mean() > 400" \
  --severity "WARNING" \
  --destinations "[\"$TOPIC_ID\"]" \
  --is-enabled true \
  --pending-duration "PT5M" \
  --body "Volume de conexoes ativas acima do padrao historico."

Interpretando a sequência dos alertas

Erros primeiro, Tráfego depois: aplicação começou a falhar antes do tráfego aumentar. Neste caso, a situação pode sugerir uma falha interna: talvez um deploy com bug, esgotamento de conexões com banco ou até falta de recursos. O aumento de requisições pode ser tentativas automáticas de clientes legítimos.

Tráfego primeiro, erros depois: o volume chegou antes de qualquer falha. Isso quer dizer que a aplicação ficou sobrecarregada, seja por ataque, seja por audiência legítima.

Para termos certeza, precisamos analisar os dados de acesso.

# Verificar distribuição de IPs via Audit
# Muitos IPs únicos = audiência real
# Poucos IPs com volume muito alto = ataque ou scraping

oci audit event list \
  --compartment-id $COMPARTMENT_ID \
  --start-time "$(date -u -d '30 minutes ago' +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  | jq '[.data[] | ."source-ip-address"] | 
        group_by(.) | 
        map({ip: .[0], total: length}) | 
        sort_by(-.total) | .[:10]'

Centenas de IPs distintos, cada um com volume moderado: pode ser que um dos seus conteúdos tenha viralizado. Agora, três ou quatro IPs com dezenas de milhares de requisições, não precisa investigar mais: é ataque ou scraping agressivo.

Resposta para conteúdo viral: escalar

Se a análise aponta para audiência legítima, o problema é capacidade. Como o tráfego não era esperado, a instância compute por trás do Load Balancer precisa de mais recursos para atender essa demanda:

# Verificar shape atual da instância
oci compute instance get \
  --instance-id $INSTANCE_ID \
  --query "data.\"shape-config\""

# Atualizar para mais OCPUs e memória (sem reiniciar, se o shape permitir)
oci compute instance update \
  --instance-id $INSTANCE_ID \
  --shape-config '{"ocpus": 4, "memoryInGBs": 32}'

Se a arquitetura usa um Load Balancer com múltiplos backends, você pode adicionar a instância existente num backend set maior ou subir uma segunda instância e registrá-la:

# Adicionar backend ao Load Balancer existente
oci lb backend create \
  --load-balancer-id $LB_ID \
  --backend-set-name "backend-principal" \
  --ip-address $NOVA_INSTANCIA_IP \
  --port 80 \
  --weight 1

Resposta para ataque: bloquear na borda

Se o tráfego vem de poucos IPs com volume desproporcional, o bloqueio mais rápido é no nível do sistema operacional. Security Lists na OCI funcionam com permissões explícitas e não têm sintaxe de deny por IP específico, por isso a melhor resposta durante um incidente como esse é via iptables na própria instância:

# Bloquear o IP agressor na instância
sudo iptables -A INPUT -s $IP_AGRESSOR -j DROP

# Persistir a regra entre reboots (Ubuntu/Debian)
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Se o ambiente usa WAF, adicionar uma regra de bloqueio é melhor ainda: a filtragem acontece antes do tráfego chegar à instância, mas se não for esse o caso, o bom e velho iptables resolve sem tempo de propagação e dá conta do recado.

 

O que os três cenários têm em comum

Cenário Fonte do sinal Serviço Resposta
Bucket com acessos anômalos Métrica GetRequests OCI Monitoring Bloquear acesso público, auditar origem
Usuário criado fora do horário Evento IAM OCI Events Isolar, investigar, decidir
Site sobrecarregado Métricas do Load Balancer OCI Monitoring Diagnosticar, escalar ou bloquear

Você só vai precisar configurar Notifications e tópicos uma vez e os alarmes e regras de eventos podem ser adicionados conforme a operação cresce. Na verdade, você não precisa - e nem deve - monitorar tudo desde o início. O mais importante é começar pelos recursos que já estão em produção e têm histórico de comportamento conhecido, porque qualquer desvio nesses recursos vai fazer sentido imediato quando um alerta chegar.

Calibrar bem o pending-duration e as dimensões dos alarmes é o que separa um sistema que notifica do que só faz barulho. Uma notificação que ninguém abre tem o mesmo efeito de não ter configurado nada.

Leia mais

← Todos os artigos
editar