Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
stop-bots — Automatize o bloqueio de bots maliciosos que tentam acessar seu servidor | Kitploit
Ferramentas/GitHubGitHub/ivankovic/stop-bots
Ferramentas DefensivasAuditoria de ConfiguraçãoColeta de InformaçõesSegurança WebSegurança de RedeUtilitários e FrameworksDetecção de IntrusãoAnti-BotAnálise de Logs
GitHubivankovic/stop-bots

stop-bots

Automatize o bloqueio de bots maliciosos que tentam acessar seu servidor

12há 1 diaAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Ver Repositório
Compartilhar

Stop Bots

CI crates.io Coverage MSRV License: AGPL v3+

Uma TUI, uma interface web e uma CLI que ajudam você a configurar seu servidor para bloquear bots maliciosos sem se esconder atrás de um CDN.

Funciona em conjunto com o NGINX e seu firewall existente (iptables ou nftables), em dois planos separados:

  • Configuração do NGINX. - Classifica bots conhecidos por categoria (scanners, mecanismos de busca, rastreadores de IA) e os bloqueia ou permite injetando uma regra nas configurações do seu site. Ele analisa o log do NGINX para detectar bots dinamicamente e bloqueá-los mesmo que nenhum conjunto de regras os rastreie ainda.
  • Um script de firewall. - Bloqueie países inteiros, faixas de IP de datacenters, faixas de IP de bots conhecidos ou qualquer endereço IP que tente fazer login no seu servidor sem sucesso repetidamente.

O painel do stop-bots: categorias de bots em todo o sistema, geobloqueio, detectores automáticos e o cron interno

Baixar ferramenta

O aplicativo faz o possível para não bloquear seu acesso ao servidor, mas você o usa por sua conta e risco. E observe que ele é licenciado sob AGPL, então se você o estiver usando comercialmente, certifique-se de obedecer à letra da licença.

Instalação

Do crates.io:``` cargo install stop-bots

root@kitploit:~
Ou compile a partir de um checkout:```
cargo install --path .

Um binário Linux x86_64 pré-compilado está disponível nas releases do GitHub.

Dependências

Requer Rust 1.88 ou mais recente para compilar. Apenas Linux na prática: ele invoca systemctl, nginx -t e nft/iptables, então embora compile em outros lugares, não será muito útil lá.

Uso

Execute o binário sem argumentos para iniciar a TUI, stop-bots web para as mesmas telas em um navegador (veja A interface web), ou veja stop-bots --help para a lista completa de subcomandos da CLI. A TUI e a CLI podem ser usadas juntas. Configure tudo na TUI e depois use a CLI em um crontab para manter as regras atualizadas.

Você pode sair do aplicativo, ou voltar de um popup/submenu, com 'q' ou Escape.

Tema

Você pode alternar entre o tema escuro e claro com 't'. O aplicativo tentará detectar automaticamente o tema, mas para algumas combinações de terminal e multiplexador não há informação suficiente disponível para fazer a escolha correta.

Telas

1–4 (ou d/b/s/p) saltam diretamente para uma tela; Esquerda/Direita, ou seus aliases vim h/l, percorrem-nas; ? alterna uma referência completa de atalhos a qualquer momento, e : abre uma paleta de comandos listando cada ação por nome. Tab / Shift+Tab sempre se movem entre os painéis da tela atual, nunca entre telas.

O Dashboard possui tudo que acaba no script de firewall; as configurações de Site possuem tudo que acaba na configuração do NGINX. Essa divisão decide onde cada configuração vive.

  • Dashboard (a tela padrão): padrões de categoria para todo o sistema (Scanners / Search Bots / AI Bots — Permitidos ou Bloqueados); geo-bloqueio para todo o host (bloquear ou permitir lista de países específicos); um painel "Bloqueio automático" com um interruptor liga/desliga para cada detector e cada blocklist de terceiros; um painel "Script de firewall" (quantas regras uma renderização escreveria, se o script em disco está desatualizado, e os sites e listas de bots a partir dos quais ele é renderizado); um painel "Agendado" mostrando os trabalhos do cron interno e quando foram executados pela última vez (com um spinner ao lado de qualquer trabalho em execução em segundo plano); e um Log do que o aplicativo fez por último. Uma faixa de status sob as abas mostra as verificações de integridade do host em cada tela. Up/Down fluem entre as três listas; m alterna o modo geo. Pressione F para renderizar as regras de firewall atuais em um script — o popup também tem um interruptor "aplicar após escrever" (Space) para realmente aplicá-lo imediatamente, em vez de aplicá-lo manualmente depois. Mais três teclas agem sobre todo o host: u baixa todas as listas, a aplica ambos os planos (NGINX, depois o firewall), e w coloca este console atrás do NGINX — os mesmos três que o navegador tem como botões e um painel.
  • Configurações de bots: lista cada fonte de lista de bots conhecida (com uma ação para atualizá-la) e cada bot individual, pesquisável por nome, com uma substituição por bot (Permitido / Bloqueado / seguir o padrão da categoria).
  • Configurações de site: um painel "Configurações do NGINX" (Tab para focá-lo) contendo as escolhas para todo o host que moldam a configuração gerada — o que uma requisição bloqueada recebe de volta (veja abaixo), se deve servir um robots.txt gerado, e limitação de taxa — acima de cada site NGINX descoberto em disco, cada um com um status ao vivo "atualizado / desatualizado / não encontrado" e ações para aplicar a política atual a um site ou a todos eles. Alterar qualquer uma dessas configurações muda cada site aplicado para STALE, que é o seu sinal para reaplicar. Abrir um site permite substituir sua política de categoria/bot, ativar qualquer uma das seis regras de forma de requisição, e listar caminhos isentos de bloqueio.
  • Proteção Dinâmica: uma visão ao vivo e acionável do que está atingindo o servidor no momento — "Top IPs tentando conexão SSH" e "Top User Agents", cada um classificado por contagem e marcado NOT BLOCKED/BLOCKED (mostrado em vermelho). Tab/Shift+Tab alternam a qual dos dois painéis Up/Down se aplicam; f alterna um filtro compartilhado (todos / apenas não bloqueados / apenas bloqueados); Enter bloqueia a linha NOT BLOCKED selecionada, ou desbloqueia se já estiver BLOCKED. i inspeciona o endereço selecionado: quais dos feeds de reputação o listam, se ele está dentro de um intervalo de crawler publicado (que é o que separa um Googlebot real de um user agent que apenas diz ser), a qual país pertence, e como quais contas ele tentou fazer login. Tudo isso a partir de listas que este host já baixou — não há consulta de DNS reverso ou whois aqui, porque um registro PTR é escrito por quem detém o endereço e seria texto fornecido pelo atacante que se lê como autoritativo.
  • Ajuda: a referência completa de atalhos.

Configurações de bots, onde cada fonte de lista e cada bot individual vive:

Configurações de bots: as três fontes de lista de bots com suas contagens, e uma pesquisa correspondendo a cinco bots entre categorias

Configurações de site, onde as escolhas do NGINX para todo o host ficam acima de cada site encontrado em disco:

Configurações de site: resposta de bloqueio, robots.txt e limitação de taxa, acima de dois sites marcados UP TO DATE e STALE

Proteção Dinâmica, a visão ao vivo do que está atingindo o servidor agora:

Proteção Dinâmica: logins SSH falhados e principais user agents, cada linha marcada BLOCKED, BLOCKLIST ou NOT BLOCKED

Contra o que ele realmente protege

Usando a configuração do NGINX

  • Bots conhecidos, por categoria (scanner / mecanismo de busca / crawler de IA), obtidos de ArcJet's Well-Known Bots, ai.robots.txt e a lista NGINX Ultimate Bad Bot Blocker. Bloquear uma categoria injeta uma regra if ($http_user_agent ...) na configuração NGINX de cada site (apply-blocks / a/A das configurações de Site).

  • Muitas requisições, via limitação de taxa do próprio NGINX. Diferente de tudo mais aqui, isso é aplicado pelo NGINX no momento da requisição em vez de analisar um log depois. Desligado por padrão: um limite ajustado para o site errado afasta visitantes reais.

  • Educadamente, primeiro — um robots.txt gerado opcional listando cada bot que você está bloqueando, para os crawlers que o respeitam, mais o caminho honeypot abaixo. Desligado por padrão, porque substitui o que seu site serve em /robots.txt hoje.

  • Exceto onde você disser o contrário — isenções de caminho por site, para que você possa bloquear crawlers de IA em todos os lugares exceto /blog.

  • Requisições que não parecem um navegador, por site. Seis regras independentes, cada uma com seu próprio interruptor e cada uma desligada por padrão — um interruptor por regra para que, se algo seu parar de funcionar, você possa identificar qual regra causou:

    Duas salvaguardas se aplicam a todas elas, e são aplicadas em vez de deixadas para você:

    • As duas regras dependentes de TLS só são escritas em blocos server HTTPS. Navegadores não fazem HTTP/2 sem TLS, então em um bloco listen 80 simples toda requisição é HTTP/1.1 — incluindo o redirecionamento que um navegador faz a caminho do HTTPS. Seus blocos de porta 80 e porta 443 geralmente compartilham um server_name, então a configuração alcança ambos; apenas o de TLS recebe essas regras. As regras de forma de cabeçalho funcionam sobre HTTP simples e são escritas em ambos.
    • /.well-known/ é sempre isento assim que qualquer regra está ativada. É onde o Let's Encrypt busca seu desafio HTTP-01, sobre HTTP/1.1 sem Accept e frequentemente sem User-Agent — sem a isenção seu certificado para de renovar semanas depois.

O que uma requisição bloqueada realmente recebe

Uma escolha para todo o host, nas configurações de Site. Estes não são códigos de status intercambiáveis — cada um diz algo diferente, e a diferença importa mais para os clientes que você não pretendia capturar:

OpçãoPara que serve
403 Forbidden (padrão)diz que o bloqueio foi deliberado; o único sobre o qual um humano capturado por engano pode agir
404 Not Foundesconde que algo foi bloqueado
410 Gonepede a crawlers bem-comportados que descartem a URL para sempre — prefira isto ao 403 quando você está afastando crawlers em vez de atacantes
429 Too Many Requestsdiz a um cliente educado para recuar e tentar novamente
418 I'm a teapota piada da RFC 2324. Funciona; só não é registrado pela IANA, e o NGINX o envia com corpo vazio
444 close connectionnenhuma resposta; mais barato, mas indistinguível do servidor estar fora do ar
Tarpitresponde 403 mas goteja o corpo a um byte por segundo, então o cliente espera em vez de seguir em frente

O tarpit é a opção mais gentil para um falso positivo — um cliente capturado por engano é desacelerado, não recusado — e a mais severa em custo para um bot, cuja conexão fica ociosa. Duas coisas a saber antes de escolhê-lo: ele mantém uma das suas conexões de worker durante todo o tempo também, então uma enxurrada de clientes em tarpit compete com visitantes reais por worker_connections; e quanto tempo ele realmente dura depende de como o NGINX escolhe escrever um corpo de erro pequeno, o que é anotado no TODO.md como precisando de verificação contra um servidor real.

Dos seus logs, automaticamente

Cada um destes é um interruptor independente no painel "Bloqueio automático" do Dashboard, e cada um adiciona um bloqueio de firewall temporário que expira por conta própria e é readicionado se o comportamento continuar.

Eles rodam em um temporizador interno que relê seus logs de acesso SSH e NGINX a cada minuto — mas apenas enquanto a TUI ou a interface web estiver rodando. Qualquer uma delas mantém o mesmo agendamento, no mesmo banco de dados, então deixar a interface web ativa é suficiente; nada é detectado quando nenhuma está rodando. Para um servidor sem nenhum processo stop-bots nele, veja Desassistido, via cron abaixo.

  • Scanners de SSH e web: IPs com uma pilha de logins SSH falhados, ou muitos caminhos distintos com 404. Nunca um IP com um login SSH bem-sucedido recente, ou um dentro do intervalo de IP publicado de um crawler conhecido.
  • Crawlers forjados: qualquer coisa alegando ser Googlebot, Bingbot ou GPTBot de um endereço que o próprio operador daquele crawler não publica. O disfarce comum mais barato que existe, e as listas CIDR publicadas resolvem isso. Inerte até que essas listas tenham sido realmente obtidas.
  • Sondagem por segredos expostos: uma única requisição para /.env, /.git/config, /wp-config.php e similares é conclusiva por si só, então isso não precisa de limiar. A lista embutida deliberadamente deixa de fora caminhos que são legítimos em algum lugar — /wp-login.php, /wp-admin/, /xmlrpc.php, /phpmyadmin — já que bloquear seu próprio administrador seria pior do que perder um scanner que o detector de 404 captura de qualquer forma. Adicione os seus com set-probe-paths.
  • Honeypot: um caminho publicado apenas como Disallow: no robots.txt gerado e linkado em lugar nenhum. Alcançá-lo significa ignorar o robots.txt, o que nada legítimo faz por acidente — o sinal mais forte aqui, e o bloqueio mais longo. Precisa da geração de robots.txt ativada para funcionar.

Mais três olham como um cliente se comporta em vez do que ele pede. Todos os três estão desligados por padrão, porque cada um tem um falso positivo que não pode descartar sozinho — e todos os três isentam crawlers de mecanismos de busca verificados, que de outra forma corresponderiam a todos eles:

  • Não busca nenhum recurso: muitas páginas distintas e nem uma folha de estilo, script ou imagem. Navegadores carregam o que acompanha uma página. Não captura um cliente de API (ele conta caminhos distintos, e um cliente de API acessa poucos) ou um visitante recorrente bem cacheado (um 304 conta como um recurso buscado). Não pode ajudar em um site que não serve nenhum recurso — uma API JSON pura.
  • User agent rotativo: várias identidades de um endereço. Enfraquecido consideravelmente por NAT: um gateway de operadora, campus ou escritório apresenta muitos navegadores reais em um IP, e sem análise de timestamp não há como distinguir isso de um scraper alternando agents.
  • Rastreia sem referer: muitas páginas profundas distintas, nunca um Referer. Enfraquecido por Referrer-Policy: no-referrer e ferramentas de privacidade; o limiar de caminhos distintos é o que o torna utilizável.

Por endereço

  • Países inteiros, via listas CIDR agregadas do IPdeny — bloqueie países específicos, ou mude para o modo de lista de permissões e bloqueie todo o resto.
  • Endereços conhecidos como maliciosos, via listas de terceiros: FireHOL nível 1, nós de saída Tor e blocklist.de. Todos desligados por padrão.
  • Provedores de hospedagem inteiros: AWS, Google Cloud e DigitalOcean publicam seu espaço de endereços, e visitantes residenciais não navegam a partir dele. Estes são instrumentos contundentes e rotulados como tal — eles bloqueiam todo visitante hospedado lá, incluindo endpoints de VPN, saída corporativa e clientes de API, não apenas bots. Desligados por padrão, com um aviso quando você ativa um.
  • Endereços vizinhos, opcionalmente: quando vários endereços em um único /24 IPv4 são sinalizados na mesma passagem, bloqueie o /24. Desligado por padrão — bloquear 256 endereços porque três se comportaram mal é dano colateral por design. (IPv6 é diferente e não precisa de interruptor: uma detecção sempre bloqueia o /64, porque um /64 é uma LAN, a mesma coisa que um único endereço IPv4 representa. Bloquear o único endereço que um atacante IPv6 usou não pararia nada — eles têm 2^64 a mais.)
  • Qualquer outra coisa, manualmente — adicione uma regra de permissão ou bloqueio de IP/CIDR diretamente, ou use a tela de Proteção Dinâmica para bloquear permanentemente um IP ou user agent específico que você detectou antes que ele cruze qualquer limiar automático.

Está realmente funcionando?

Tudo acima é gerado. Se algo disso está em vigor é uma questão separada, e stop-bots status é o que responde a ela:``` stop-bots status

root@kitploit:~
Sete verificações, e a primeira é a que vale a pena ter: as regras geradas
estão realmente no kernel, ou apenas no disco? Um host real ficou em execução por três semanas com
48.860 regras de drop em `/etc/stop-bots/firewall.nft` e um conjunto de regras vazio,
porque escrever o script e carregá-lo são dois passos e nada tinha alguma vez
olhado para o segundo.

O resto: o conjunto de regras sobreviverá a um reboot (`nftables.service` ativado?), o
script ainda corresponde às regras, os blocos NGINX estão aplicados, o serviço de consola
está a executar o binário que nomeia, há espaço para a base de dados, e os
detetores conseguem ler os seus logs.

Sai com código diferente de zero se algo for **CRITICAL**, por isso funciona como uma verificação de
monitorização. `--quiet` imprime apenas o que precisa de atenção, que é a forma para cron:```
0 * * * * /usr/local/bin/stop-bots status --quiet

Uma verificação que não pôde ser executada — nft list precisa de root — reporta UNKNOWN, nunca OK. Uma verificação de integridade que diz que está tudo bem porque não conseguiu olhar é pior do que nenhuma, porque é acreditada.

O mesmo relatório está no Dashboard tanto no console quanto na TUI, obtido a cada hora pelo cron interno em vez de a cada renderização: nft list num grande conjunto de regras são megabytes de texto.

Nada acontece sem você

Toda decisão de firewall acima é gerada, nunca aplicada automaticamente: render-firewall (ou a tecla f do Dashboard) escreve um script iptables ou nftables para você revisar e aplicar você mesmo, e recusa-se a escrever um que bloquearia uma sessão SSH atualmente conectada.

Três coisas podem aplicá-lo para você, e todas as três precisam que você peça: o popup de renderização da TUI ("aplicar após escrever") ou sua tecla a, o painel de firewall do console web ("executar após escrever") ou seu botão "Aplicar tudo", e batch --apply a partir de um crontab que você escreveu — veja Desassistido, a partir do cron. Nenhum deles é um efeito colateral de nada automático: o cron interno renderiza o script e nunca o executa.

O mesmo se aplica ao lado do NGINX: alterar uma configuração só altera o que seria escrito. As configurações do site mostram cada site como STALE até você aplicar.

Desligar um detector nunca remove os bloqueios que ele já adicionou — esses expiram por conta própria. "Parar de detectar" e "desfazer o que foi detectado" são deliberadamente separados; o segundo é a tela de Proteção Dinâmica ou remove-firewall-rule.

Há também uma contagem simples de logs de acesso, independente do bloqueio: record-access-stats / list-access-stats contam com que frequência cada user agent aparece em requisições bem-sucedidas (não-erro), para que você possa ver quem está realmente visitando além de quem está sendo bloqueado.

Desassistido, a partir do cron

stop-bots batch é uma passagem por tudo o que a TUI faz manualmente: atualizar cada lista, escanear os logs, escrever as regras de bloqueio do NGINX e o script de firewall.```

One full pass a night. Refreshes the lists, scans the logs, applies both.

0 4 * * * root /usr/local/bin/stop-bots batch --apply --ssh-log /var/log/auth.log

And detection every ten minutes, without re-downloading lists that change weekly.

*/10 * * * * root /usr/local/bin/stop-bots batch --apply --no-fetch --ssh-log /var/log/auth.log

root@kitploit:~
Ele não diz nada quando tudo funcionou, então uma execução noturna saudável não te envia email. Um passo falhado imprime para stderr e define um estado de saída não-zero, que é o que faz o cron avisar-te sobre isso. Executa-o uma vez manualmente com `--verbose` primeiro — isso imprime uma linha por passo, e é a forma mais fácil de ver o que ele está realmente a fazer.

**`--apply` é o que faz com que ele imponha algo.** Sem ele, o `batch` escreve a configuração do NGINX e o script da firewall e para: a configuração não faz nada até um reload, um script não faz nada até ser executado. Esse é o padrão deste projeto em todo o lado, e continua a ser o padrão aqui.

O `batch` e um front-end de longa duração coexistem em segurança. A TUI, a UI web e o `batch` registam todos o que fizeram através das mesmas chaves na mesma base de dados, por isso quem chegar primeiro a uma tarefa fá-la e os outros descobrem que já não está devida — não obténs duas passagens de deteção, e o painel "Scheduled tasks" do Dashboard mostra o que realmente aconteceu em vez de afirmar que está tudo em atraso. Se já deixas a UI web a correr, a entrada noturna do `batch` é um cinto e suspensórios em vez de um requisito; se não deixas, é a única coisa que mantém a deteção atualizada.

**Com `--apply`, a proteção contra bloqueio de SSH pode recusar — e recusar significa que nada é aplicado.** Ela recusa se as regras bloquearem um cliente que está ligado neste momento, *e* se nenhum log de SSH puder ser lido de todo, porque então a verificação não pôde ser executada. O `render-firewall` interativo apenas imprime uma nota nesse segundo caso, partindo do princípio de que há um humano a vigiar o terminal; a partir do cron não há ninguém. **Passa `--ssh-log` explicitamente**: o cron corre como root, por isso `/var/log/auth.log` normalmente lê-se bem, mas num host apenas com journald o `journalctl` sob cron pode voltar vazio, que é exatamente o caso em que ele recusa. O `--force` sobrepõe-se à proteção se for mesmo isso que queres.

Um passo a falhar nunca para os outros, e as metades do NGINX e da firewall são independentes — um reload do NGINX falhado ainda deixa a firewall aplicada, e vice-versa.

O `batch` regista cada passo contra o mesmo agendamento que o cron interno da TUI usa, por isso os dois concordam sobre o que já foi executado em vez de ambos o fazerem, e o painel "Scheduled tasks" do Dashboard mostra o que o teu cron real fez.

# A UI web

O `stop-bots web` serve os mesmos cinco ecrãs num navegador.```
stop-bots web

Ele vincula 127.0.0.1:8787 — acessível apenas a partir dessa máquina — e imprime uma palavra-passe gerada uma vez, na primeira execução. Acede-lhe a partir do teu portátil através de um túnel SSH:``` ssh -L 8787:127.0.0.1:8787 your-server

root@kitploit:~
então abra <http://127.0.0.1:8787/>.

![O painel do console web: chips de saúde e os dois botões de host inteiro no cabeçalho, política, geo-bloqueio e feeds de terceiros em uma coluna, bloqueio automático e tarefas agendadas na outra](https://assets.kitploit.com/production/public/readmes/55148/73bbcc92f0f3d2c9d0586bd71ad18f1b4d582fa59824b4f5e3c97e08575f5070/bb45db648f6a59192f56b1e14a019f50f0816bff651766316c377cbe79f700b6-display-v1.webp)

O console segue a configuração de tema claro ou escuro do sistema operacional, com um botão de alternância no
cabeçalho; as capturas de tela da TUI acima são do tema escuro, estas do claro. As teclas que a
TUI usa também funcionam aqui: `1`–`4` alternam entre telas, `/` foca a caixa de pesquisa, `?` abre a Ajuda.

![A página de Proteção Dinâmica do console web: logins SSH falhados e principais user agents, cada um com uma barra de contagem e uma etiqueta de estado, e um botão de bloquear ou desbloquear por linha](https://assets.kitploit.com/production/public/readmes/55148/090d4d2151eb00a69781c44351abe10f268d8031816199b9aeb5b4d2cddfc5f5/52a05387d1227288e7f45ece3c33e4af17957d8e9e73fb7c0213d64c49dc7419-display-v1.webp)

Três ações de host inteiro ficam no cabeçalho, no navegador como botões e na TUI
como teclas individuais:

- **Atualizar tudo** (`u`) baixa todas as listas de bots, todos os intervalos de IP de crawlers, todos os
  feeds de reputação *habilitados* e todos os países *selecionados* — o mesmo conjunto que `stop-bots batch`
  busca, do mesmo plano. A falha de uma fonte não impede as restantes, e nada é
  aplicado até que algo o faça.
- **Aplicar tudo** (`a`) escreve e recarrega a configuração do NGINX, depois escreve e executa o
  script de firewall. Os dois planos são independentes: seja qual for que falhe, o outro ainda tem
  a sua vez, porque um host meio aplicado é melhor do que um onde um erro de sintaxe do NGINX também deixou
  o firewall desatualizado.
- **Acesso Web** (`w`) configura o NGINX para servir o próprio console — consulte
  [Por trás do NGINX](#behind-nginx-a-subdomain-or-a-path-prefix).

## Como serviço (Debian)```
sudo stop-bots install web

Grava /etc/systemd/system/stop-bots-web.service, cria /var/lib/stop-bots (0700 — contém o hash da palavra-passe da consola) e /etc/stop-bots, gera uma palavra-passe se não existir nenhuma, e ativa e inicia a unit.

--dry-run imprime todo o plano e não altera nada. Este é o único comando do projeto que inicia um daemon, por isso comece por aí. --prefix <dir> escreve a mesma árvore num local que pode ler sem root. Se a unit já existir e a tiver editado, o instalador para e avisa, em vez de substituir a sua edição; --force se era isso que pretendia.

O serviço corre como root, porque a consola reescreve /etc/nginx, escreve o script da firewall, e executa nginx -t e systemctl reload nginx. Não há uma separação sem privilégios que mantenha o conjunto de funcionalidades intacto. A unit inclui o hardening que sobrevive a esse requisito e um comentário a indicar qual hardening foi omitido e porquê.

O endereço de bind, a allowlist de hosts e o prefixo de caminho estão deliberadamente fora da unit — o servidor em execução volta a lê-los da base de dados, por isso colocá-los em ExecStart dar-lhes-ia duas fontes de verdade. Altere-os com stop-bots web --save ... e reinicie.

Uma coisa muda quando isto corre como root: a tarefa diária RenderFirewall do cron interno pode agora escrever /etc/stop-bots/firewall.nft, o que não conseguia quando executava a consola manualmente como o seu próprio utilizador. Nada aplica esse script — executá-lo continua a ser responsabilidade sua.

Apenas Debian é verificado, porque é o que foi testado; a unit é muito provavelmente correta em qualquer distribuição systemd, mas o caminho dos logs SSH que assume é o do Debian.

Expondo-o

Fazer bind a algo que não seja loopback exige uma segunda flag deliberada, porque esta consola pode reescrever a firewall e a configuração do NGINX do host onde corre:``` stop-bots web --bind 0.0.0.0:8787 --expose --allowed-hosts admin.example.com --save

root@kitploit:~
`--allowed-hosts` não é opcional na prática: uma requisição que carrega um nome de host que não está
listado é recusada. É isso que faz o DNS rebinding contra o console falhar, e é
por isso que um servidor exposto acessado por nome precisa que o nome seja especificado.

Coloque-o atrás do NGINX com TLS — o mesmo NGINX que esta ferramenta está protegendo. Se o fizer, e o
proxy definir `X-Forwarded-For`, avise o console de que ele pode confiar nesse cabeçalho, ou ele não conseguirá
determinar de qual endereço uma requisição realmente veio:```
stop-bots web --bind 127.0.0.1:8787   # and set web:trust_forwarded_for

Por trás do TLS, defina também web:secure_cookie. Sem isso, um navegador enviará o cookie de sessão também para um URL http:// do mesmo host.

web:trust_forwarded_for importa mais do que parece. Sem ele, cada requisição atrás de um proxy chega de 127.0.0.1, então o console não consegue distinguir um cliente de outro — o que significa que uma enxurrada de tentativas de login compartilha o mesmo balde de throttle que você, e a proteção que impede você de bloquear seu próprio endereço não tem com o que comparar. Com ele, ambos funcionam por cliente.

Atrás do NGINX: um subdomínio, ou um prefixo de caminho

O console pode configurar isso para você, e o TUI também (w no Dashboard). Ambos escrevem a configuração do NGINX, registram o prefixo de caminho e adicionam o nome do host à allowlist — as três coisas que precisam concordar, porque um prefixo ausente faz cada link sair do bloco location e um nome de host ausente faz cada requisição virar um 403. Ambos validam com nginx -t antes que a configuração possa entrar em vigor, revertem se isso falhar, e registram o novo endereço apenas depois que ele foi validado.

Dois modos, e path é o padrão por um motivo: ele adiciona um bloco location a um site que você já tem, então o console herda o certificado desse site. Um subdomínio precisa do seu próprio, e até que certbot --nginx -d <host> tenha sido executado, o formulário de senha e o cookie de sessão deste console atravessam a rede em texto claro.

O restante desta seção é a mesma coisa feita à mão, o que vale a pena ler uma vez mesmo que você use o painel — a armadilha da barra final abaixo é o erro que ele existe para prevenir.

Um subdomínio é a implantação mais simples, e a que você deve escolher se puder:```nginx server { server_name stopbots.example.com; location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; } }

root@kitploit:~
| `-s` | `--server` | `SERVER` | `http://localhost:8080` | URL do servidor |
| `-t` | `--token` | `TOKEN` | - | Token de autenticação |
| `-o` | `--output` | `FILE` | stdout | Arquivo de saída |
| `-f` | `--format` | `FORMAT` | `json` | Formato de saída (json, yaml, table) |
| `-v` | `--verbose` | - | `false` | Ativar saída detalhada |
| `-q` | `--quiet` | - | `false` | Suprimir saída não essencial |
| `--timeout` | - | `SECONDS` | `30` | Tempo limite da requisição em segundos |
| `--retry` | - | `COUNT` | `3` | Número de tentativas em caso de falha |
| `--insecure` | - | - | `false` | Ignorar verificação de certificado TLS |

### Exemplos

```bash
# Listar todos os alvos
scanner targets list

# Obter detalhes de um alvo específico
scanner targets get --id abc123

# Criar um novo alvo
scanner targets create --name "web-server" --host 192.168.1.100

# Excluir um alvo
scanner targets delete --id abc123

# Exportar resultados em formato JSON
scanner scan --target abc123 --output results.json --format json

# Executar com saída detalhada
scanner scan --target abc123 --verbose

# Usar um arquivo de configuração personalizado
scanner --config /path/to/config.yaml scan --target abc123

Arquivo de Configuração

O scanner oferece suporte a um arquivo de configuração YAML para definir opções padrão:

root@kitploit:~
server: http://localhost:8080
token: your-api-token-here
output: results.json
format: json
timeout: 60
retry: 5
insecure: false

targets:
  - name: web-server
    host: 192.168.1.100
    ports:
      - 80
      - 443
      - 8080
  - name: db-server
    host: 192.168.1.200
    ports:
      - 3306
      - 5432

Variáveis de Ambiente

As seguintes variáveis de ambiente podem ser usadas para substituir as configurações padrão:

VariávelDescriçãoPadrão
SCANNER_SERVERURL do servidorhttp://localhost:8080
SCANNER_TOKENToken de autenticação-
SCANNER_OUTPUTArquivo de saídastdout
SCANNER_FORMATFormato de saídajson
SCANNER_TIMEOUTTempo limite da requisição30
SCANNER_RETRYNúmero de tentativas3
SCANNER_INSECUREIgnorar verificação TLSfalse

Códigos de Saída

CódigoDescrição
0Sucesso
1Erro geral
2Uso incorreto do comando
3Erro de autenticação
4Recurso não encontrado
5Tempo limite da requisição excedido

Solução de Problemas

Erro: Conexão recusada

Verifique se o servidor está em execução e se a URL está correta:

root@kitploit:~
curl -v http://localhost:8080/health

Erro: Não autorizado

Verifique se o token de autenticação está correto e não expirou:

root@kitploit:~
scanner auth verify --token your-api-token-here

Erro: Tempo limite da requisição excedido

Aumente o valor do tempo limite usando a flag --timeout:

root@kitploit:~
scanner scan --target abc123 --timeout 120

Erro: Certificado TLS inválido

Use a flag --insecure para ignorar a verificação do certificado (apenas para ambientes de teste):

root@kitploit:~
scanner scan --target abc123 --insecure

Desinstalação

Para remover o scanner do seu sistema:

root@kitploit:~
# Se instalado via pip
pip uninstall scanner-cli

# Se instalado via npm
npm uninstall -g scanner-cli

# Se instalado a partir do código-fonte
cd scanner-cli
make uninstall

Licença

Este projeto está licenciado sob a Licença MIT - consulte o arquivo LICENSE para obter detalhes.

Contribuindo

Contribuições são bem-vindas! Consulte CONTRIBUTING.md para obter diretrizes.

Agradecimentos

  • Biblioteca XYZ - Pela excelente biblioteca de rede
  • Projeto ABC - Pela inspiração e ideias
  • Todos os contribuidores que ajudaram a tornar este projeto melhor

Suporte

Se você encontrar algum problema ou tiver dúvidas, abra uma issue no GitHub.

Aviso Legal

Esta ferramenta destina-se apenas a testes de segurança autorizados e fins educacionais. Os autores não se responsabilizam por qualquer uso indevido ou danos causados por esta ferramenta. Sempre obtenha permissão por escrito antes de testar qualquer sistema que você não possua.``` stop-bots web --allowed-hosts stopbots.example.com --save

root@kitploit:~
**Um prefixo de caminho também funciona**, mas o console precisa ser informado sobre ele — ele precisa
gerar cada link, ação de formulário, redirecionamento e caminho de cookie com o prefixo já
incluído, e não consegue adivinhar:```
stop-bots web --base-path /stop-bots --allowed-hosts example.com --save

| -s | --server | SERVER | http://localhost:8080 | URL do servidor | | -t | --token | TOKEN | null | Token de autenticação | | -c | --config | CONFIG | null | Caminho do arquivo de configuração | | -v | --verbose | VERBOSE | false | Saída detalhada | | -q | --quiet | QUIET | false | Modo silencioso | | -d | --debug | DEBUG | false | Modo de depuração | | -h | --help | HELP | false | Exibir ajuda | | -V | --version | VERSION | false | Exibir versão |

Exemplos

root@kitploit:~
# Iniciar o servidor
python3 server.py

# Executar o cliente
python3 client.py

# Executar com opções
python3 client.py -s http://localhost:8080 -t mytoken -v

Estrutura do Projeto

root@kitploit:~
project/
├── server.py          # Arquivo principal do servidor
├── client.py          # Arquivo principal do cliente
├── config.py          # Arquivo de configuração
├── requirements.txt   # Dependências do projeto
├── README.md          # Documentação do projeto
└── tests/             # Diretório de testes
    ├── test_server.py
    └── test_client.py

Desenvolvimento

Configuração do Ambiente

root@kitploit:~
# Clonar o repositório
git clone https://github.com/example/project.git
cd project

# Criar ambiente virtual
python3 -m venv venv
source venv/bin/activate

# Instalar dependências
pip install -r requirements.txt

Executando os Testes

root@kitploit:~
# Executar todos os testes
pytest

# Executar com cobertura
pytest --cov=. --cov-report=html

# Executar testes específicos
pytest tests/test_server.py -v

Estilo de Código

root@kitploit:~
# Formatar código
black .

# Verificar lint
flake8 .

# Verificar tipos
mypy .

Implantação

Docker

root@kitploit:~
# Construir imagem
docker build -t project:latest .

# Executar contêiner
docker run -d -p 8080:8080 project:latest

Docker Compose

root@kitploit:~
# Iniciar serviços
docker-compose up -d

# Parar serviços
docker-compose down

Solução de Problemas

Problemas Comuns

  1. Porta já em uso

    root@kitploit:~
    # Encontrar processo usando a porta
    lsof -i :8080
    
    # Encerrar processo
    kill -9 <PID>
    
  2. Permissão negada

    root@kitploit:~
    # Tornar executável
    chmod +x server.py
    
  3. Módulo não encontrado

    root@kitploit:~
    # Instalar dependências
    pip install -r requirements.txt
    

Logs

root@kitploit:~
# Visualizar logs
tail -f /var/log/project/server.log

# Filtrar logs
grep "ERROR" /var/log/project/server.log

Contribuição

  1. Faça um fork do repositório
  2. Crie uma branch de funcionalidade (git checkout -b feature/AmazingFeature)
  3. Faça commit das alterações (git commit -m 'Add some AmazingFeature')
  4. Faça push para a branch (git push origin feature/AmazingFeature)
  5. Abra um Pull Request

Licença

Este projeto está licenciado sob a Licença MIT - consulte o arquivo LICENSE para obter detalhes.

Agradecimentos

  • Contribuidor 1
  • Contribuidor 2

Contato

  • Autor: Seu Nome
  • E-mail: [email protected]
  • Projeto: https://github.com/example/project

Status do Projeto

Status Versão Licença```nginx location /stop-bots/ { proxy_pass http://127.0.0.1:8787; # NO trailing slash proxy_set_header Host $host; }

root@kitploit:~
**A barra final em `proxy_pass` importa, e sua ausência é todo o truque.**
Sem ela, o NGINX passa o caminho completo adiante e o `stop-bots` vê
`/stop-bots/whatever`, que é o que ele agora serve e gera. *Com* uma barra
final, o NGINX remove o prefixo — e então o navegador resolve os links na página
em relação à raiz do domínio, cai fora do bloco `location`, e tudo retorna 404. Nenhum
cuidado do lado do servidor pode corrigir isso, então o prefixo precisa sobreviver ao
proxy.

Nada impõe isso de fora, mas a falha é ruidosa em vez de sutil: com o
prefixo configurado, uma requisição sem prefixo é um 404 simples em vez de uma página que
funciona pela metade.

## O que ele não fará

Duas coisas estão faltando de propósito, e a tela de Ajuda diz isso com os motivos:

- **Ele não desbloqueará algo que uma lista baixada bloqueou** — a próxima atualização dessa
  lista desfaria isso silenciosamente.
- **Ele não mudará sua própria senha.** Use `stop-bots web --set-password` no host.

Ele também se recusa a bloquear o endereço do qual você está conectado, o que tiraria o
console que você usaria para desfazer isso.

**Costumava ser três.** Aplicar o script de firewall era a terceira, com o argumento de que
executá-lo é a única operação que pode tirar o host da rede. Isso agora está
disponível — "Apply everything" no Dashboard (`a` na TUI), ou a caixa "run it after
writing" no painel de firewall — porque a proteção que o torna seguro a partir do cron o torna seguro a partir de um
botão: as regras são verificadas contra os clientes atualmente logados via SSH, na
ordem em que o próprio script as avaliará, e uma regra que bloquearia um deles é uma
recusa em vez de um aviso. Inicie o console com `--no-apply` para recuperar o comportamento antigo
de apenas escrita.

As tentativas de login são limitadas. Não porque a senha seja adivinhável — ela é gerada,
144 bits — mas porque verificá-la executa Argon2id, e deixar um chamador não autenticado
conduzir isso o mais rápido que conseguir postar é uma negação de serviço contra o host que esta ferramenta
deveria estar protegendo. Dez tentativas erradas são gratuitas; além disso, um cliente recua
exponencialmente, e um limite global limita a CPU independentemente de quantos endereços as
tentativas vêm.

## Executando o NGINX em um contêiner

Se o NGINX está no Docker e sua configuração está em um bind mount, `systemctl reload nginx` não recarrega
nada. Aponte os dois comandos para o contêiner — isso se aplica à CLI e à
TUI também:```
stop-bots set-nginx-commands \
  --test   "docker exec web nginx -t" \
  --reload "docker exec web nginx -s reload"

O comando é dividido em palavras e executado diretamente. Ele nunca passa por um shell, portanto ;, | e $VAR são caracteres comuns em vez de sintaxe.

Contribuindo

Como o código está organizado, como é testado e as regras segundo as quais é escrito estão em CONTRIBUTING.md. O processo de release está em RELEASING.md.

Contato

Você pode entrar em contato comigo em [email protected].

Licença

Copyright (C) 2026 Marko Ivankovic

Este programa é software livre: você pode redistribuí-lo e/ou modificá-lo sob os termos da GNU Affero General Public License, conforme publicada pela Free Software Foundation, seja a versão 3 da Licença, ou (a seu critério) qualquer versão posterior.

Consulte o arquivo LICENSE para o texto completo da Licença.

Não pode usar software AGPL?

Licenciamento alternativo NÃO está disponível.

RegraAfasta, além de bots
HTTP/1.0 e HTTP/1.1crawlers e clientes de API que não falam HTTP/2
Sem cabeçalho Acceptalguns clientes de API não enviam nenhum
Sem Accept-Languageferramentas de privacidade o removem
User-Agent vazio/ausentescripts e verificações de integridade frequentemente o omitem
Host é um IP puroquebra o acesso ao site por IP
TLS 1.0 / 1.1apenas clientes muito antigos