Cloudflare Security Rules — Neofarma

Modelo mental

As custom rules da Cloudflare são avaliadas de cima para baixo (regra 1 → 2 → 3 → 4 → 5). Quando uma regra executa uma ação terminante (Block ou Managed Challenge), a request para ali e não chega às regras seguintes. A ação Skip retira a request do pipeline de segurança, permitindo que ela passe direto ao origin.

A estratégia adotada segue o princípio de filtro progressivo: as primeiras regras liberam tráfego que nunca deve ser bloqueado (allowlist, webhooks), e as regras seguintes bloqueiam do mais restritivo para o mais permissivo. A última regra aplica challenge em tráfego legítimo que ainda precisa de verificação.

Request → [1. Allowlist?] → [2. Webhook?] → [3. API/Interno?] → [4. Host/País?] → [5. Challenge?] → Origin
              skip              skip             block              block            challenge

Classificação dos subdomínios

Allowlist only (server-to-server)

Acesso exclusivo para IPs na lista $allowlist. Nenhum usuário acessa diretamente pelo browser.

SubdomínioFunção
api-internal.neofarma.com.brAPI interna, chamada exclusivamente por VPS

Internos (BR + CF Access)

Bloqueados para tráfego de fora do Brasil. O Cloudflare Access cuida da autenticação — o papel da custom rule aqui é apenas reduzir a superfície de ataque impedindo que tráfego internacional sequer chegue ao CF Access..

SubdomínioFunção
api.neofarma.com.brAPI principal (browser de usuários BR chama direto)
profissional.neofarma.com.brPortal profissional (depende do api.neofarma)
agent.neofarma.com.brAgente interno
chat.neofarma.com.brChat (recebe webhooks do WhatsApp/Facebook)
litellm.neofarma.com.brLiteLLM gateway
openwebui.neofarma.com.brOpen WebUI
sms.neofarma.com.brServiço de SMS

Nota: api.neofarma.com.br e chat.neofarma.com.br possuem exceções para webhooks (regra 2). O profissional.neofarma.com.br faz chamadas client-side ao api.neofarma.com.br, por isso ambos precisam estar acessíveis para IPs brasileiros — o IP de origem é o do browser do usuário, não o da VPS.

Client-facing (países amigos + challenge)

Acessíveis do Brasil sem restrição. Tráfego de países amigos (US, ES, PT, PE, CL, FR, GB, BO) recebe Managed Challenge. Países fora dessa lista são bloqueados.

SubdomínioFunção
neofarma.com.brSite principal
auth.neofarma.com.brAutenticação
portal.neofarma.com.brPortal do cliente
info.neofarma.com.brInformações
drpeel.neofarma.com.brMarca Dr. Peel
tratamento.neofarma.com.brTratamentos
checkout.neofarma.com.brCheckout
webinar.neofarma.com.brWebinars
lp.neofarma.com.brLanding pages
static.neofarma.com.brAssets estáticos (CSS, JS, imagens)

Nota: static.neofarma.com.br é excluído do challenge porque assets estáticos não conseguem resolver um challenge — isso quebraria o carregamento de imagens, CSS e JS em todos os subdomínios que referenciam o static.


Regras

Regra 1 — IP skip

Objetivo: garantir que IPs confiáveis nunca sejam afetados por nenhuma regra de segurança, presente ou futura.

Expression: (ip.src in $allowlist)
Action:     Skip → WAF custom rules, rate limiting, SBFM, managed rules

A allowlist contém: IPs das VPS (incluindo servidores US de webhook), IPs de administração e qualquer IP que precise de acesso irrestrito. Ao posicionar essa regra primeiro e usar Skip em todas as features, qualquer IP na lista passa direto sem avaliação adicional.

O que está na $allowlist:

  • IPs das VPS no Brasil
  • IPs dos servidores US (webhook e infra)
  • IPs de administração

Manutenção: ao adicionar nova infra (nova VPS, novo provedor de webhook), basta incluir o IP na allowlist. Nenhuma regra precisa ser alterada.


Regra 2 — Webhooks skip

Objetivo: permitir a entrega de webhooks de parceiros específicos, sem abrir o acesso geral às APIs.

Expression:
(http.host eq "api.neofarma.com.br"
 and http.request.uri.path contains "/webhook"
 and ip.src.country in {"BR"})
or
(http.host eq "chat.neofarma.com.br"
 and ip.src.asnum eq 32934
 and http.request.uri.path contains "/webhook")

Action: Skip → WAF custom rules restantes
ComponenteSignificado
http.request.uri.path contains "/webhook"Limita ao path de webhook, não abre toda a API
ip.src.country in {"BR"}Cobre o Itaú e outros parceiros nacionais
ip.src.asnum eq 32934ASN do Facebook/Meta (webhooks do WhatsApp)

Sobre o escopo de ip.src.country in {"BR"}: esta condição libera qualquer IP brasileiro no path /webhook do api.neofarma. Se isso for considerado muito amplo no futuro, a alternativa é: adicionar os IPs do Itaú na $allowlist (regra 1 já cobre) e manter a regra 2 apenas com o ASN do Facebook.


Regra 3 — APIs restritas + internos non-BR

Objetivo: bloquear acesso não autorizado a APIs e subdomínios internos.

Expression:
(http.host eq "api-internal.neofarma.com.br")
or
(http.host in {
  "api.neofarma.com.br"
  "agent.neofarma.com.br"
  "chat.neofarma.com.br"
  "litellm.neofarma.com.br"
  "openwebui.neofarma.com.br"
  "sms.neofarma.com.br"
  "profissional.neofarma.com.br"
} and not ip.src.country in {"BR"})

Action: Block

Esta regra tem dois comportamentos em uma expression:

Parte 1 — api-internal: block incondicional

Qualquer request para api-internal.neofarma.com.br é bloqueada. Não há filtro de país porque o acesso é exclusivo para allowlist — e quem está na allowlist já saiu na regra 1. O efeito combinado das regras 1 + 3 é: api-internal aceita apenas $allowlist.

Parte 2 — internos: block non-BR

Os demais subdomínios internos bloqueiam tráfego de fora do Brasil. Tráfego BR passa e encontra o Cloudflare Access, que cuida da autenticação. Webhooks do Facebook e parceiros BR já saíram na regra 2, então não são afetados.


Regra 4 — Subdomínios desconhecidos + países hostis

Objetivo: catch-all que bloqueia subdomínios não gerenciados e tráfego de países sem clientes.

Expression:
(not http.host in {
  "neofarma.com.br"
  "agent.neofarma.com.br"
  "chat.neofarma.com.br"
  "profissional.neofarma.com.br"
  "auth.neofarma.com.br"
  "drpeel.neofarma.com.br"
  "portal.neofarma.com.br"
  "info.neofarma.com.br"
  "lp.neofarma.com.br"
  "api.neofarma.com.br"
  "sms.neofarma.com.br"
  "litellm.neofarma.com.br"
  "static.neofarma.com.br"
  "tratamento.neofarma.com.br"
  "openwebui.neofarma.com.br"
  "checkout.neofarma.com.br"
  "webinar.neofarma.com.br"
  "api-internal.neofarma.com.br"
})
or
(not ip.src.country in {"BO" "BR" "CL" "FR" "PE" "PT" "GB" "US" "ES"})

Action: Block

Duas funções combinadas via OR:

CondiçãoO que protege
Host não está na lista de 18 subdomíniosBloqueia acesso a subdomínios não gerenciados (ex: teste.neofarma.com.br)
País não está na lista de 9 países amigosBloqueia tráfego de países onde não há clientes

Lista de países amigos: BR (Brasil), US (EUA), ES (Espanha), PT (Portugal), PE (Peru), CL (Chile), FR (França), GB (Reino Unido), BO (Bolívia).

Manutenção: ao criar um novo subdomínio, adicioná-lo nesta lista. Ao expandir para um novo mercado, adicionar o código do país.


Regra 5 — Challenge non-BR em client-facing

Objetivo: verificar que tráfego de países amigos (non-BR) é humano antes de permitir acesso.

Expression:
(not ip.src.country in {"BR"}
 and not http.host in {"static.neofarma.com.br"})

Action: Managed Challenge

Neste ponto do pipeline, o tráfego que chega à regra 5 é:

  • De um país amigo (os demais foram bloqueados na regra 4)
  • Em um subdomínio client-facing (internos foram bloqueados na regra 3)
  • Não está na allowlist (saiu na regra 1)

A regra aplica Managed Challenge — o usuário resolve (geralmente invisível, sem CAPTCHA) e acessa normalmente. Tráfego do Brasil passa direto sem challenge.

static.neofarma.com.br é excluído porque requests de assets estáticos (imagens, CSS, JS) são feitas automaticamente pelo browser e não conseguem resolver um challenge, o que quebraria o carregamento das páginas.


Resumo do fluxo por cenário

OrigemDestinoRegraResultado
IP na $allowlistqualquer subdomínio1Passa direto
Itaú (BR) → /webhookapi.neofarma2Passa direto
Facebook (ASN 32934) → /webhookchat.neofarma2Passa direto
Hacker RU → /webhookapi.neofarma3Bloqueado (non-BR)
Usuário BRprofissional.neofarmaPassa → CF Access autentica
Usuário BRapi.neofarma (via browser)Passa → funciona com profissional
Usuário USprofissional.neofarma3Bloqueado (non-BR, interno)
Qualquer (non-allowlist)api-internal.neofarma3Bloqueado (incondicional)
Usuário BRcheckout.neofarmaPassa direto
Usuário UScheckout.neofarma5Managed Challenge → passa
Usuário CNcheckout.neofarma4Bloqueado (país hostil)
Usuário USstatic.neofarmaPassa direto (sem challenge)
Qualquerxyz.neofarma.com.br4Bloqueado (host desconhecido)

Pontos de atenção

Regra 2: escopo do webhook BR

A condição ip.src.country in {"BR"} na parte do api.neofarma libera qualquer IP brasileiro no path /webhook. Se no futuro isso for muito permissivo, há duas opções:

  1. Restringir por ASN do Itaú: trocar ip.src.country in {"BR"} por ip.src.asnum eq XXXXX
  2. Mover para allowlist: adicionar os IPs do Itaú na $allowlist e remover a condição de país da regra 2

Bot Fight Mode

O Bot Fight Mode (versão gratuita) opera fora do Ruleset Engine. Custom rules não conseguem skipá-lo. Se ele bloquear tráfego legítimo, as opções são desativá-lo ou fazer upgrade para Super Bot Fight Mode (que aceita Skip rules).

Novos subdomínios

Ao criar um novo subdomínio, classificá-lo e atualizar as regras:

  • Interno (BR + CF Access): adicionar na regra 3 (lista de hosts internos)
  • Client-facing: adicionar na regra 4 (lista de hosts permitidos)
  • Em ambos os casos, a regra 4 precisa ser atualizada para incluir o novo host na lista de subdomínios conhecidos

Novos países

Ao expandir para um novo mercado, adicionar o código do país na regra 4 (lista de países amigos).

Diagnóstico de bloqueios

Se um request legítimo for bloqueado:

  1. Ir em Security > Events
  2. Localizar a request bloqueada
  3. Verificar o campo Service (identifica o produto: custom rules, managed rules, bot fight mode, etc.)
  4. Verificar o campo Rule ID (identifica qual regra específica atuou)
  5. Conferir se o host e país estão nas listas corretas da regra identificada