Sua sessão. Seu IP. Seu fingerprint. Sua escolha.
Um navegador descartável, isolado, com IP rotacionado pelo Tor e fingerprint coerente trocado em nível C++. Linux (Debian/Arch/Fedora + Flatpak fallback) e macOS. Bash. Sem telemetria. Sem conta. Sem rastro.
npm i -g anonymous-browser # uma vez
anonymous-browser # toda vez que quiser uma identidade novaA web de 2026 não te trata como visitante. Te trata como target. Cada fetch() que seu browser faz num site arbitrário sai com:
- IP público (resolvível pra cidade, ISP, AS, e muitas vezes pra você como pessoa)
- Canvas hash, WebGL renderer, audio fingerprint, lista de fontes, screen + colorDepth,
Intl.timeZone,navigator.platform, Client Hints,userAgentData.brands - Cookies, localStorage, IndexedDB, ServiceWorker caches, ETags persistentes
- TLS JA3/JA4, HTTP/2 SETTINGS frame fingerprint, ordem de headers
Combinando esses sinais, um único site identifica você unicamente em >99% das visitas (Panopticlick, FingerprintJS). Cookie-clearing, modo anônimo e VPN básica resolvem nenhum dos vetores acima.
anonymous-browser é o oposto político disso: uma stack curta de scripts shell que monta, antes de cada sessão, uma máquina virtual de identidade — IP, fingerprint, locale, geo, timezone — coerente o suficiente pra passar em CreepJS com Trust >70% e descartável o suficiente pra desaparecer no Ctrl+C.
Isso não é furtar. Isso é se recusar a pagar com seus dados o pedágio que sites cobram pra te deixar entrar. É o mesmo princípio das listas de domínio do uBlock Origin, do Tor Project, do EFF Privacy Badger, do Mullvad VPN: na ausência de uma lei honesta de privacidade, você se defende sozinho.
"Privacy is necessary for an open society in the electronic age. Privacy is not secrecy." — Eric Hughes, A Cypherpunk's Manifesto (1993)
# via npm (recomendado): instala um comando 'anonymous-browser' no seu PATH
npm i -g anonymous-browser
anonymous-browserNa primeira execução o comando dispara install.sh automaticamente (instala Tor, libs nativas do Camoufox e o venv Python — pede sudo). Depois disso, cada execução pergunta se você quer um e-mail temporário descartável e abre o browser.
Quer rodar do source sem npm?
git clone https://github.com/frederico-kluser/anonymous-browser
cd ghost-browser
./install.sh
./anonymous.shanonymous-browser (ou ./anonymous.sh) te pergunta a URL, sorteia um OS pra spoofar (windows/macos/linux), força um novo circuito Tor, abre um Firefox-patched (Camoufox) com fingerprint coerente, nega GPS silenciosamente e apaga tudo (perfil temporário, browser, processo) no momento que você fecha o navegador, dá Ctrl+C ou fecha o terminal.
| Vetor | Defesa |
|---|---|
| IP / ASN / geo | Tor SOCKS5 em 127.0.0.1:9050, novo circuito por sessão via new-tor-circuit.sh |
| Cookies, storage, cache | Perfil em mktemp -d, apagado por trap INT TERM HUP EXIT |
| Canvas / WebGL / Audio / Fonts | Camoufox patcha em C++ (Firefox fork da BrowserForge) |
navigator.platform, Client Hints, userAgentData |
Camoufox os="windows"|"macos"|"linux" — coerentes entre si |
Intl.timeZone, navigator.language |
Camoufox geoip=True → bate com cidade do exit Tor (dataset MaxMind) |
| WebRTC IP leak | Camoufox block_webrtc=True (default) |
| HTML5 Geolocation API | firefox_user_prefs={"permissions.default.geo": 2} → site recebe PERMISSION_DENIED sem prompt |
| Botão "X" do navegador | BrowserContext.wait_for_event("close") → encerra script + apaga perfil |
| Proxy / VPN customizado | env var PROXY=socks5://... sobrescreve Tor default; PROXY=none desliga proxy |
| Identidade persistente | env var KEEP=nome salva perfil em ~/.anonymous-browser/profiles/<nome>/ com OS fixado |
E o que não dá pra resolver com esta stack — sendo honesto:
- Anti-bot enterprise (Cloudflare Bot Management, DataDome, PerimeterX, Kasada). Esses caras analisam TLS JA3, HTTP/2 frame ordering, comportamento de mouse com ML. Camoufox melhora mas não esconde. Se você precisa passar por isso, vai pagar GoLogin, Multilogin, AdsPower — não é missão deste repo.
- Mobile fingerprint coerente. Camoufox só suporta desktop (
windows/macos/linux). Removemos os perfis iPhone/iPad/Android do projeto para não dar falsa sensação de proteção — qualquer anti-bot detectava como inconsistente. - Identidade externa. Se o site quer SMS/e-mail único, você precisa de addy.io, SimpleLogin, número descartável. Fora do escopo.
Esta seção lista, sem omissões, cada técnica usada pelo
anonymous-browsere como ela é implementada. A intenção é que você possa auditar tudo lendo o código — cada subseção referencia o arquivo e o bloco relevantes. Se algo está aqui, está no código. Se está no código mas não está aqui, é bug de documentação — abra issue.
Sem PROXY setado (ou com PROXY=tor), o tráfego do navegador sai pelo Tor local em 127.0.0.1:9050. Tor já vem instalado pelo install.sh e habilitado como serviço (systemctl enable --now tor no Linux, brew services start tor no macOS — ambos persistem entre boots).
Arquivo: anonymous.sh, bloco # -------- resolve PROXY --------. O default está no case ""|tor) PROXY_URL="socks5://127.0.0.1:9050".
Quatro modos aceitos: tor (default), none (sem proxy — IP real), socks5://host:port, http(s)://host:port. Qualquer outro valor faz o script abortar antes de tocar no navegador. SOCKS4 não é suportado — limitação do Playwright (engine do Camoufox), explicitada no comentário do código.
Arquivo: anonymous.sh, mesmo bloco. Validação por case exclusivo.
Quando o proxy é SOCKS5, todas as chamadas de curl que o anonymous-browser faz usam --socks5-hostname em vez de --socks5. A diferença é crítica: --socks5-hostname envia o nome do host para o proxy resolver; --socks5 resolve localmente e só manda o IP. Sem --hostname, seu resolver DNS do sistema (ISP, Google 8.8.8.8) veria todas as queries — leak de DNS clássico.
Arquivo: lib/platform.sh, função anon_curl_proxy_args(). O comportamento é simétrico ao que install.sh usa pra testar Tor (--socks5-hostname 127.0.0.1:9050).
Antes de abrir o navegador (quando proxy é Tor), o anonymous-browser força um circuito novo — IP de saída diferente do que você acabou de usar. Dois caminhos:
- Caminho rápido: se você habilitou
ControlPort 9051notorrc, mandamosAUTHENTICATE "" / SIGNAL NEWNYM / QUITvianc 127.0.0.1 9051. Tor renova circuitos sem reiniciar. Latência: ~1s. - Fallback: se ControlPort estiver fechada, fazemos reload do serviço (
sudo systemctl reload toroubrew services restart tor). Funciona, mas é mais lento (~5–15s) e fecha qualquer conexão Tor ativa.
Arquivo: new-tor-circuit.sh. A escolha do caminho é decidida por anon_port_open 127.0.0.1 9051.
Cloudflare hoje bloqueia o conjunto clássico de endpoints de "qual é meu IP" (api.ipify.org, ipinfo.io, checkip.amazonaws.com, icanhazip.com) quando a origem é exit Tor — devolvem HTTP 403 ou corpo vazio. Se o Camoufox tentasse o auto-probe interno dele, levantaria InvalidIP e o navegador nunca abriria.
Resolução: o anonymous-browser resolve o IP de saída no próprio shell consultando https://check.torproject.org/api/ip (purpose-built pra detectar Tor, nunca bloqueia), parseia .IP com jq, e passa o IP como string para geoip= do Camoufox. Tem fallback para icanhazip.com, ifconfig.co/ip, ipecho.net/plain quando o proxy não é Tor.
Se todos falham (rede caída, todo mundo bloqueado): cai para geoip=False com aviso, mas o navegador ainda abre — preferimos identidade levemente inconsistente a sessão impossível.
Arquivo: anonymous.sh, bloco # -------- resolve IP de saída para geoip --------.
A maioria dos anti-detect "soluções" baratas spoofa navigator.platform via hook JavaScript injetado no documento. Detectar isso é trivial: o site checa navigator.platform.toString.toString() ou compara Object.getOwnPropertyDescriptor(navigator, 'platform').get com o esperado, ou simplesmente carrega um iframe cuja janela ainda tem o platform real.
Camoufox é um fork do Firefox que patcha os valores em C++, antes de o JS ser executado. Não há Function.prototype.toString que delate o hook, porque não existe hook — o valor é genuíno no nível do engine. É o mesmo princípio que o Tor Browser usa, exceto que Camoufox spoofa uma identidade arbitrária em vez de uma uniforme.
anonymous-browser escolhe (ou recebe via ANON_OS) um entre windows, macos, linux. Esse único valor cascateia em dezenas de subvetores que Camoufox alinha sozinho:
navigator.platform(Win32/MacIntel/Linux x86_64)navigator.userAgent(versão de Firefox compatível com o OS)navigator.userAgentData.brands/.platform(Client Hints)- Headers HTTP
Sec-CH-UA-Platform,Sec-CH-UA-Platform-Version - Lista de fontes disponíveis (
Segoe UIaparece no Windows, não no Linux) - Vendor / Renderer de WebGL coerentes (
ANGLE (NVIDIA…)no Windows,Apple Inc.no macOS)
A coerência interna é o que detectores procuram. Spoofar UA pra Windows e deixar navigator.platform="Linux x86_64" é detectado em milissegundos por qualquer fingerprinter sério. Camoufox + BrowserForge sincronizam todos os campos antes do primeiro byte ir pro site.
Arquivo: anonymous.sh, bloco # -------- resolve ANON_OS -------- + chamada Camoufox(os=OS_ARG, ...).
| Vetor | Como spoofamos |
|---|---|
| Screen | Screen(max_width, max_height) da browserforge.fingerprints — limites por OS (1920×1080 win/linux, 2560×1600 macos). Camoufox sorteia dentro do limite. |
| Fontes | Dataset bundled da BrowserForge — Camoufox restringe a document.fonts ao set típico do OS sorteado. |
| Canvas | Patch C++: HTMLCanvasElement.prototype.toDataURL retorna pixels com ruído determinístico por sessão, mas constante entre frames da mesma sessão (anti-detecção de "noise random per call"). |
| WebGL | Vendor / Renderer / UNMASKED_VENDOR_WEBGL / UNMASKED_RENDERER_WEBGL reescritos no Firefox patched, casando com o OS. |
| Audio | AudioContext.createOscillator retorna buffer levemente alterado — quebra audioContext.fingerprint da FingerprintJS. |
Tudo isso é feito pelo Camoufox/BrowserForge — não há código nosso aqui além de escolher o OS e passar a Screen correta. A "magia" toda mora no fork do Firefox.
Arquivo: anonymous.sh, dict screens = {...} + bloco with Camoufox(...).
Chromium e Firefox modernos mandam um set de headers que o site explicitamente requisita (Accept-CH). Esses headers não estão expostos a navigator.userAgent — um spoof clássico de UA não os afeta. Camoufox os patcha em nível de rede no Firefox patched, casando com o OS spoofado.
Verificável: abra https://browserleaks.com/javascript dentro do anonymous.sh e compare a seção "User-Agent Client Hints" com o OS sorteado.
Camoufox(humanize=True) injeta micro-delays entre eventos (mouse-move, keypress) seguindo distribuições típicas de humano. Não é bot-puro com page.click() instantâneo. Útil contra trackers comportamentais simples (requestAnimationFrame-based behavioral detection); inútil contra ML-based behavioral (Datadome, Akamai BMP) — esses casos exigem stack diferente.
Arquivo: anonymous.sh, kwarg humanize=True na chamada with Camoufox(...).
Mesmo com proxy SOCKS5, WebRTC clássico (RTCPeerConnection) faz STUN/TURN diretos que ignoram proxy HTTP/SOCKS — vazam IP local e público em segundos. Camoufox traz block_webrtc=True como default — o stack inteiro de WebRTC fica desligado no Firefox patched. Não é configurável a partir do nosso anonymous.sh (intencional: ligar WebRTC anula meio Tor).
Verificável: https://browserleaks.com/webrtc deve mostrar "No leaks".
firefox_user_prefs={"permissions.default.geo": 2} — 2 significa deny implícito sem mostrar prompt ao usuário. Sites recebem PERMISSION_DENIED instantaneamente quando chamam navigator.geolocation.getCurrentPosition(). Diferente do default Firefox (0 = prompt), que daria pop-up — sinal forte de fingerprint atípico.
Arquivo: anonymous.sh, kwarg firefox_user_prefs={"permissions.default.geo": 2} no Camoufox(...).
Camoufox consulta o dataset MaxMind GeoLite2 (baixado pelo install.sh via python -m camoufox fetch, ~65 MB) para mapear o IP de saída em:
Intl.DateTimeFormat().resolvedOptions().timeZone— timezone coerente com a cidade do exitnavigator.language/navigator.languages— idioma típico da região (pt-BR no Brasil, fr-FR na França, etc.)- Locale do Firefox (formato de datas, moeda)
Sem isso, você pareceria "ucraniano com timezone de NY" para qualquer site que cruza esses sinais.
Como descrito em §1.5: Camoufox geoip=True tentaria descobrir o IP via api.ipify.org/ipinfo.io — tudo Cloudflare-blocked pra exits Tor. Resolvemos o IP no shell e passamos como string explícita: geoip="185.220.101.42".
Quando você desliga o proxy, automaticamente desabilitamos geoip (geoip_kw = False). Razão: se o Camoufox fizer auto-probe de IP, ele vai bater em api.ipify.org com seu IP real — o IP que você acabou de pedir pra esconder. Trade-off: sem geoip, locale/timezone podem não bater com sua região real (alguns sites notam), mas seu IP fica em casa.
Arquivo: anonymous.sh, bloco final no heredoc Python — if proxy_arg is None: geoip_kw = False.
Sem KEEP, o user_data_dir do Firefox é criado via mktemp -d "$(anon_tmp_prefix)/anon-XXXXXX". anon_tmp_prefix() retorna $TMPDIR no macOS (/var/folders/.../T/) ou /tmp no Linux. Tudo (cookies, localStorage, IndexedDB, ServiceWorker caches, ETags) vive só dentro desse dir e é apagado pelo trap no EXIT.
Por que perfil temporário e não anônimo do Firefox? Modo anônimo do Firefox persiste alguns artefatos entre janelas privadas no mesmo processo, e principalmente não isola fingerprint — o objetivo aqui é zero state, não privacidade-de-cookies.
Arquivo: anonymous.sh, bloco # -------- perfil descartável OU persistente --------.
Setando KEEP=trabalho, o perfil vive em ~/.anonymous-browser/profiles/trabalho/. Cookies, histórico, logins, extensões — tudo persiste entre execuções. Útil pra ter identidades alternativas estáveis (uma "pessoa" pra trabalho, outra pra pessoal, sem cross-contamination).
Validação: KEEP precisa casar ^[A-Za-z0-9_-]+$. Sem ., sem /, sem espaço — previne path traversal e nomes problemáticos no mkdir -p.
Arquivo: anonymous.sh, bloco # -------- resolve KEEP --------.
Cada perfil persistente memoriza o OS sorteado na primeira vez, num arquivo .anon-os dentro do próprio perfil. Sessões subsequentes leem o OS do arquivo (sem sorteio novo), mantendo a identidade coerente entre as visitas — navigator.platform não pula de Win32 pra MacIntel entre execuções, o que delataria spoofing.
Override possível: ANON_OS=macos KEEP=trabalho ... reescreve o .anon-os na hora.
Arquivo: anonymous.sh, bloco # -------- resolve ANON_OS -------- (lógica de leitura/escrita do OS_FILE).
O Python espera por browser.wait_for_event("close", timeout=0) — timeout zero = infinito. O evento close é disparado quando o processo Firefox termina (todas as janelas fechadas, ou kill no processo). Enquanto o navegador está aberto, o shell fica passivamente bloqueado — zero CPU.
Arquivo: anonymous.sh, dentro do with Camoufox(...). Note que KeyboardInterrupt e SystemExit são capturados pra cleanup limpo em Ctrl+C / SIGTERM.
Tor com exit ruim pode demorar >30s pra responder. Default do Playwright derruba a sessão com TimeoutError. Aumentamos pra 60s e capturamos a exceção: se goto falhar, imprimimos aviso e a janela continua aberta — você decide se recarrega, troca circuito (./new-tor-circuit.sh), ou desiste com Ctrl+C.
Arquivo: anonymous.sh, dentro do with Camoufox(...) — bloco try: page.goto(URL, timeout=60_000).
trap cleanup INT TERM HUP EXITINT(SIGINT) — Ctrl+C no terminalTERM(SIGTERM) —kill <pid>ousystemctl stopHUP(SIGHUP) — terminal fechado (SSH disconnect, fechar janela do gnome-terminal)EXIT— qualquer saída do script, incluindoexit 0normal e erros viaset -e
O cleanup() é idempotente: mata o watcher de e-mail (se MAIL=1), espera ele encerrar com wait, e apaga o $TMP se for perfil descartável. Garante que nenhum caminho de saída deixa lixo.
Arquivo: anonymous.sh, função cleanup() no topo do script.
Dentro do heredoc Python:
for s in (signal.SIGHUP, signal.SIGTERM):
signal.signal(s, lambda *_: sys.exit(0))Razão: SIGINT o Python já converte em KeyboardInterrupt sozinho. SIGHUP e SIGTERM por default matam o processo sem rodar finally — perderíamos a chance de fechar o Camoufox educadamente. Convertendo em sys.exit(0), o with do context manager dispara __exit__ e fecha o browser apropriadamente.
Quando MAIL=1, anonymous-mail.sh roda em background com seu próprio PID. O cleanup() do anonymous.sh faz kill "$MAIL_PID" seguido de wait "$MAIL_PID". O wait é importante: dá tempo do trap do anonymous-mail.sh rodar (que apaga a conta no mail.tm), antes do shell pai sair. Sem wait, a conta efêmera vaza no mail.tm.
Arquivo: anonymous.sh, função cleanup() (linhas iniciais).
nap() {
sleep "$1" &
SLEEP_PID=$!
wait "$SLEEP_PID" 2>/dev/null || true
SLEEP_PID=""
}sleep puro do bash não responde a sinais até terminar. Se o poll do mail é 5s e o usuário Ctrl+C, o watcher esperaria os 5s antes de reagir — visível como lag perceptível ao fechar o navegador. Rodando sleep & + wait, qualquer sinal dispara o trap imediatamente; o trap mata o SLEEP_PID e o script encerra em <100ms.
Arquivo: anonymous-mail.sh, função nap().
Critérios pro serviço: free, sem API key, sem cadastro, REST público, deletável. mail.tm bate todos:
- Gratuito, sem limite de contas (rate limit de 8 req/s, ok pra polling)
- Sem signup nem API key:
POST /accountscria e retorna ID na hora - API REST documentada (Hydra-style; aceitamos JSON Accept header pra evitar envelope)
DELETE /accounts/{id}apaga conta de verdade
Alternativas (Guerrilla Mail, 10minutemail) ou exigem API paga, ou retornam endereços já-spammed, ou bloqueiam Tor agressivamente.
Atribuição obrigatória nos termos: "Inbox by mail.tm" — incluída no banner que imprimimos.
Três chamadas:
GET /domains— lista de domínios ativos no mail.tm (rotacionam de tempos em tempos). Pegamos o primeiroisActiveviajq.POST /accounts {address, password}— cria a conta. Address éanon<12-random-chars>@<domain>; password é 24 chars[a-z0-9]. Retries até 5x em HTTP 422 (colisão de address aleatoriamente).POST /token {address, password}— autentica e retorna JWT. Salvamos no.anon-maildentro do perfil.
Arquivo: anonymous-mail.sh, função provision_fresh().
LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom 2>/dev/null | head -c "$n"Tanto address (<12 chars>) quanto password (<24 chars>) vêm de /dev/urandom — entropia de kernel, não $RANDOM do bash (que é cíclico e previsível). LC_ALL=C evita expansão de classes Unicode no tr, garantindo consistência cross-distro.
Arquivo: anonymous-mail.sh, função rand_str().
mail.tm não tem WebSocket público. A solução é loop de polling de GET /messages a cada ANON_MAIL_POLL segundos (default 5; mínimo 2 — limite imposto pelo script pra não estourar rate limit). Default escolhido empiricamente: serviços de signup normalmente entregam e-mail em <10s; com poll 5s, latência média do usuário é ~7s entre disparar e ver no terminal.
Cada iteração compara IDs vistos (SEEN) com IDs retornados; imprime só os novos, em ordem cronológica (mail.tm devolve do mais novo pro mais antigo — invertemos).
Arquivo: anonymous-mail.sh, loop while true; do ... done final.
99% dos signups mandam um número de 4–8 dígitos como código de OTP. Pra evitar o usuário precisar ler o corpo do e-mail manualmente, regexamos:
code="$(printf '%s' "$body $subj" | grep -Eo '[0-9]{4,8}' | head -n1)"Procuramos no subject + text. Pega o primeiro match. Falsos positivos existem (ex: ano "2026" num footer), mas mostramos ao lado do código também ("Código provável: 1234") — usuário valida visualmente.
Arquivo: anonymous-mail.sh, função print_message().
Alguns sites enviam só text/html, sem text/plain. Quando .text vem vazio, fazemos:
body="$(jqr '(.html // []) | join("\n")' \
| sed -e 's/<[^>]*>//g' -e 's/ / /g' -e 's/&/\&/g')"Concatena os fragmentos HTML, remove tags via regex e desescapa entidades comuns. Não é parser HTML — é o suficiente pra extrair texto legível de e-mails transacionais (que tendem a HTML simples), não pra renderizar newsletter complexa.
Arquivo: anonymous-mail.sh, função print_message() (bloco do fallback).
mail.tm expira tokens depois de algumas horas. Detectamos via HTTP 401 no polling, chamamos get_token() (que faz POST /token com address+password salvos), regravamos as creds, e continuamos o loop sem perder mensagens (a próxima iteração re-lista tudo).
Arquivo: anonymous-mail.sh, dentro do while true — if [[ "$RESP_CODE" == "401" ]]; then.
mail.tm rate-limit é 8 req/s. Em 429, esperamos extra 5s antes do próximo poll. Em 5xx ou rede caída (HTTP 000), silenciosamente continuamos — o próximo poll resolve. Não rompemos a sessão por blip de rede.
Arquivo: anonymous-mail.sh, mesmo loop.
Quando o perfil é efêmero (sem KEEP), o cleanup() do mail script faz DELETE /accounts/{id} antes de morrer. A conta deixa de existir no mail.tm. Casa com a filosofia geral: ao fechar o navegador, nada dessa identidade sobrevive.
Quando o perfil é persistente (KEEP=X ou caminho explícito via $1), mantemos a conta — mesma identidade volta na próxima sessão.
Arquivo: anonymous-mail.sh, função cleanup() (condicional if PERSISTENT -eq 0).
Com KEEP, o mail script primeiro tenta load_creds() do .anon-mail do perfil. Se as creds estão lá e o token ainda valida (get_token retorna 200), reutiliza. Se o token expirou e o address ainda existe no mail.tm, renova só o token. Se o address foi deletado pelo mail.tm (acontece após dias de inatividade), cria conta nova com o mesmo padrão.
Arquivo: anonymous-mail.sh, bloco # -------- provisiona ou recarrega --------.
( umask 077
jq -nc --arg address "$ADDRESS" ... > "$CRED_FILE" )umask 077 dentro de subshell garante que .anon-mail é criado com rw------- (mode 600). Sem isso, outros usuários no mesmo sistema poderiam ler o token JWT e drenar sua caixa de entrada.
Arquivo: anonymous-mail.sh, função save_creds().
case "$(uname -s)" in
Linux) GHOST_OS=linux ;;
Darwin) GHOST_OS=macos ;;Depois (só no Linux) lemos /etc/os-release e classificamos ID + ID_LIKE em três famílias: debian, arch, fedora. Distros derivadas (Ubuntu, Pop!_OS, Manjaro, Nobara, etc.) são detectadas via ID_LIKE — o script funciona em qualquer derivativo sem ajuste manual.
Arquivo: lib/platform.sh, funções anon_os() e anon_linux_distro().
anon_pkg_install() {
case "$(anon_pkg_manager)" in
apt) sudo apt install -y "$@" ;;
pacman) sudo pacman -S --noconfirm --needed "$@" ;;
dnf) sudo dnf install -y "$@" ;;
brew) brew install "$@" ;;
esac
}Todos os comandos de instalação/remoção/check passam por essas funções. O install.sh chama anon_pkg_install agnóstico do package manager. Adicionar suporte a uma nova distro = uma linha na tabela.
brew no macOS dispensa sudo (intencional do Homebrew). pacman --needed evita reinstalar pacotes já presentes. apt -y/dnf -y aceitam confirmações automaticamente.
Arquivo: lib/platform.sh, funções anon_pkg_*.
anon_service_enable() {
case "$(anon_os)" in
linux) sudo systemctl enable --now "$1" ;;
macos) brew services start "$1" ;;
esac
}No macOS, brew services start já persiste entre boots — não há "enable" separado, então enable = start. No Linux usamos systemctl enable --now que faz as duas operações de uma vez. Quem chama (install.sh) trata as duas plataformas com a mesma chamada.
Arquivo: lib/platform.sh, funções anon_service_*.
anon_port_open() {
nc -z -w 2 "$1" "$2" >/dev/null 2>&1
}nc -z (zero-I/O port scan) funciona em Linux (netcat-openbsd/openbsd-netcat/nmap-ncat) e macOS (BSD nc). Não usamos /dev/tcp porque o /bin/bash do macOS é 3.2.57 e não tem suporte a /dev/tcp — falharia silenciosamente.
-w 2 é timeout de 2s. Tor responde em <100ms; se demorar 2s, algo está errado e queremos saber rápido.
Arquivo: lib/platform.sh, função anon_port_open().
/bin/bash no macOS é 3.2.57 (de 2007, último Apple-shipped antes do GPL3). Nada de:
mapfile/readarray(bash 4+)${var,,}lowercase expansion (bash 4+)- Associative arrays
declare -A(bash 4+) &>redirect (bash 4+, embora tolerado)
Substituições que usamos:
| Em vez de... | Usamos... |
|---|---|
mapfile -t arr < file |
arr=(); while IFS= read -r l; do arr+=("$l"); done < file |
${var,,} |
printf '%s' "$var" | tr '[:upper:]' '[:lower:]' |
[[ -v VAR ]] |
[[ -n "${VAR:-}" ]] |
read -d '' |
IFS= read -r em loop |
Arquivo: lib/platform.sh (comentários no header explicitam a restrição).
/tmp no Linux, /var/folders/.../T/ no macOS (via $TMPDIR). Hardcoding /tmp quebraria o macOS. Função anon_tmp_prefix() retorna ${TMPDIR:-/tmp} — mktemp -d aceita ambos.
Arquivo: lib/platform.sh, função anon_tmp_prefix().
Tudo que install.sh instala é gravado em ~/.cache/anonymous-browser/installed-pkgs, uma linha por pacote. uninstall.sh lê esse arquivo e só remove o que nós colocamos — nunca o que o usuário já tinha. Se você já tinha curl antes, ele continua depois do uninstall.sh.
Arquivo: install.sh, variável PKG_TRACK_FILE.
pkg:tor
pkg:python3-venv
cask:firefox # legado macOS (não usado atualmente)
flatpak:com.brave... # legado Pop!_OS
wrapper:/home/user/.local/bin/anonymous-browser
O prefixo permite o uninstall.sh dispatchar pra ferramenta certa: brew uninstall --cask, flatpak uninstall --user, rm direto pro wrapper, etc.
Arquivo: install.sh (escrita) + uninstall.sh (leitura por prefixo).
Ubuntu 24.04 (Noble) e Pop!_OS 24.04 fizeram a transição time_t para 64-bit em 32-bit ARMv7, renomeando dezenas de libs com sufixo t64:
libasound2→libasound2t64libgtk-3-0→libgtk-3-0t64
Se você instala libasound2 no Noble, o apt aceita (stub virtual), mas a versão real é libasound2t64. Detectamos qual é o pacote real (não-stub) via apt-cache show ... | grep '^Filename:':
pick_pkg() {
for cand in "$@"; do
if apt-cache show "$cand" 2>/dev/null | grep -q '^Filename:'; then
echo "$cand"; return 0
fi
done
}
LIBASOUND=$(pick_pkg libasound2t64 libasound2)Pega o primeiro candidato com Filename: (pacote real). Funciona em Ubuntu 22.04 (escolhe libasound2) e 24.04 (escolhe libasound2t64).
Arquivo: install.sh, bloco do case debian).
Cada step do install.sh checa antes de agir:
- Pacotes:
anon_pkg_is_installedantes de instalar - Serviço Tor:
anon_service_is_active torantes de enable - Venv:
[[ -d "$VENV" ]]antes de criar - Wrapper:
mkdir -pe overwrite (sempre regenera, sem corromper estado)
Rodar install.sh 10 vezes seguidas é seguro. A segunda execução em diante imprime [=] ("já presente") pra cada step.
Antes de declarar sucesso, install.sh testa Tor com https://check.torproject.org/api/ip (mesmo motivo que §1.5 — ipinfo.io foi removido como primário por ficar Cloudflare-blocked). Se a saída do exit responde com IP válido, marca tor como [+] no resumo final. Se falha, marca [!] mas não aborta — você pode estar atrás de DPI que precisa de bridges, e instalação continua.
Arquivo: install.sh, bloco # -------- 4. validação final --------.
Por default, install.sh cria ~/.local/bin/anonymous-browser apontando pra $SCRIPT_DIR/anonymous.sh (modo clone). Quando rodado via npm (que já forneceu o binário global), o launcher Node seta ANON_SKIP_WRAPPER=1 antes de chamar install.sh, e essa step é pulada — evita dois anonymous-browser no PATH com mesma função.
Arquivo: install.sh, bloco # -------- 4b. wrapper global --------.
npm é a forma mais ubíqua de instalar CLIs globais hoje (mais até que brew ou cargo install — todo dev tem npm). Mas o anonymous-browser é shell + Python. Solução: um shim Node em bin/anonymous-browser.js que apenas orquestra (spawn('bash', [anonScript])). Mantém shell como tecnologia primária; usa Node só pra distribuição.
Arquivo: bin/anonymous-browser.js.
postinstall.js só corrige execbits dos .sh (npm às vezes preserva mode 644 do tarball). Não roda install.sh. Razão: npm i -g frequentemente roda como root (via sudo), e install.sh cria ~/.camoufox-venv — que seria criado em /root por engano. Pior: sudo npm i -g em sistemas onde o usuário não passou --unsafe-perm falha em rodar postinstall scripts complexos.
Solução: na primeira execução de anonymous-browser, se ~/.camoufox-venv não existe, o shim chama install.sh no usuário corrente. Aí sim ele tem $HOME certo e roda sudo interativamente quando necessário.
Arquivo: bin/anonymous-browser.js, bloco if (!fs.existsSync(venv)).
if (process.stdin.isTTY && process.stdout.isTTY) {
const ans = await ask('[anonymous-browser] Quer e-mail temporário descartável? [y/N] ');
...
} else {
process.env.MAIL = '0';
}Em uso humano (terminal), pergunta sobre MAIL. Em scripts (stdin redirecionado de pipe/arquivo), assume MAIL=0 e segue silenciosamente — não trava esperando input que nunca vem.
Arquivo: bin/anonymous-browser.js, função (async () => ...).
for (const s of ['anonymous.sh', 'install.sh', 'new-tor-circuit.sh', 'anonymous-mail.sh']) {
try { fs.chmodSync(path.join(pkgRoot, s), 0o755); } catch (_) {}
}Tarball npm às vezes preserva execbits da source, às vezes não (depende da versão do npm e do registry). Em vez de confiar, o shim faz chmod logo no boot. try/catch ignora EPERM (sistema readonly, etc.).
Arquivo: bin/anonymous-browser.js (logo após requires).
Quando o usuário dá Ctrl+C no anonymous-browser, o sinal precisa chegar ao anonymous.sh (que tem o trap). Implementamos spawn(..., { stdio: 'inherit' }) — o shell filho herda stdin/stdout, e Node propaga sinais. Quando o filho morre por sinal, repassamos:
child.on('exit', (code, signal) => {
if (signal) { process.kill(process.pid, signal); return; }
process.exit(code == null ? 0 : code);
});Sem isso, anonymous-browser retornaria exit 0 mesmo o shell tendo sido killed por SIGTERM — mascara o erro pro shell pai.
Arquivo: bin/anonymous-browser.js, child.on('exit', ...).
Todas as defesas acima cobrem fingerprinting passivo — o que sites veem de você sem cooperar com vendors anti-bot pagos. Existem vetores que esta stack não trata:
A assinatura TLS ClientHello (cipher suites, extensões, ordem) revela "isso é Firefox real" vs "isso é Firefox patched". Camoufox não patcha o stack TLS — a JA3 dele é a de um Firefox normal, mas detectores comparando JA3 entre clientes podem notar. Solução real exige reescrever curl/openssl no nível abaixo do navegador — fora do escopo.
Mesmo princípio: a ordem de frames HTTP/2 que o browser manda na primeira conexão é fingerprintable. Camoufox segue Firefox upstream — coerente com os="linux" e levemente fora se você spoofou os="macos" (Firefox no macOS tem ordem ligeiramente diferente).
Cadência de digitação, padrões de movimento de mouse, scroll velocity — Datadome, Akamai BMP, Kasada usam ML treinado em centenas de milhões de sessões pra distinguir humano de bot. humanize=True melhora vs detector ingênuo; não engana ML maduro.
Cloudflare Bot Management ($120k/ano), Datadome, PerimeterX, Shape (F5), Kasada — esses caras combinam TLS+HTTP/2+behavioral+device-graph. Se você precisa passar por isso, alternativas pagas: GoLogin, Multilogin, AdsPower (eles licenciam fingerprints reais via SDK proprietário). Não é o caso de uso desta stack.
Camoufox upstream não suporta os="ios" nem os="android". Tentar spoofar User-Agent de iPhone sem o resto (touch events, gyroscope, screen pixel ratio, dpr, sensor APIs) seria fingerprint imediatamente detectado como inconsistente. Removemos quaisquer presets mobile do código pra não dar falsa sensação.
Mesmo com block_webrtc=True, browsers modernos opcionalmente revelam IPs de mDNS local (.local addresses) via Network Information API em alguns contextos. Camoufox bloqueia o stack WebRTC inteiro como default, mas se o usuário (ou uma extensão) reativar via about:config, leak volta. Não toque em media.peerconnection.enabled se você se preocupa com isso.
A versão do Firefox que Camoufox spoofa segue o release do upstream Camoufox. Se Mozilla solta Firefox 142 e Camoufox ainda está em 135, seu UA dirá 135 enquanto humanos reais já estão em 142 — sinal fraco mas crescente. Mitigar: rodar python -m camoufox fetch mensalmente (manualmente; o install.sh puxa o latest mas não há auto-update entre rodadas).
Esta stack rotaciona identidade de aplicação (IP, UA, fingerprint). Não protege contra adversário que observa o tráfego TLS ao redor do seu PC (ISP, rede corporativa, MITM com cert raiz instalado). Tor protege metadata de rede; se você precisa de privacidade contra adversário com cert root no seu device, problema é maior que browser fingerprint.
npm i -g anonymous-browserIsso instala um comando anonymous-browser no seu PATH. Na primeira execução, ele dispara install.sh automaticamente — instala Tor + libs nativas via sudo (Linux) ou brew (macOS), cria o venv Python e baixa o binário Camoufox.
A cada execução depois disso, anonymous-browser pergunta se você quer um e-mail temporário descartável (MAIL=1) e abre o browser. Para pular o prompt, exporte MAIL=0 ou MAIL=1 antes.
install.sh detecta S.O. e distro automaticamente. Mesmo comando nas três famílias Linux principais e no macOS:
./install.sh| Família | Distros confirmadas | Package manager |
|---|---|---|
| Debian | Ubuntu, Pop!_OS, Debian, Mint | apt |
| Arch | Arch, Manjaro, EndeavourOS, CachyOS | pacman |
| Fedora | Fedora, Nobara, RHEL, Rocky, AlmaLinux | dnf |
| macOS | macOS 13+ | brew (Homebrew obrigatório) |
Camoufox traz Firefox bundled — não há dependência de navegador do sistema. Em qualquer distro Linux com
tor,python3e libs GTK/X11 básicas, oanonymous.shfunciona.
Linux — usa sudo na primeira execução pro package manager nativo (apt/pacman/dnf) e systemctl.
macOS — requer Homebrew pré-instalado; o install.sh orienta o usuário caso esteja faltando. Não usa sudo (brew dispensa root).
O install.sh é idempotente e fala muito. Ele instala (só o que falta):
tor(proxy SOCKS5 em127.0.0.1:9050) —systemdno Linux,brew servicesno macOS- Libs runtime do Camoufox (nomes diferem por distro:
libgtk-3-0t64no Debian,gtk3no Arch/Fedora, etc.). macOS dispensa — Camoufox usa Firefox Cocoa nativo. - venv Python em
~/.camoufox-venvcomcamoufox[geoip] - binário Camoufox (Firefox patched) + dataset GeoIP (~300 MB)
- valida saída Tor em endpoints Tor-friendly (
check.torproject.org,api.ipify.org)
No fim, imprime um resumo categorizado: [+] instalado agora, [=] já presente, [!] falhou. Se algo está em [!], veja FIXES.md para diagnóstico.
Sem ControlPort 9051, new-tor-circuit.sh cai para um reload do serviço Tor — funciona mas é mais lento e fecha conexões em andamento. Para habilitar a troca rápida de circuito:
- Linux: edite
/etc/tor/torrcadicionandoControlPort 9051+CookieAuthentication 0, depoissudo systemctl restart tor. - macOS:
brew install tordeixa apenastorrc.sample. Crie otorrcprimeiro:cp "$(brew --prefix)/etc/tor/torrc.sample" "$(brew --prefix)/etc/tor/torrc" printf '\nControlPort 9051\nCookieAuthentication 0\n' >> "$(brew --prefix)/etc/tor/torrc" brew services restart tor
Reverter tudo:
./uninstall.shRemove venv, cache do Camoufox (XDG no Linux ou ~/Library/Caches/camoufox no macOS), perfis temporários, e pergunta antes de remover pacotes (só o que foi rastreado em ~/.cache/anonymous-browser/installed-pkgs). Se houver perfis persistentes em ~/.anonymous-browser/profiles/, também pergunta interativamente antes de apagá-los.
./anonymous.sh # pergunta URL interativamente
./anonymous.sh https://site.com/signup # one-liner
./anonymous.sh youtube.com # esquema é opcional, prepende https://Cada execução:
- Detecta S.O. e inicia o Tor se ele estiver parado (
systemctl start torno Linux,brew services start torno macOS). - Força novo circuito Tor (
SIGNAL NEWNYMse ControlPort estiver aberto, senão reload do serviço). - Sorteia OS spoofado (
windows|macos|linux). - Cria perfil descartável em
$TMPDIR/anon-XXXXXX(/tmp/...no Linux,/var/folders/.../anon-...no macOS). - Abre Camoufox com fingerprint coerente + Tor + GPS negado silenciosamente.
- Bloqueia até você fechar o navegador.
- Apaga o perfil no exit (Ctrl+C, X do terminal, X do navegador, kill, crash — tudo).
# padrão: Tor + OS aleatório + perfil descartável
./anonymous.sh https://site.com
# usando VPN própria (Mullvad, ProtonVPN paga, qualquer SOCKS5/HTTP)
PROXY=socks5://10.2.0.1:1080 ./anonymous.sh
# sem proxy (IP real, mas fingerprint trocado) — útil para sites internos
PROXY=none ./anonymous.sh
# força um OS específico (sem aleatório)
ANON_OS=macos ./anonymous.sh
# identidade persistente "trabalho" (cookies + OS fixos entre sessões)
KEEP=trabalho ./anonymous.sh https://gmail.com
# cria identidade nova com OS escolhido manualmente
KEEP=pessoal ANON_OS=windows ./anonymous.sh
# + e-mail descartável: imprime o endereço e mostra os e-mails
# recebidos em tempo real NO MESMO terminal (útil pra código de verificação)
MAIL=1 ./anonymous.sh https://site.com/signup
# e-mail persistente junto da identidade persistente (mesmo endereço sempre)
MAIL=1 KEEP=trabalho ./anonymous.sh https://gmail.com
# se o exit Tor estiver bloqueado pelo Cloudflare do mail.tm, manda só o
# e-mail direto (o navegador continua via Tor):
MAIL=1 ANON_MAIL_PROXY=none ./anonymous.sh https://site.com/signup| Variável | Valores | Efeito |
|---|---|---|
PROXY |
tor (default) | none | socks5://host:port | http://host:port | https://host:port |
Sobrescreve o proxy Tor padrão. none desliga proxy (usa IP real). |
KEEP |
qualquer nome [A-Za-z0-9_-]+ |
Salva o perfil em ~/.anonymous-browser/profiles/<nome>/. OS é fixado na primeira vez. Sem KEEP, o perfil é descartado no fim. |
ANON_OS |
windows | macos | linux (aceita maiúsculas; é normalizado para lowercase) |
Força um OS específico (sem sorteio). Combinado com KEEP, fixa o OS persistente. |
USE_TOR (legado) |
0 |
Alias de PROXY=none. Mantido por compat com docs antigas. |
MAIL |
1 |
Gera um e-mail descartável (mail.tm) e mostra os recebidos em tempo real no mesmo terminal. Usa o mesmo PROXY e o mesmo perfil do navegador. Com KEEP, o endereço persiste entre sessões; sem KEEP, a conta é apagada no exit. |
ANON_MAIL_POLL |
segundos (default 5, mínimo 2) |
Intervalo de checagem da caixa de entrada. |
ANON_MAIL_PROXY |
tor | none | socks5://... | http(s)://... |
Override de proxy só pro e-mail (o navegador segue no PROXY). Use none se o exit Tor estiver bloqueado pelo Cloudflare do mail.tm. |
E-mail descartável (
MAIL=1): o endereço é criado no mail.tm — serviço gratuito, sem API key e sem cadastro (rate limit 8 req/s). Inbox by mail.tm. Como qualquer serviço de e-mail temporário, não use para nada sensível: as mensagens são públicas pra quem souber o endereço. Conta efêmera é deletada ao fechar o navegador / Ctrl+C.
Tor × Cloudflare no mail.tm: o
MAIL=1roteia as chamadas pelo mesmo Tor do navegador (consistência de IP). Exit nodes Tor às vezes levam desafio do Cloudflare e a criação da caixa falha — oanonymous-mail.shavisa e segue sem derrubar o navegador. Soluções:./new-tor-circuit.sh(troca o exit) ouMAIL=1 ANON_MAIL_PROXY=none ./anonymous.sh ...(e-mail direto, navegador ainda via Tor).
Schemes de proxy aceitos:
socks5://,http://,https://. O Playwright (engine do Camoufox) não suportasocks4://oficialmente — usarsocks4://resulta em erro do Camoufox.
Privacidade com
PROXY=none: quando você desliga o proxy, oanonymous.shtambém desativageoipautomaticamente. Sem isso, Camoufox tentaria buscar seu IP real emapi.ipify.org(ou fallback) para casar locale/timezone — o que vazaria o IP que você quer esconder. Trade-off: semgeoip, locale/timezone do Firefox podem não bater com sua região, mas seu IP real fica em casa.
Perfil persistente em paralelo: Firefox usa um arquivo
parent.lockdentro douser_data_dir. RodarKEEP=foo ./anonymous.shduas vezes simultaneamente faz a segunda instância travar com timeout. Use nomes diferentes (KEEP=foo+KEEP=bar) para rodar em paralelo.
./new-tor-circuit.sh— força IP novo entre execuções. Já é chamado peloanonymous.shquando o proxy é Tor. Pra rodar standalone, abraControlPort 9051no torrc (caminho depende do S.O. — Linux:/etc/tor/torrc; macOS:$(brew --prefix)/etc/tor/torrc). Veja a seção "Configuração do ControlPort do Tor" acima../anonymous-mail.sh— e-mail descartável com leitura em tempo real, standalone (sem abrir navegador). Imprime o endereço e fica mostrando os e-mails recebidos. AceitaPROXY,ANON_MAIL_PROXY,ANON_MAIL_POLLeKEEP(endereço persistente, mesmo padrão de perfil doanonymous.sh). Já é disparado automaticamente porMAIL=1 ./anonymous.sh. Inbox by mail.tm.
Abre essas URLs dentro da janela aberta pelo anonymous.sh:
| Site | O que checar |
|---|---|
| check.torproject.org | IP é exit Tor (a badge verde "Congratulations" só aparece no Tor Browser oficial; aqui o que importa é o IP retornado bater com o de saída) |
| ipinfo.io/json | IP, país, ASN do exit |
| browserleaks.com/javascript | navigator.platform, screen, UA — devem casar com OS sorteado |
| browserleaks.com/webgl | UNMASKED_VENDOR/RENDERER — Camoufox spoofa coerente |
| browserleaks.com/fonts | Lista de fontes do OS spoofado, não do seu Linux real |
| browserleaks.com/geo | "Permission denied" — GPS negado sem prompt |
| abrahamjuliot.github.io/creepjs | Trust Score >70% e zero "lies" — métrica de ouro |
| amiunique.org/fingerprint | Entropia / unicidade |
Validar IP no terminal:
curl -s --socks5-hostname 127.0.0.1:9050 https://check.torproject.org/api/ip
# {"IsTor":true,"IP":"107.189.5.121"}anonymous-browser (este repo) |
Tor Browser oficial | |
|---|---|---|
| Engine | Camoufox (Firefox patched em C++) | Firefox ESR + patches Tor |
| Filosofia | Você finge ser outro device | Você se uniformiza com todo mundo |
| Troca UA | ✅ | n/a (todos têm o mesmo) |
Troca navigator.platform |
✅ | ✅ (mas todo mundo tem o mesmo) |
| Troca WebGL/canvas/audio/fonts | ✅ coerente via BrowserForge | ✅ via resistFingerprinting (zeros) |
Client Hints (Sec-CH-UA-*) |
✅ | ✅ |
| Geo/timezone casados com IP | ✅ (geoip=True) |
uniforme |
| Proxy customizado (VPN, etc.) | ✅ (PROXY=socks5://...) |
❌ (só Tor) |
| Identidade persistente entre sessões | ✅ (KEEP=nome) |
❌ (sempre descartável) |
| Perfis mobile | ❌ (Camoufox não suporta) | ❌ |
| Passa em CreepJS | ✅ Trust >70% típico | ✅ Trust ~80% (homogêneo) |
| Dependências | apt + venv (~300 MB) | bundle pronto |
Use anonymous.sh quando quiser identidade trocada (parecer outra pessoa específica, com cookies/sessão controláveis). Use Tor Browser quando quiser anonimato uniforme (se misturar com a multidão, sem variação entre você e os outros usuários).
anonymous-browser/
├── README.md # este arquivo
├── FIXES.md # histórico de bugs corrigidos (todos fechados)
├── LICENSE # MIT
├── logo.jpg # mascote (fantasma minimalista, mono)
├── .gitignore
├── install.sh # auto-detecta S.O. + distro Linux (Debian/Arch/Fedora);
│ # instala Tor, libs Camoufox, venv Python; resumo [+]/[=]/[!] no fim
├── uninstall.sh # remove venv/cache/perfis; pergunta antes de remover pacotes;
│ # também pergunta antes de apagar perfis persistentes em ~/.anonymous-browser/
├── anonymous.sh # ★ super-comando: PROXY/KEEP/ANON_OS via env, Camoufox+Tor por default
├── new-tor-circuit.sh # força SIGNAL NEWNYM (ControlPort 9051) ou reload do serviço
├── anonymous-mail.sh # e-mail descartável (mail.tm) + leitura em tempo real no terminal
└── lib/platform.sh # detecção de S.O. + distro + dispatch de package manager
# (apt/pacman/dnf/brew); bash 3.2 portable
# estado (não versionado):
~/.anonymous-browser/profiles/ # perfis persistentes criados por KEEP=nome
~/.camoufox-venv/ # venv com Camoufox + BrowserForge + GeoIP
~/.cache/anonymous-browser/ # track-file de pacotes instalados pelo install.sh
- Não é silver bullet. Anti-bot enterprise (Cloudflare BM, DataDome) detecta Camoufox via TLS/HTTP-2 fingerprint. Esta stack mira tracking publicitário e cadastros normais — não nações-estado, não Akamai-fronted login flows.
- Tor é lento. Em média 5–15s pra primeira requisição. Cloudflare desafia exit nodes. Se um site bloquear, troque por VPN própria:
PROXY=socks5://seu-vpn:1080 ./anonymous.sh. - User-Agents envelhecem. O Camoufox/BrowserForge atualizam UAs automaticamente. Pra puxar o dataset mais recente:
source ~/.camoufox-venv/bin/activate && python -m camoufox fetch. - Mullvad Browser e Tor Browser homogeneízam, não personificam. Útil pra ler anonimamente, inútil pra cadastrar como "outro alguém".
- WebRTC permanece bloqueado pelo Camoufox (
block_webrtc=True) mesmo comPROXY=none, mas DNS lookups vão pelo seu resolver local — sua máquina aparece como Linux normal para o ISP nesse modo. - Camoufox não emula iPhone/Android. Documentação oficial só aceita
os="windows"|"macos"|"linux". Pra mobile coerente, alternativas pagas: GoLogin, Multilogin, AdsPower.
Firefox deixa um parent.lock (e/ou .parentlock) dentro do user_data_dir. Se você matou o processo no kill -9 ou o sistema travou, o lock fica órfão e a próxima execução fica esperando.
# checar
ls -la ~/.anonymous-browser/profiles/<nome>/ | grep -i lock
# limpar (com o anonymous.sh fechado)
rm -f ~/.anonymous-browser/profiles/<nome>/parent.lock \
~/.anonymous-browser/profiles/<nome>/.parentlock# Linux
sudo systemctl status tor
sudo systemctl restart tor
journalctl -u tor@default | tail -20
# macOS
brew services info tor
brew services restart torSe o ISP está bloqueando Tor, use PROXY=socks5://seu-vpn:1080 ./anonymous.sh com uma VPN.
Confira os schemes aceitos: tor, none, socks5://, http://, https://. socks4:// não é suportado pelo Playwright.
Significa que o proxy custom (VPN/SOCKS) não está respondendo. Teste manualmente:
curl -s --socks5-hostname <vpn-host>:<port> https://api.ipify.orgSe não retorna IP, o proxy está fora. Volte ao Tor (PROXY=tor) ou conserte o VPN.
Nenhum em aberto até 12/05/2026. Os 3 bugs originais (teste de Tor com ipinfo.io, ausência de Chromium em Pop!_OS sem snap, TypeError do Camoufox 0.4.11) estão todos fechados — histórico técnico completo em FIXES.md.
Se algo quebrar depois de uma atualização do Camoufox, Firefox ou Tor: abra issue no GitHub com o stacktrace e o resumo do ./install.sh.
Privacy não é sobre esconder. É sobre escolher o que mostrar, pra quem, e quando. Sites que coletam fingerprint sem te perguntar quebraram esse contrato primeiro. Esta ferramenta é uma resposta proporcional.
Não promove fraude. Não burla mecanismos de pagamento. Não invade sistemas. Faz uma coisa só: te devolve o controle de qual identidade seu browser apresenta ao internet.
A legalidade depende de jurisdição e de termos-de-uso do destino. Em quase todos os lugares civilizados, trocar UA, IP e fingerprint é permitido. Burlar ToS é cinza. Fraude documental é crime — em qualquer lugar, com ou sem esta ferramenta. Você é o operador, você assume as consequências. Esta linha não tem como ser apagada por boa intenção do dev.
- Tor Project — o original
- Camoufox — Firefox C++ patched, faz o trabalho pesado
- BrowserForge — fingerprints coerentes
- EFF Privacy Badger, uBlock Origin, Mullvad VPN
- Cypherpunks Manifesto, Crypto Anarchist Manifesto
- EFF Cover Your Tracks — entenda o quanto você vaza
MIT. Faça fork. Faça merge. Mande PR. Mande issue. Se algo quebrar com uma atualização do Camoufox/Firefox, abra issue com o stacktrace — esta stack vai precisar de manutenção contínua porque o lado adversário também não dorme.
"If privacy is outlawed, only outlaws will have privacy." — Phil Zimmermann (criador do PGP)
