@dracofy/shield
v1.0.12
Published
Proteção de campanhas de tráfego pago contra bots e crawlers automatizados
Readme
@dracofy/shield
Camada 1 do Dracofy Shield: decide no servidor, antes da página ser entregue, se o visitante vê a página real (allow) ou a Safe Page (qualquer outra resposta), sempre na mesma URL.
Instalar
Na raiz do seu projeto:
npx @dracofy/shield initO init detecta a hospedagem, mostra o progresso e cria o Shield, .env.local (fora do Git), shield.config.json, white.html e o site seguro em safe-site/. Nada é sobrescrito em silêncio: um arquivo que você já tinha vira .bak (em PHP o init recusa, para não expor código-fonte).
Sem perguntas (CI):
npx @dracofy/shield init --project-id <uuid> --token shld_xxxxx --niche "Capacetes"Opções: --stack vercel|nextjs|node|netlify|cloudflare|php, --domain, --pages, --force-safe-site, --no-banner, e os dados da empresa da Safe Page (opcionais): --company "Razão Social", --cnpj, --address, --email. Eles vão para o rodapé, Contato, Política de Privacidade (LGPD) e Termos; o CNPJ é validado e, sem dados, o texto fica genérico. Em CI e em pipes a saída é texto puro. NO_COLOR=1 desliga as cores.
O
initsó grava arquivos na sua máquina. Para valer em produção: credenciais no host, envio/deploy edoctor.
Onde o seu site está hospedado
| Hospedagem | Como o Shield roda | Você precisa |
|---|---|---|
| Vercel (estático, SPA, multipágina) | middleware.js na raiz | variáveis de ambiente na Vercel + git push |
| Next.js (com ou sem src/) | middleware.js / src/middleware.js | idem |
| Express (Railway, Render, Heroku, VPS) | dracofy-shield.js (app.use(...)) | variáveis no host + deploy |
| Netlify | Edge Function netlify/edge-functions/dracofy-shield.js | variáveis na Netlify + git push |
| Cloudflare (qualquer origem: PHP, WordPress, hospedagem comum) | Worker na frente do seu domínio | domínio no Cloudflare (nuvem laranja), wrangler deploy e wrangler secret put |
| PHP (cPanel, Hostinger, VPS) | dracofy-shield.php (arquivo único, sem Composer) | enviar os arquivos (FTP/Git) + uma linha nas páginas |
| Next.js com output: "export" | não suportado (site 100% estático, sem servidor) | o init recusa |
Cloudflare (domínio + lista de páginas)
npx @dracofy/shield init --stack cloudflare --domain minhaloja.com.br --pages "/,/oferta,/checkout/*"
npx wrangler login
npx wrangler deploy
npx wrangler secret put DRACOFY_SHIELD_TOKEN # cole o token; ele nunca vai para o Git- O Worker fica na frente do seu site.
white.htmlesafe-site/precisam estar na sua origem (o Worker busca a Safe Page lá). - No Cloudflare, o registro DNS do domínio precisa estar com a nuvem laranja (Proxied). Sem isso o Worker não roda.
--pageslista as páginas protegidas (/*= todas)./oferta,/oferta/,/oferta.html,/oferta.phpe/OFERTAcontam como a mesma página. Para mudar depois, editeDRACOFY_PROTECTED_PATHSnowrangler.tomle faça o deploy de novo.- O IP vem de
cf-connecting-ip, que o próprio Cloudflare escreve (o visitante não consegue forjar). Acesso direto ao IP da origem não passa pelo Worker: se possível, restrinja a origem a conexões do Cloudflare.
Netlify
npx @dracofy/shield init --stack netlify --pages "/,/oferta"Cadastre DRACOFY_SHIELD_TOKEN e DRACOFY_PROJECT_ID em Site configuration > Environment variables e faça o git push. As páginas protegidas ficam em config.path do arquivo gerado.
PHP
npx @dracofy/shield init --stack php --pages "index.php,oferta.php"- O
initcolocarequire __DIR__ . '/dracofy-shield.php';na primeira linha das páginas escolhidas (arquivos comnamespaceno topo não são alterados, ele avisa). - Envie por FTP/painel:
dracofy-shield.php,dracofy-shield.config.php(tem o token: fica fora do Git),white.html,safe-site/e as páginas alteradas. Alternativa aoconfig.php: variáveis de ambienteDRACOFY_SHIELD_TOKENeDRACOFY_PROJECT_ID. - Página
.html? Renomeie para.php(ou peça ao host para processar.htmlcomo PHP). - Precisa de PHP 7.0+ e
curl(ouallow_url_fopen) com saída HTTPS. Odoctorconfere. - O IP é o da conexão (
REMOTE_ADDR). Atrás de proxy seu:DRACOFY_PROXY_HOPS. Atrás do Cloudflare:DRACOFY_TRUST_CLOUDFLARE=1.
Variáveis de ambiente
O .env.local não vai para a produção. Cadastre no seu host:
| Variável | |
|---|---|
| DRACOFY_SHIELD_TOKEN | token do Shield |
| DRACOFY_PROJECT_ID | ID da campanha |
| DRACOFY_PROTECTED_PATHS | (Cloudflare) páginas protegidas, /* por padrão |
| DRACOFY_SESSION_MINUTES | opcional, padrão 240 |
| DRACOFY_PROXY_HOPS | opcional (Express e PHP), padrão 1 no Express e 0 no PHP |
| DRACOFY_TRUST_CLOUDFLARE | opcional, 1 se estiver atrás do Cloudflare |
Sem as duas primeiras, todo visitante vê a Safe Page.
IP do visitante (segurança)
O IP decide país, datacenter e proxy, então não pode ser forjável. Cada adaptador só confia em cabeçalhos que a infraestrutura escreve:
| Onde roda | O que é usado |
|---|---|
| Vercel / Next.js na Vercel | x-vercel-forwarded-for, x-real-ip, x-forwarded-for (a Vercel sobrescreve os três). cf-connecting-ip e true-client-ip são ignorados: a Vercel os repassa como o cliente mandou |
| Express | O IP anexado pelo proxy mais próximo (DRACOFY_PROXY_HOPS, padrão 1). Servidor exposto direto na internet: DRACOFY_PROXY_HOPS=0 |
| Netlify | context.ip (escrito pela Netlify) |
| Cloudflare Worker | cf-connecting-ip (escrito pelo Cloudflare) |
| PHP | REMOTE_ADDR; DRACOFY_PROXY_HOPS / DRACOFY_TRUST_CLOUDFLARE só quando você declara |
Conferir em produção
npx @dracofy/shield doctor https://seu-site.comConfirma que o Shield está ativo em produção, com o mesmo token do .env.local, sem chamar a API do Shield (sem log de acesso e sem risco de banir o seu IP). Em Netlify, Cloudflare e PHP passe a URL de uma página protegida (ex.: https://seu-site.com/oferta.php). Cada item tem gravidade (crítico ou aviso) e o relatório termina com um veredito:
| Veredito | Significa | |---|---| | PRONTO PARA SUBIR TRÁFEGO | arquivos e produção conferem | | PODE SUBIR, COM RESSALVAS | sem críticos, mas há avisos | | ARQUIVOS OK · PRODUÇÃO NÃO VERIFICADA | passe a URL para confirmar no ar | | NÃO SUBA TRÁFEGO AINDA | há problema crítico: o Shield não está protegendo |
O doctor também confere:
- que os arquivos do Shield estão commitados no Git (a Vercel e a Netlify só publicam o que está no repositório);
- que a oferta é publicada junto com a Safe Page (na Vercel, sem build, a pasta
public/é a única publicada: oinitsó a cria quando é seguro); - que o lead liberado enxerga a oferta, sem 404 e sem cair na Safe Page (teste com cookie de sessão assinado, sem chamar a API do Shield);
- que o servidor alcança a API do Shield (Cloudflare, Netlify e PHP) e, em PHP, que o
dracofy-shield.config.phpnão está exposto na web.
Sai com código 1 quando há item crítico (serve em CI). --json imprime o resultado em JSON.
