Filtro de Página
Quem for aprovado vê a página real, quem for reprovado vê a isca, e os dois no mesmo endereço. Leva cerca de 30 minutos, mais o tempo do certificado.
A página real não é configurada em lugar nenhum — a borda busca na origem o mesmo caminho que o visitante pediu. Só a isca é um destino fixo, e é a única página que você aponta.
Na sua hospedagem, crie um subdomínio origem apontando para a mesma pasta do site que já existe — não deixe criar pasta nova. Na Hostinger: Domínios → Subdomínios, marcando “Usar diretório public_html”.
Depois de criar, abra origem.seudominio.com no navegador. Tem que aparecer o seu site normalmente.
Se a hospedagem criar o subdomínio como ALIAS ou CNAME, ele pode arrastar endereços IPv6 que não respondem. O sintoma engana: o site funciona, mas cada visita leva 20 segundos. Prefira um registro A apontando direto para o IP do seu plano.
Só se o site for WordPress. Ele guarda o próprio endereço no banco e monta todos os links a partir dele — sem este ajuste a página abre pelo domínio público, mas o código-fonte entrega o endereço da origem.
No wp-config.php, logo acima da linha /* That's all, stop editing! */:
$guard_host = $_SERVER['HTTP_X_GUARD_HOST'] ?? '';
if ($guard_host && preg_match('/^[a-z0-9.-]+$/i', $guard_host)) {
$_SERVER['HTTP_HOST'] = $guard_host;
define('WP_HOME', 'https://' . $guard_host);
define('WP_SITEURL', 'https://' . $guard_host);
define('DISABLE_WP_CRON', true);
}O DISABLE_WP_CRON não é opcional. Sem ele o WordPress chama a si mesmo através da borda a cada visita — a requisição sai da hospedagem, dá a volta pela nossa borda e volta, com o PHP esperando o ciclo inteiro. São 20 segundos por visita, e nada acusa erro: o site simplesmente fica lento demais para vender.
Repare que ele está dentro do if. Assim o cron só é desligado nas visitas que chegam pela borda, e as tarefas agendadas do seu site principal continuam rodando.
Este ajuste conserta os links que o WordPress monta na hora (tema, plugins, menu). Mas o que você já inseriu pelo construtor — principalmente imagens — fica com o endereço da origem gravado no conteúdo, porque foi salvo quando você editava direto no domínio da origem. Este código não reescreve o que já está gravado.
Não precisa caçar essas URLs nem rodar "search-replace": a regra 0 do .htaccess (passo 5) deixa arquivo estático (imagem, css, js) passar sempre, então essas imagens carregam normal para o visitante — o HTML da oferta continua trancado. Se as imagens somem na aba anônima mas aparecem na logada, é sinal de que falta a regra 0 no seu lock.
No StegoAudio, aba Filtro de Página, crie um site novo:
| Campo | O que preencher |
|---|---|
| Nome | Só para você identificar |
| Domínios públicos | promo.seudominio.com |
| Onde o conteúdo real fica | origem.seudominio.com |
| Página isca | /paginaisca/ — só o caminho, com barra no começo |
O WordPress usa barra no final dos endereços. Escrevendo /paginaisca sem ela, a origem responde um redirecionamento a cada visita reprovada — e quando ele falha, o visitante recebe a página padrão em vez da sua isca.
Depois de salvar, o painel mostra o bloco Domínios na borda com os registros a criar. Copie os valores daquela tela, naquele momento — eles mudam toda vez que o domínio é registrado de novo.
| Tipo | Nome | Valor | TTL |
|---|---|---|---|
CNAME | promo | o endereço da borda que o painel mostra | 300 |
TXT | _acme-challenge.promo | um registro para cada valor que o painel listar | 300 |
Crie exatamente os TXT que o painel listar — pode ser um, podem ser dois. Quando são dois, eles têm o mesmo nome e conteúdos diferentes, um para cada tipo de certificado: não é engano nem duplicata, e criando só um o certificado fica pendente para sempre, sem nenhuma mensagem de erro. O painel diz o número na frente, e numera cada registro.
O segundo pode aparecer depois do primeiro. Vale clicar em Atualizar estado quando terminar de criar, e conferir se a lista cresceu.
Use TTL 300 desde o começo. Os provedores sugerem 14400, que são 4 horas — e se você precisar corrigir um valor depois, o antigo fica preso nesse tempo em servidores do mundo inteiro. É o erro que mais custa tempo nesta instalação.
Se o nome promo já tiver registros A ou AAAA, apague antes: um CNAME não pode conviver com eles. Se o subdomínio existir na hospedagem, remova lá também, senão ela recria os registros.
O painel passa a mostrar ATIVO em poucos minutos. O certificado sai em seguida.
Este passo é o que faz o filtro valer alguma coisa. Sem ele, qualquer um digita o endereço e vê a página real — e nada do resto importa.
Pegue o segredo do site no painel (botão de copiar, no cadastro) e coloque no .htaccess da pasta do site, antes da linha # BEGIN WordPress:
Esta página tem três blocos e eles não são intercambiáveis. Os dois primeiros vão num arquivo .htaccess e só funcionam em Apache/LiteSpeed. O terceiro vai na configuração do nginx e não funciona dentro de um .htaccess — colado lá ele não faz absolutamente nada, sem nenhuma mensagem de erro, e a oferta fica aberta.
Rode isto e veja o que aparece depois de server:
curl -sI https://origem.SEUDOMINIO.com/ | grep -i server
LiteSpeed, Apache ou hcdn → use um dos dois primeiros blocos (.htaccess). nginx → use o terceiro (configuração do nginx).
O bloco abaixo é para origem em WordPress — ele traz as exceções de wp-login/wp-admin e do cookie de login. Sem elas você tranca a si mesmo pra fora do painel (403 no editor). Se sua origem é HTML puro (estático), sem WordPress, pule para o bloco "Se a origem é HTML puro" mais abaixo: a mesma trava, mas sem essas exceções (num site estático elas não existem). Usar a versão errada é o erro mais comum aqui.
RewriteEngine On
# 0. Arquivos estáticos passam sempre (imagem/css/js/fonte não são o segredo;
# travá-los quebra as imagens da página pro visitante anônimo).
RewriteRule \.(jpe?g|png|gif|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|map)$ - [L]
# 1. Fora estáticos, só a borda (com o segredo) ou o admin logado passam —
# em QUALQUER endereço (raiz, www, origem, apex).
RewriteCond %{REQUEST_URI} !^/(wp-login\.php|wp-admin) [NC]
RewriteCond %{HTTP_COOKIE} !wordpress_logged_in [NC]
RewriteCond %{HTTP:x-guard-auth} !^SEU_SEGREDO_AQUI$
RewriteRule ^ - [F,L]
# 2. Documento NUNCA cacheia (a CDN guardaria a resposta autorizada e serviria
# a quem nao traz o segredo); estatico cacheia forte (senao vira 429).
<IfModule mod_headers.c>
SetEnvIf Request_URI "\.(jpe?g|png|gif|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|map)$" ESTATICO=1
Header always set Cache-Control "private, no-store" env=!ESTATICO
Header always set Cache-Control "public, max-age=31536000, immutable" env=ESTATICO
</IfModule>Há um lugar para trocar: o SEU_SEGREDO_AQUI pelo segredo do painel. Nenhum endereço para digitar, nenhuma lista de páginas para manter.
Repare que ela não tem condição de endereço nem lista de páginas. É de propósito.
Se você trancasse só os nomes das páginas de oferta, teria que lembrar de acrescentar cada oferta nova na regra — e toda página esquecida nasce aberta, com o sitemap do WordPress entregando o nome de graça. Trancando tudo, a oferta some de todos os endereços (raiz, www, origem, apex, e qualquer página futura), sem manutenção. Só a borda, com o segredo, entra.
A regra 1 tranca tudo. Sem as três exceções, você bloqueia a si mesmo: !wordpress_logged_indeixa passar quem já entrou (o editor carrega a página numa pré-visualização que não passa pela borda, e o Elementor travaria em "carregando"); !^/(wp-login|wp-admin) deixa a tela de login e o painel abrirem — sem ela você toma 403 antes mesmo de logar, já que aí ainda não existe cookie. Nenhuma abre brecha na oferta: o cookie só nasce depois do login com senha, e o wp-admin não é página de venda. E a regra 0 deixa as imagens passarem — sem ela, elas somem na aba anônima.
O Testar antes de subir abre origem.seudominio.com/ (a raiz) sem o cabeçalho e espera 403. Como a regra 1 tranca tudo em qualquer endereço, a raiz já responde 403 e o teste passa — sem nada de especial a configurar.
Como a regra tranca tudo, qualquer oferta ou página de teste que você criar depois já entra trancada — sem precisar voltar aqui para acrescentar nome nenhum. Uma preocupação a menos.
O Cache-Control (regra 2) resolve a última parte: sem ele, um CDN no caminho pode guardar a resposta já aprovada e servir para todo mundo. O vazamento aconteceria antes da borda, então ela não teria como impedir.
.htaccessSite estático na hospedagem, atrás da Cloudflare, sem WordPress? Use esta versão. Ela não tem as linhas de WordPress (não existe wp-admin nem cookie de login). A regra 2 continua — mas aqui ela precisa separar documento de estático (o motivo está no aviso abaixo). Troque só o SEU_SEGREDO_AQUI pelo segredo do painel:
RewriteEngine On
# 0. Estáticos passam a trava (não são o segredo)
RewriteRule \.(jpe?g|png|gif|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|map)$ - [L]
# 1. Trava: só a borda (com o segredo) entra; o resto leva 403
RewriteCond %{HTTP:x-guard-auth} !^SEU_SEGREDO_AQUI$
RewriteRule ^ - [F,L]
# 2. Cache: documento NUNCA, estático SEMPRE.
<IfModule mod_headers.c>
SetEnvIf Request_URI "\.(jpe?g|png|gif|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|map)$" ESTATICO=1
Header always set Cache-Control "private, no-store" env=!ESTATICO
Header always set Cache-Control "public, max-age=31536000, immutable" env=ESTATICO
</IfModule>Documento (HTML) sempre no-store: sem isso, a CDN da própria hospedagem guarda a resposta já autorizada (a que saiu com o x-guard-auth aprovado) e passa a servi-la a quem não trouxe o segredo — vazamento que acontece atrás da borda, onde ela não alcança. Já aconteceu em produção.
Estático (css/js/imagem) cacheia forte: um modelo antigo punha no-store em tudo — aí a CDN busca cada asset de novo a cada acesso, saindo dos poucos IPs da borda, e sob carga a hospedagem corta com 429 (a página abre só com a cor de fundo, sem imagem nem estilo). Separar as duas coisas resolve os dois problemas de uma vez.
.htaccessOs dois blocos acima são de Apache/LiteSpeed. Em nginx um .htaccess é um arquivo de texto que ninguém abre — a trava não existe e a oferta fica aberta, sem nenhuma mensagem de erro avisando. Para saber qual é o seu:
curl -sI https://origem.SEUDOMINIO.com/ | grep -i server
Peça isto a quem administra o servidor. Vai no bloco server do site (normalmente /etc/nginx/sites-available/SEUDOMINIO), e é a mesma coisa dos outros dois: trava, cache separado, e o 404 de verdade. Troque só o SEU_SEGREDO_AQUI:
# 0. Estaticos passam a trava (nao sao o segredo) e cacheiam forte
location ~* .(jpe?g|png|gif|webp|avif|svg|ico|css|js|mjs|woff2?|ttf|otf|eot|mp4|webm|map)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
try_files $uri =404;
}
# 1. Trava: so a borda (com o segredo) entra; o resto leva 403.
# 2. Documento NUNCA cacheia.
# 3. Endereco que nao existe responde 404 — e o "=404" no fim que faz isso.
location / {
if ($http_x_guard_auth != "SEU_SEGREDO_AQUI") { return 403; }
add_header Cache-Control "private, no-store" always;
try_files $uri $uri/ =404;
}Se a linha terminar em /index.html em vez de =404, o servidor responde 200 para qualquer endereço, inclusive os que não existem — e passa a devolver a página inicial no lugar do erro. Nenhum site de verdade faz isso, e é sinal que sistema automático de análise procura.
Medido em 25/09/2026: 11 de 33 origens tinham exatamente esse problema. Pediam /banana-voadora/ e recebiam a página inicial com 200.
Mesmo efeito, mesma correção: error_page 404 =200 /index.html; e rewrite ^ /index.html last;. Remova a linha.
O WordPress precisa do encaminhamento para o index.php, e isso está certo — ele responde 404 sozinho quando o conteúdo não existe. Troque só a última linha do bloco location / por try_files $uri $uri/ /index.php?$args; e adicione as exceções de wp-admin/wp-login, como no primeiro bloco desta página —sem elas você tranca a si mesmo pra fora do painel.
nginx -t && systemctl reload nginx — o nginx -t confere a sintaxe antes de aplicar. Se ele reclamar, não recarregue: o site sai do ar. E confirme no fim: curl -o /dev/null -s -w "%{http_code}" https://SEUDOMINIO/banana-voadora-123/ tem que responder 404.
Se o domínio está na Cloudflare (o promo aponta pra borda por CNAME), a trava não muda. A origem fica em nuvem cinza (Somente DNS) — a Cloudflare nem passa por ela: quem serve é a hospedagem, e é ela que lê o .htaccess. A borda busca a origem direto, com o segredo. Só seria diferente se você deixasse a origem em nuvem laranja e trancasse por regra de firewall da Cloudflare no lugar do .htaccess.
No painel do site, clique em Conferir instalação. Ele roda oito checagens — todas de coisas que, quando estão erradas, não geram mensagem de erro nenhuma:
no-store, sua hospedagem é rebuscada a cada visita e começa a cortar com 429: a página abre só com a cor de fundoCom a regra “só quem vem de anúncio” ligada, abra os dois endereços no seu próprio navegador:
https://promo.seudominio.com/paginareal/?gclid=teste → página real
https://promo.seudominio.com/paginareal/ → página iscaMesmo endereço, e a barra continua mostrando /paginareal/ nos dois casos. É proxy, não redirecionamento — quem foi reprovado não tem como perceber que foi filtrado, e o robô de revisão não vê o destino do anúncio mandando para outro lugar.
Este passo não tem nada a ver com o filtro, mas é onde a campanha silenciosamente deixa de dar retorno: a venda acontece e o Google nunca fica sabendo de qual anúncio ela veio. Sem isso, o Google Ads não tem como otimizar, e você fica olhando uma coluna de conversões zerada com vendas entrando.
O clique no anúncio chega na sua página com um identificador, o gclid. O Google guarda esse clique num cookie do domínio da sua página. Quando o comprador clica em comprar e vai para o checkout, ele está em outro domínio — que não enxerga esse cookie. Se o gclid não for junto na URL, o checkout não tem como saber de qual anúncio a venda veio, e a conversão fica órfã.
anúncio → promo.seudominio.com/oferta/?k=SUACHAVE&gclid=ABC123
(o Google guarda o clique aqui)
comprar → checkout.plataforma.com/xyz
(sem gclid: o checkout está cego)Um script que copia os parâmetros da URL para todos os links de saída da página. Cole no <head> da página de oferta:
<script>!function(){document.addEventListener("DOMContentLoaded",function(){
var q = new URLSearchParams(window.location.search);
var pular = ["k", "_verificar"];
document.querySelectorAll("a").forEach(function(a){
try {
var u = new URL(a.href);
q.forEach(function(v,k){
if (pular.indexOf(k) < 0 && !u.searchParams.has(k)) u.searchParams.set(k, v);
});
a.href = u.toString();
} catch(e) {}
});
});}()</script>pular é obrigatória aqui, e não é no resto da internetTodo tutorial de repasse de parâmetro copia tudo. Numa página comum isso é inofensivo. Na sua não é: sem a lista, o script mandaria a chave de URL junto para o domínio do checkout — ela apareceria na URL dele, no referrer e no painel da plataforma.
A chave é o que separa quem vê a oferta de quem vê a isca. Ela só pode existir no link do anúncio. Se o seu parâmetro tiver outro nome, troque "k" pelo nome que você configurou no painel.
O gclid chegar no checkout só resolve se o checkout souber o que fazer com ele: a plataforma precisa ter a tag de conversão do Google Ads na página de obrigado, ou enviar a conversão pela API dela. Se não tiver nada configurado lá, o parâmetro chega e morre. Confira isso no painel da plataforma de pagamento.
É comum sobrar tag antiga de outra conta na página. Se a campanha roda numa conta e a ação de conversão foi criada na outra, não marca nem com o gclid chegando certinho. Confira no HTML quantos AW- diferentes existem, e se o do anúncio é o mesmo da conversão.
A borda entrega a página com a URL inteira intacta, gclid incluído — é proxy, não redirecionamento, então a barra de endereço nunca perde parâmetro. Se a conversão não marca, o problema está no caminho da página para o checkout, não no filtro.
Presell é a página branca de transição entre o anúncio e a oferta: anúncio → presell → oferta. É ela que o moderador vê quando inspeciona o anúncio, então mantenha-a "white" — sem o conteúdo da oferta nela.
A chave não vai no anúncio: o anúncio aponta para a presell, sem chave. A chave vai no botão da presell que leva à oferta:
https://promo.seudominio.com/paginareal/?k=SUA_CHAVESó que aí o gclid/fbclid do anúncio fica na presell e some no salto para a oferta — e a trava “só quem vem de anúncio”reprovaria o comprador real. Este script na presell repassa esses parâmetros para o botão (troque o domínio pelo seu de oferta):
<script>
(function () {
var qs = new URLSearchParams(location.search)
if (![...qs].length) return
document.querySelectorAll('a[href]').forEach(function (a) {
try {
var u = new URL(a.href, location.href)
if (u.hostname !== 'promo.seudominio.com') return // seu domínio de oferta
qs.forEach(function (v, k) { if (!u.searchParams.has(k)) u.searchParams.set(k, v) })
a.href = u.toString()
} catch (e) {}
})
})()
</script>Quem acha sua presell num spy lê a chave no código do botão, e o gclid é só um parâmetro (dá para forjar colando ?k=chave&gclid=qualquercoisa). Então essas duas travas filtram origem de tráfego, não seguram um humano determinado. Quem realmente barra o moderador e o concorrente é o que ele não controla: as travas de país, proxy/VPN e robô/datacenter. Mantenha essas ligadas — são elas o muro. A presell ainda soma uma camada (o revisor vê a branca).
Todos os itens abaixo aconteceram numa instalação real. O que eles têm em comum é não produzirem erro visível — o site funciona, e o problema aparece como outra coisa.
wp-cron do WordPress chamando o próprio site pela borda. Passo 2, DISABLE_WP_CRON. A sexta checagem do verificador acusa isso./paginaisca por /paginaisca/.@) ainda existe. Ele é fácil de apagar sem querer no meio das mudanças, e o sintoma é específico: o endereço com www continua funcionando e o sem www não..htaccess está trancando só a origem. Falta a regra 1 do passo 5, a que não tem condição de endereço — é ela que faz a oferta sumir do domínio raiz, do www e de qualquer subdomínio.wordpress_logged_in: o editor carrega a página numa pré-visualização que não passa pela borda, e sem a exceção ela leva 403 como qualquer visitante.RewriteRule \.(jpe?g|png|...)$ - [L] logo depois de RewriteEngine On. O HTML da oferta continua trancado — só os arquivos passam./wp-admin depois de trancar a origem!^/(wp-login\.php|wp-admin) (senão a tela de login nem abre — antes de logar não há cookie) e !wordpress_logged_in (para seguir logado). Elas já estão no bloco do passo 5 acima.