Erik-Jan de Kruijf

Detecção de sondagem e fuzzing em servidores web no Traefik com resposta automatizada do Cloudflare

Este artigo mostra como uma regra de detecção personalizada do Elastic Security ES|QL pode identificar atividades de sondagem e fuzzing em servidores web nos logs do Traefik e bloquear automaticamente o IP atacante por meio do Cloudflare.

8 min de leituraHabilitação

Introdução

Serviços auto-hospedados expostos por meio de um proxy reverso inevitavelmente atraem scanners automatizados que buscam configurações incorretas, painéis de administração e endpoints vulneráveis. Neste artigo, mostro como transformar os logs de acesso rotineiros do Traefik em um controle defensivo ativo usando o Elastic Security e o Cloudflare.

Utilizo uma regra de detecção ES|QL pronta para uso para identificar o comportamento de descoberta e fuzzing do servidor web. Quando padrões de sondagem suspeitos são detectados, um fluxo de trabalho automatizado bloqueia imediatamente o endereço IP de origem infrator na borda da rede por meio da API do Cloudflare. A melhor parte dessa configuração é que ela se adapta facilmente a diferentes tamanhos. Ao construir essa infraestrutura de resposta uma única vez para detecção de fuzzing, posso anexar exatamente a mesma ação de bloqueio a qualquer outra regra do Elasticsearch, como aquelas que detectam injeções de SQL ou tentativas de inclusão de arquivos. Isso transforma um sistema básico de registro de dados em uma defesa perimetral altamente adaptável.

Contexto e panorama de ameaças

Meu ambiente de laboratório doméstico utiliza o Proxmox VE para contêineres e máquinas virtuais. Eu uso um proxy reverso Traefik, protegido com Authelia para autenticação, para permitir acesso externo sem VPN. O Cloudflare, com o proxy ativado, gerencia o DNS.

Para quem está menos familiarizado com essa pilha de tecnologias específica, o Traefik funciona como a porta de entrada da rede. Quando uma solicitação web chega via Cloudflare, o Traefik roteia o tráfego dinamicamente para o contêiner interno correto, gerenciando os certificados SSL para manter as conexões criptografadas. No entanto, antes que qualquer tráfego chegue efetivamente a esses aplicativos de back-end, ele é interceptado pelo Authelia. Ao aproveitar o recurso de autenticação direta do Traefik, o Authelia impõe o Single Sign-On e a Autenticação Multifator em todos os aspectos. Isso significa que scanners automatizados e invasores não conseguem sequer acessar as telas de login dos meus serviços internos sem passar por esse portal seguro inicial.

Para manter a visibilidade e a segurança, eu ingiro esses logs de acesso do Traefik no Elasticsearch usando a integração oficial. Durante o monitoramento de rotina, observei inúmeros códigos de resposta HTTP 404 originados dos mesmos endereços IP de origem nesses registros.

Esse padrão sugere uma possível sondagem ou teste de tráfego por parte do servidor web, visando vulnerabilidades em aplicações que não estão efetivamente em uso na minha rede. Exemplos desses caminhos direcionados incluem /wp-includes/mani., /wp-content/plugins/all-in-one-wp-security-and-firewall/templates.php, /archive.php e /wp-admin/includes/header.php.

Filosofia de design: por que não Fail2Ban?

Uma dúvida comum na comunidade de laboratórios domésticos é por que não usar ferramentas locais como Fail2Ban ou CrowdSec diretamente no servidor Traefik. Embora essas sejam excelentes ferramentas, orquestrar a resposta por meio do Elastic Security e transferir o bloqueio para o Cloudflare oferece duas grandes vantagens. Ao bloquear o tráfego malicioso na borda da rede Cloudflare, economiza-se largura de banda local e mantém os scanners completamente fora da rede doméstica. Além disso, orquestrar a resposta por meio do Elastic nos proporciona uma visão unificada de todo o monitoramento de segurança.

Estratégia de detecção e estratégia de implementação

Para identificar eficazmente tentativas de reconhecimento malicioso, nossa estratégia se baseia na análise da frequência dos códigos de resposta HTTP no nível do proxy. Especificamente, estamos procurando por um alto volume de erros 404 (Não encontrado) gerados por um único endereço IP de origem em um curto período de tempo, um indicador clássico de fuzzing de diretório ou varredura de vulnerabilidades.

Embora o Elastic Security forneça regras de detecção robustas e prontas para uso exatamente para esse cenário, essas regras exigem dados ECS (Elastic Common Schema) devidamente normalizados para funcionar corretamente. Detectar e mitigar essas varreduras requer, portanto, um fluxo coordenado. Para que isso funcione, precisamos ingerir os logs do Traefik, preencher o campo host.name ausente usando um pipeline personalizado e direcionar a regra de detecção para nossos dados.

Lógica de limiar e ajuste

Nossa estratégia de detecção se afasta da simples correspondência de strings, baseando-se, em vez disso, em limiares estatísticos. A regra monitora especificamente recursos negados ou inexistentes representados pelos códigos de resposta HTTP 403 e 404 e agrega essa atividade pelo IP de origem.

Esse comportamento é regido pela instrução final where na consulta. Por padrão, um alerta só é acionado se um IP de origem produzir mais de 500 erros em 250 caminhos URI distintos durante a janela de pesquisa. Este limiar de dupla camada foi projetado para eliminar falsos positivos, garantindo que um único recurso corrompido não acione um bloqueio, ao mesmo tempo que identifica scripts automatizados que percorrem listas de palavras de diretórios.

Em ambientes de laboratório doméstico menores ou com equipes reduzidas, essas configurações padrão costumam ser muito permissivas. Como o tráfego externo legítimo não tem motivo para acessar painéis de administração inexistentes na minha rede, ajustei a sensibilidade para detectar tentativas de reconhecimento mais furtivas logo no início. Modifiquei a lógica para ser acionada quando event_count > 100 e url_original_count_distinct > 50.

Para ambientes de produção onde os aplicativos naturalmente geram volumes de erros mais altos, você pode considerar aumentar esses valores ou adicionar uma cláusula ES|QL where not para excluir links quebrados conhecidos. Finalmente, uso um filtro where source.ip not in (...) para garantir que ferramentas de segurança autorizadas ou scanners de vulnerabilidade pessoais não sejam banidos acidentalmente pelo fluxo de trabalho automatizado.

Ingestão de logs de acesso do Traefik

Para integrar os logs de acesso do Traefik ao cluster, utilizei a integração padrão do Traefik. O Elastic Agent coleta registros dos servidores Traefik. Esta integração grava os logs ingeridos no fluxo de dados logs-traefik.access-default .

Construindo um pipeline de ingestão personalizado

O campo host.name é crucial para a regra de detecção que estou usando, mas a integração padrão do Traefik não o preenche. Portanto, é necessário um pipeline de ingestão personalizado para adicionar esse campo. Como a integração do Traefik utiliza um fluxo de arquivo no servidor Traefik, posso copiar o valor do campo agent.name existente para preencher host.name.

Eu uso especificamente o pipeline logs-traefik.access@custom em vez de modificar o principal. As integrações elásticas são projetadas para detectar e executar automaticamente esses pipelines @custom logo no final de seu fluxo de processamento. Mais importante ainda, os pipelines padrão são completamente sobrescritos sempre que atualizo uma integração. Ao armazenar minha lógica no pipeline personalizado, garanto que meus mapeamentos de campo sejam mantidos após a próxima atualização. A chamada de API necessária para criar esse pipeline pode ser executada no console das Ferramentas de Desenvolvedor:

PUT _ingest/pipeline/logs-traefik.access@custom
{
  "description": "copy the agent.name field to the host.name field",
  "processors": [
    {
      "set": {
        "field": "host.name",
        "value": "{{{agent.name}}}",
        "override": false,
        "ignore_empty_value": true,
        "ignore_failure": true
      }
    }
  ]
}

Resposta automatizada por meio do fluxo de trabalho do Cloudflare

Para passar da detecção à defesa ativa, implementamos um fluxo de trabalho que preenche a lacuna entre nossos alertas do Elasticsearch e a borda da Cloudflare. A lógica foi projetada para ser eficiente: em vez de criar uma nova regra de firewall para cada alerta, o que rapidamente atingiria os limites de regras do Cloudflare, o fluxo de trabalho primeiro recupera a lista de bloqueio existente. Em seguida, adiciona dinamicamente o novo endereço IP de origem da ofensa à lista antes de enviar a atualização de volta para a API do Cloudflare. Assim que a segurança da borda estiver garantida, o fluxo de trabalho termina com o reconhecimento do alerta no Elastic, fechando efetivamente o ciclo do incidente.

Pré-requisitos e escopo do token

Esse processo requer tanto uma chave de API quanto o ID da zona para a configuração do Cloudflare. O token da API deve possuir privilégios de "edição do WAF de zona" para permitir a criação da regra. Ao gerar este token no painel do Cloudflare, use a opção "Criar token personalizado" e defina as permissões estritamente para Zone -> Zone WAF -> Edit.

Após a configuração do fluxo de trabalho, ele deve ser atribuído como uma ação à regra de detecção "Descoberta de Servidor Web ou Atividade de Fuzzing".

Com os pré-requisitos definidos, vamos analisar passo a passo como construir o fluxo de trabalho.

Configuração e gatilhos do fluxo de trabalho

Primeiro, definimos os metadados básicos. Este fluxo de trabalho bloqueia os endereços IP encontrados nos alertas de Descoberta de Servidor Web ou Atividade de Fuzzing. O fluxo de trabalho está habilitado e tem um tempo limite de 30 segundos para a solicitação da API. Neste caso, ele é baseado em um alerta, portanto, é executado automaticamente quando um alerta de segurança é acionado.

# =========================================================================
# Workflow: Block IP at Cloudflare test
# Category: security/response
# =========================================================================
version: '1'
name: Block IP at Cloudflare
enabled: true

triggers:
  - type: alert

Constantes e autenticação

Esta seção contém as variáveis para autenticação. Lembre-se de substituir as strings de espaço reservado pelo seu token de API e ID da zona reais.

consts:
  cloudflare_api: "<cloudflare API>"
  cloudflare_zone: "<cloudflare ZONE>"

Passo 1: Recuperando a lista de bloqueio atual

A sequência verifica se a regra do firewall já existe. O fluxo de trabalho faz uma solicitação HTTP GET para recuperar a regra de bloqueio de IP existente.

steps:
  - name: cloudflare_current_block
    type: http
    with:
      url: "https://api.cloudflare.com/client/v4/zones/{{consts.cloudflare_zone}}/rulesets/phases/http_request_firewall_custom/entrypoint"
      headers:
        Authorization: Bearer {{consts.cloudflare_api}}
      method: GET
    on-failure:
      continue: true

Etapa 2: Atualizando ou criando a regra do firewall

Se a regra já existir, o endereço IP será adicionado a ela; caso contrário, a regra será criada. O fluxo de trabalho identifica se a descrição "bloco de varredura do servidor web" está presente. Nesse caso, o novo endereço IP é adicionado à lista atual de endereços IP bloqueados por meio de uma solicitação PUT. Caso contrário, o sistema recorre à criação de uma nova regra.

 - name: cloudflare_block
    type: if
    condition: 'steps.cloudflare_current_block.output.data.result.rules[0].description == "webserver scanning block"'
    steps:
      - name: ip-block-cloudflare_add
        type: http
        with:
          url: "https://api.cloudflare.com/client/v4/zones/{{consts.cloudflare_zone}}/rulesets/phases/http_request_firewall_custom/entrypoint"
          method: PUT
          headers:
            Authorization: Bearer {{consts.cloudflare_api}}
          timeout: 30s
          body: '{ "rules": [ { "description": "webserver scanning block", "expression": "{{steps.cloudflare_current_block.output.data.result.rules[0].expression}} or (ip.src eq {{event.alerts[0].source.ip}})", "action": "block" } ]}'
    else:
      - name: ip-block-cloudflare_new
        type: http
        with:
          url: "https://api.cloudflare.com/client/v4/zones/{{consts.cloudflare_zone}}/rulesets/phases/http_request_firewall_custom/entrypoint"
          method: PUT
          headers:
            Authorization: Bearer {{consts.cloudflare_api}}
          timeout: 30s
          body: '{ "rules":[ { "description": "webserver scanning block", "expression": "(ip.src eq {{event.alerts[0].source.ip}})", "action": "block" } ]}'
    on-failure:
      continue: true

Etapa 3: Confirmar o alerta

Em seguida, o alerta é reconhecido. Esta etapa usa a ação kibana.SetAlertsStatus para fechar automaticamente o alerta no Elastic Security.

  - name: update_alert_status
    type: kibana.SetAlertsStatus
    with:
      status: "acknowledged"
      signal_ids: ["{{event.alerts[0]._id}}"]

Etapa 4: Vincular o fluxo de trabalho à regra

Com o fluxo de trabalho totalmente construído, a etapa final é vinculá-lo à regra de detecção para que seja acionado automaticamente. Nas configurações da regra do Elastic Security para a regra "Descoberta de servidor web ou atividade de fuzzing", eu navego até a guia Ações da regra e adiciono uma nova ação. Na lista suspensa de conectores, basta selecionar o fluxo de trabalho do Cloudflare que acabei de criar.

Nota sobre os limites do WAF

Como este fluxo de trabalho concatena endereços IP usando uma declaração or (or (ip.src eq <IP>)), lembre-se de que a Cloudflare tem um limite de caracteres para expressões WAF personalizadas (normalmente 4096 caracteres nos níveis padrão). Em ambientes altamente segmentados, essa string pode eventualmente atingir o limite. Para laboratórios domésticos e pequenas equipes, limpar ocasionalmente essa regra do WAF manualmente serve como uma reinicialização saudável.

Testes e Validação

Para verificar se o pipeline está funcionando de ponta a ponta, podemos gerar algum ruído com uma ferramenta de fuzzing padrão. Você pode simular um ataque de varredura contra seu próprio laboratório doméstico usando uma ferramenta de fuzzing como ffuf ou gobuster.

Execute uma verificação rápida em um diretório inexistente no seu domínio Traefik público:

ffuf -u https://your-domain.com/FUZZ -w /path/to/wordlist.txt

Assim que a simulação estiver em execução, podemos observar a cadeia de defesa automatizada em ação. Os erros 404 aparecem quase imediatamente no fluxo de dados logs-traefik.access-default . Dentro do intervalo de consulta, a regra ES|QL identifica o padrão e gera um novo alerta na página de Alertas de Segurança do Elastic. A partir daí, o fluxo de trabalho entra em ação: ele altera o status do alerta para "confirmado" e envia o bloqueio de IP para nossa regra do WAF da Cloudflare, neutralizando efetivamente o scanner na borda antes que ele possa continuar seu reconhecimento.

Você pode confirmar se o bloqueio foi bem-sucedido verificando seu painel do Cloudflare em Security -> WAF -> Custom rules. (Observação: certifique-se de remover seu IP da regra do Cloudflare posteriormente para não se bloquear!)

Ampliar a defesa

A grande vantagem dessa configuração é que nosso fluxo de trabalho com o Cloudflare não se limita apenas à detecção por fuzzing. Uma vez que a automação esteja criada, podemos associá-la a qualquer regra do Elasticsearch que sinalize tráfego suspeito de proxy. Por exemplo, podemos vincular essa mesma ação de resposta a regras prontas para uso que visam vulnerabilidades específicas de aplicativos, como Atividade de Inclusão de Arquivo Local do Servidor Web e Atividade Potencial de Inclusão de Arquivo Remoto do Servidor Web , para derrubar o invasor imediatamente. Ele também se integra perfeitamente com o recurso "Potential Spike in Web Server Error Logs" e "Unusual Web User Agent" para detectar scrapers mal configurados e ruídos de rede mais amplos. Instalamos a rede hidráulica uma vez, e de repente todo o perímetro fica mais inteligente.

Conclusão

Integrar o Traefik e o Cloudflare ao Elastic Security é uma ótima maneira de transformar registros de acesso básicos em uma defesa ativa. Os ambientes de laboratório doméstico são constantemente bombardeados por scanners automatizados em busca de vulnerabilidades fáceis de explorar. Esse fluxo de trabalho automatizado não apenas bloqueia os atacantes na borda da rede, mas também reduz a sobrecarga de alertas, reconhecendo os incidentes automaticamente. Este é um exemplo prático de como a orquestração e resposta de segurança podem economizar tempo e, ao mesmo tempo, melhorar significativamente sua postura de segurança.

Compartilhe este artigo