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ínio | Função |
|---|---|
api-internal.neofarma.com.br | API 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ínio | Função |
|---|---|
api.neofarma.com.br | API principal (browser de usuários BR chama direto) |
profissional.neofarma.com.br | Portal profissional (depende do api.neofarma) |
agent.neofarma.com.br | Agente interno |
chat.neofarma.com.br | Chat (recebe webhooks do WhatsApp/Facebook) |
litellm.neofarma.com.br | LiteLLM gateway |
openwebui.neofarma.com.br | Open WebUI |
sms.neofarma.com.br | Serviço de SMS |
Nota:
api.neofarma.com.brechat.neofarma.com.brpossuem exceções para webhooks (regra 2). Oprofissional.neofarma.com.brfaz chamadas client-side aoapi.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ínio | Função |
|---|---|
neofarma.com.br | Site principal |
auth.neofarma.com.br | Autenticação |
portal.neofarma.com.br | Portal do cliente |
info.neofarma.com.br | Informações |
drpeel.neofarma.com.br | Marca Dr. Peel |
tratamento.neofarma.com.br | Tratamentos |
checkout.neofarma.com.br | Checkout |
webinar.neofarma.com.br | Webinars |
lp.neofarma.com.br | Landing pages |
static.neofarma.com.br | Assets 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
| Componente | Significado |
|---|---|
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 32934 | ASN 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ção | O que protege |
|---|---|
| Host não está na lista de 18 subdomínios | Bloqueia acesso a subdomínios não gerenciados (ex: teste.neofarma.com.br) |
| País não está na lista de 9 países amigos | Bloqueia 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
| Origem | Destino | Regra | Resultado |
|---|---|---|---|
| IP na $allowlist | qualquer subdomínio | 1 | Passa direto |
Itaú (BR) → /webhook | api.neofarma | 2 | Passa direto |
Facebook (ASN 32934) → /webhook | chat.neofarma | 2 | Passa direto |
Hacker RU → /webhook | api.neofarma | 3 | Bloqueado (non-BR) |
| Usuário BR | profissional.neofarma | — | Passa → CF Access autentica |
| Usuário BR | api.neofarma (via browser) | — | Passa → funciona com profissional |
| Usuário US | profissional.neofarma | 3 | Bloqueado (non-BR, interno) |
| Qualquer (non-allowlist) | api-internal.neofarma | 3 | Bloqueado (incondicional) |
| Usuário BR | checkout.neofarma | — | Passa direto |
| Usuário US | checkout.neofarma | 5 | Managed Challenge → passa |
| Usuário CN | checkout.neofarma | 4 | Bloqueado (país hostil) |
| Usuário US | static.neofarma | — | Passa direto (sem challenge) |
| Qualquer | xyz.neofarma.com.br | 4 | Bloqueado (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:
- Restringir por ASN do Itaú: trocar
ip.src.country in {"BR"}porip.src.asnum eq XXXXX - 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:
- Ir em Security > Events
- Localizar a request bloqueada
- Verificar o campo Service (identifica o produto: custom rules, managed rules, bot fight mode, etc.)
- Verificar o campo Rule ID (identifica qual regra específica atuou)
- Conferir se o host e país estão nas listas corretas da regra identificada