WAF (ModSecurity)

Monitore eventos de WAF, analise ataques, ajuste regras e coloque IPs na lista de permissões para o OWASP ModSecurity CRS via Docker.

Documentação

Servidor MCP WAF

Um servidor MCP (Model Context Protocol) para gerenciar o OWASP ModSecurity CRS via Docker. Oferece a assistentes de IA como o Claude acesso direto ao monitoramento, análise e configuração do WAF por meio de um pipeline estruturado de detalhamento.

Desenvolvido para o Claude Code, mas funciona com qualquer cliente compatível com MCP.

Por quê

Serviços de proxy de LLM (LiteLLM, OpenRouter, etc.) ficam atrás de WAFs que geram uma quantidade enorme de falsos positivos — prompts contêm código, SQL, HTML, comandos de shell que disparam todas as regras de inspeção de conteúdo existentes. Gerenciar esses WAFs exige monitoramento constante, ajuste de exclusões e investigação de eventos.

Este servidor MCP permite que um assistente de IA faça esse trabalho diretamente:

  1. Visão geral — veja o total de eventos, IPs únicos, regras ativas de uma só vez
  2. Detalhamento — filtre eventos por IP ou regra, inspecione os dados correspondentes
  3. Ação — desative regras, coloque IPs na lista de permissões, altere o modo do mecanismo — tudo sem sair da conversa

Ferramentas

Análise (pipeline de detalhamento)

FerramentaDescrição
waf_overviewPainel: total de eventos, IPs/regras únicos, eventos na última hora
waf_top_ipsPrincipais IPs por contagem de eventos com enriquecimento geográfico (ipinfo.io)
waf_top_rulesRegras mais acionadas com gravidade e descrição
waf_fp_candidatesRegras acionadas em respostas HTTP 2xx (candidatos a falso positivo)
waf_events_by_ipEventos filtrados por IP de origem
waf_events_by_ruleEventos filtrados por ID de regra
waf_event_detailEvento completo: cabeçalhos, corpo da requisição, todas as correspondências de regras com dados correspondentes

Ações

FerramentaDescrição
waf_statusSaúde do contêiner, modo do mecanismo, regras carregadas, nível de paranoia
waf_set_engineAlternar entre On, Off, DetectionOnly
waf_set_paranoiaDefinir nível de paranoia do CRS (1–4)
waf_disable_ruleDesativar uma regra por ID (adiciona SecRuleRemoveById às exclusões)
waf_enable_ruleReativar uma regra previamente desativada
waf_allow_ipColocar um IP na lista de permissões (ignorar o WAF completamente)
waf_deny_ipRemover um IP da lista de permissões
waf_testExecutar suíte de testes: detecção de scanner, SQLi, XSS, path traversal

Parâmetros comuns

since — Todas as ferramentas de análise aceitam um parâmetro since para controlar a janela de tempo. O padrão é "24h". Suporta sintaxe de duração do Docker: "1h", "24h", "7d", "30m". Dias são convertidos automaticamente para horas (o --since do Docker não suporta o sufixo d nativamente).

waf_overview(since: "7d")        # last 7 days
waf_events_by_ip(ip: "1.2.3.4", since: "1h")  # last hour

verbose — waf_events_by_ip, waf_events_by_rule e waf_event_detail aceitam verbose: true. Por padrão, matchedData e requestBody são truncados para manter as respostas dentro dos limites de contexto:

CampoPadrãoDetalhado
matchedData (por regra)150–200 caracteres4000 caracteres
requestBody500 caracteres8000 caracteres

Pré-requisitos

  • Docker com um contêiner owasp/modsecurity-crs em execução
  • Docker Compose gerenciando o contêiner ModSecurity
  • Node.js 18+
  • ModSecurity configurado com log de auditoria JSON Serial (SecAuditLogFormat JSON)

Instalação

git clone https://github.com/KratosUAE/waf_mcp.git
cd waf_mcp
npm install
npm run build

Configuração

Variáveis de ambiente

VariávelObrigatóriaPadrãoDescrição
WAF_COMPOSE_DIRSim—Caminho para o diretório que contém docker-compose.yml
WAF_DOMAINNãohttps://localhostDomínio para requisições de teste do WAF
WAF_LOGS_SINCENão24hJanela de tempo padrão para consultas de log
WAF_CONTAINER_PATTERNNãomodsecurityPadrão de grep para encontrar o contêiner ModSecurity
WAF_EXCLUSIONS_FILENãomodsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.confCaminho para o arquivo de exclusões do CRS (relativo ao diretório do compose)
WAF_COMPOSE_FILENãodocker-compose.ymlNome do arquivo Docker Compose
IPINFO_TOKENNão—Token do ipinfo.io para geolocalização de IP
WAF_DEBUGNão—Defina qualquer valor para habilitar log de depuração

Conectar ao Claude Code

claude mcp add --transport stdio --scope user \
  -e WAF_COMPOSE_DIR=/path/to/your/compose/dir \
  -e WAF_DOMAIN=https://your-domain.com \
  waf -- node /path/to/waf_mcp/dist/index.js

Ou adicione manualmente ao ~/.claude.json:

{
  "mcpServers": {
    "waf": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/waf_mcp/dist/index.js"],
      "env": {
        "WAF_COMPOSE_DIR": "/path/to/your/compose/dir",
        "WAF_DOMAIN": "https://your-domain.com"
      }
    }
  }
}

Configuração do Docker Compose

O servidor espera um contêiner ModSecurity gerenciado pelo Docker Compose. Exemplo de definição de serviço:

modsecurity:
  image: owasp/modsecurity-crs:nginx-alpine
  environment:
    - BACKEND=http://your-app:8080
    - MODSEC_RULE_ENGINE=DetectionOnly
    - MODSEC_AUDIT_LOG=/dev/stderr
    - MODSEC_AUDIT_LOG_FORMAT=JSON
    - MODSEC_AUDIT_LOG_TYPE=Serial
    - MODSEC_AUDIT_ENGINE=RelevantOnly
    - MODSEC_REQ_BODY_ACCESS=On
    - MODSEC_REQ_BODY_LIMIT=52428800
    - MODSEC_RESP_BODY_ACCESS=Off
    - PARANOIA=1
    - ANOMALY_INBOUND=5
  volumes:
    - ./modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:/etc/modsecurity.d/owasp-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf:ro

Configurações principais:

  • MODSEC_AUDIT_LOG=/dev/stderr — envia o log de auditoria para os logs do Docker (necessário para o servidor MCP ler os eventos)
  • MODSEC_AUDIT_LOG_FORMAT=JSON — formato JSON para análise estruturada
  • Montagem do arquivo de exclusões — permite recarga a quente das exclusões de regras via nginx -s reload

Exclusões do CRS para tráfego de LLM

Os endpoints de API de LLM recebem prompts contendo código, SQL, HTML e comandos de shell — todo conteúdo legítimo que aciona regras do WAF. Crie um arquivo de exclusões para desativar regras de inspeção de conteúdo em caminhos de API:

# modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
SecRule REQUEST_URI "@rx ^(/v1/)?(chat/completions|completions|embeddings|responses|messages)|^/anthropic/" \
    "id:1000,phase:1,nolog,pass,\
    ctl:ruleRemoveById=921000-944999"

Isso desativa as regras 921000–944999 (todas as categorias de inspeção de conteúdo: SQLi, XSS, RCE, LFI, RFI, etc.) nos endpoints de API de LLM, mantendo ativos a aplicação de protocolo, detecção de scanner, proteção contra DoS e verificações de reputação de IP.

Exemplo de uso

Fluxo de trabalho típico no Claude Code:

You: "Check the WAF — anything suspicious?"

Claude: [calls waf_overview]
  → 332 events, 4 unique IPs, 12 rules triggered

Claude: [calls waf_top_ips]
  → 135.237.83.23 (Washington, US, Microsoft) — 320 events

Claude: [calls waf_events_by_ip, ip: "135.237.83.23", count: 5]
  → All POST /chat/completions, HTTP 200, rules: 942360, 932100...

Claude: [calls waf_event_detail, index: 42]
  → User-Agent: OpenAI/JS 6.26.0, body contains tool descriptions
  → Rule 942360 matched "update" in cron action descriptions

Claude: "This is your OpenClaw bot — all false positives.
         Want me to whitelist this IP?"

You: "Yes"

Claude: [calls waf_allow_ip, ip: "135.237.83.23"]
  → Done. IP whitelisted.

Investigando eventos mais antigos:

You: "Check IP 185.206.249.230 — it was flagged yesterday"

Claude: [calls waf_events_by_ip, ip: "185.206.249.230", since: "7d"]
  → 2 events from Apr 7, GET /v1/skills, HTTP 401, no rules triggered
  → Apple Private Relay IP (Singapore), just unauthorized API probes

Desenvolvimento

npm run build        # Compile TypeScript
npm test             # Run tests (43 tests)
npm run test:watch   # Watch mode
WAF_DEBUG=1 npm start  # Run with debug logging

Arquitetura

src/
├── index.ts           # MCP server setup, tool registration
├── waf-manager.ts     # Core service: Docker exec, log parsing, config management
├── types.ts           # TypeScript interfaces
├── config.ts          # Environment-based configuration
├── logger.ts          # stderr-only logger (stdout reserved for MCP protocol)
└── tools/
    ├── overview.ts        # L0: dashboard
    ├── top-ips.ts         # L1: IP aggregation
    ├── top-rules.ts       # L1: rule aggregation
    ├── fp-candidates.ts   # L1: false positive detection
    ├── events-by-ip.ts    # L2: drill-down by IP
    ├── events-by-rule.ts  # L2: drill-down by rule
    ├── event-detail.ts    # L3: full event inspection
    ├── status.ts          # Container status
    ├── set-engine.ts      # Engine mode control
    ├── set-paranoia.ts    # Paranoia level control
    ├── disable-rule.ts    # Rule management
    ├── enable-rule.ts     # Rule management
    ├── allow-ip.ts        # IP whitelist
    ├── deny-ip.ts         # IP whitelist
    ├── test.ts            # WAF test suite
    └── utils.ts           # Shared utilities

Os eventos são analisados dos logs do Docker e armazenados em cache por 30 segundos. Chamadas rápidas de detalhamento (visão geral → principais IPs → eventos por IP → detalhe do evento) usam o cache em vez de reanalisar. O cache é invalidado quando o parâmetro since muda.

Licença

MIT