Aula 17: CrowdSec — bouncers: bloqueio com Nginx, Apache e iptables
Seja muito bem-vindo à décima sétima aula do nosso curso completo Firewall, fail2ban e CrowdSec — Do Zero ao Avançado. Hoje vamos mergulhar fundo em um dos componentes mais poderosos e flexíveis do ecossistema CrowdSec: os bouncers. Você já aprendeu nas aulas anteriores a instalar o agente, ler cenários, interpretar logs e gerenciar decisões. Agora chegou o momento de transformar essas decisões em ações reais de bloqueio na borda da sua rede e diretamente nos seus servidores web. Imagine receber um alerta de que um IP está realizando um ataque de força bruta contra seu painel WordPress e, em milissegundos, esse IP ser barrado pelo iptables ou pelo próprio Nginx antes mesmo de chegar à aplicação — isso é o que configuraremos hoje, passo a passo, sem atalhos perigosos.
Ao longo desta aula, vamos dissecar a arquitetura de funcionamento de um bouncer CrowdSec, entender como ele se comunica com a API Local (LAPI) e aplicar essa teoria em três cenários práticos que cobrem a maioria das infraestruturas atuais: bloqueio perimetral via iptables (ou nftables), bloqueio no layer 7 com o Nginx e bloqueio via Apache HTTP Server. Todos os procedimentos serão executados duas vezes — uma em distribuições baseadas em Debian/Ubuntu e outra em RHEL/CentOS/Rocky Linux — porque sabemos que ambientes heterogêneos são a realidade em mais de 90% dos data centers. Se você acompanhar esta aula com atenção e executar cada comando na ordem proposta, sairá dela com três bouncers totalmente funcionais, capazes de proteger serviços críticos contra varreduras, ataques de dicionário, crawlers maliciosos e tentativas de exploração de vulnerabilidades conhecidas.
Por que esta aula é um divisor de águas no curso? Porque não adianta nada ter um sistema de detecção comportamental de última geração se ele não consegue impor consequências. O bouncer é o braço armado do CrowdSec; é ele quem lê a lista de decisões do banco de dados local e traduz o veredito em regras de firewall, respostas HTTP 403 ou redirecionamentos para captchas. Em nossos projetos na JRT Technology Solutions, utilizamos diariamente essa arquitetura para proteger ambientes que vão desde pequenos portais institucionais com 300 visitantes/dia até plataformas de e-commerce que processam centenas de milhares de requisições por minuto. A beleza está na padronização: o agente coleta, o LAPI serve e os bouncers aplicam, independentemente da tecnologia de barreira utilizada.
Antes de colocar a mão no teclado, vamos alinhar expectativas e pré-requisitos. Você precisa ter concluído a Aula 16, onde deixamos o agente CrowdSec rodando e o comando cscli decisions list já exibia decisões ativas. O core do sistema — agente e LAPI — deve estar operacional em uma máquina que será o ponto central de distribuição, podendo ser a mesma onde instalaremos os bouncers ou um servidor dedicado. Além disso, é fundamental ter portas de comunicação liberadas (padrão TCP 8080 para a LAPI) e permissões de superusuário (sudo ou root) em todos os nós envolvidos. Se você ainda não emitiu um certificado TLS para a LAPI, acessos locais via localhost não exigem isso, mas trabalharemos com boas práticas desde já. Ao final dos procedimentos, você realizará um teste real de bloqueio, forçando uma detecção e observando o tráfego ser rejeitado em segundos.
O que você vai aprender nesta aula
- Compreender a diferença entre bouncers de rede (firewall) e bouncers de aplicação (web servers) no ecossistema CrowdSec
- Instalar e configurar o crowdsec-firewall-bouncer-iptables em Debian/Ubuntu e Rocky Linux a partir do repositório oficial
- Instalar e ativar o bouncer para Nginx, incluindo o módulo Lua necessário em ambas as famílias de distribuições
- Instalar e configurar o bouncer para Apache utilizando
mod_security2e o lua-modsecurity - Registrar cada bouncer no LAPI via
csclie compreender o fluxo de autenticação e polling - Testar, em tempo real, o bloqueio de um IP malicioso em cada uma das camadas configuradas
- Diagnosticar e corrigir os 4 erros mais comuns que impedem a comunicação entre bouncer e LAPI
Pré-requisitos e Ambiente
Para executar esta aula sem interrupções, você precisará de pelo menos duas máquinas virtuais ou contêineres — uma com o agente CrowdSec e LAPI já funcionais (conforme Aula 16) e outra(s) onde instalaremos os bouncers. Numa configuração laboratorial mínima, uma única máquina pode hospedar tudo, mas encorajamos a separação para simular um ambiente real. O sistema operacional das máquinas bouncer pode ser Ubuntu Server 22.04/24.04 LTS, Debian 12, CentOS Stream 9 ou Rocky Linux 9. Em todos os cenários, assumimos que o usuário possui privilégios de sudo e que o firewall local (se existente) está configurado para permitir conexões SSH e o tráfego das portas que testaremos. Como instalaremos componentes que manipulam regras de rede e hooks em servidores HTTP, uma boa prática é criar um snapshot das VMs antes de começar — isso já nos salvou incontáveis horas de troubleshooting nos projetos implementados pela JRT Technology Solutions.
Entendendo o Papel dos Bouncers no Ecossistema CrowdSec
Antes de executar qualquer comando, é fundamental internalizar como um bouncer se posiciona no fluxo de dados. O termo “bouncer” vem do inglês e significa “leão de chácara” — aquele que fica na porta selecionando quem entra e quem fica do lado de fora. Na arquitetura CrowdSec, o agente analisa logs e toma decisões do tipo ban ou captcha para determinados IPs e ranges. Essas decisões são armazenadas localmente no banco SQLite e expostas pela LAPI (Local API) via protocolo HTTP. O bouncer consulta periodicamente essa API — por padrão a cada 1 segundo — em busca de novas decisões ou revogações. Quando encontra um IP na lista, ele adiciona uma regra específica no subsistema alvo (iptables, Nginx, Apache, Cloudflare, etc.). Da mesma forma, quando a decisão expira, o bouncer remove a regra, liberando o IP.
Existem duas categorias principais de bouncers. A primeira são os bouncers de rede, que operam nos layers 3 e 4 do modelo OSI. O mais comum é o crowdsec-firewall-bouncer-iptables, que insere regras nos chains do Netfilter (ou nftables, a depender da versão do pacote e do kernel) bloqueando todo o tráfego proveniente dos IPs constantes na lista. Sua vantagem é a eficiência extrema: o bloqueio acontece no kernel, antes mesmo que o pacote chegue a qualquer espaço de usuário consumindo CPU. A segunda categoria são os bouncers de aplicação, que atuam no layer 7. Aqui encontramos integrações com Nginx, Apache, Traefik, HAProxy e até CDNs como Cloudflare. O bloqueio no layer 7 permite ações mais granulares: em vez de simplesmente dropar o pacote, podemos devolver um HTTP 403, um captcha ou um redirect, preservando a capacidade de registro e oferecendo ao atacante uma resposta mais informativa (ou não, conforme a necessidade).
O processo de comunicação segue um fluxo bem definido. Primeiro, o bouncer precisa ser registrado no LAPI — isso gera uma api_key única que será usada em todas as requisições subsequentes. O comando cscli bouncers add <nome> cria essa chave e a armazena no banco. Depois, no arquivo de configuração do bouncer (geralmente /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml ou equivalente), informamos a URL da LAPI e a chave de API. Ao iniciar, o bouncer autentica-se e começa a puxar a lista completa de decisões ativas. Em seguida, entra em modo de polling, consultando o endpoint /v1/decisions/stream com um parâmetro startup que retorna apenas as mudanças incrementais. Essa arquitetura é extremamente leve: um bouncer de iptables com 50 mil IPs na lista consome menos de 100 MB de RAM e o polling de 1 segundo gera tráfego ínfimo na interface de loopback.
Outro ponto importante é que o bouncer não é um “firewall” no sentido tradicional — ele não substitui um iptables ou um Web Application Firewall, ele os complementa. O conjunto de regras inserido pelo bouncer fica em chains ou tabelas dedicadas, evitando conflitos com regras administrativas. Em nossos treinamentos corporativos e implementações de campo pela JRT Technology Solutions, uma dúvida recorrente é se o bouncer pode “derrubar” o servidor em caso de pico de novos IPs. A resposta é não: mesmo com atualizações constantes, o bouncer utiliza chamadas atômicas ao subsistema de firewall, levando milissegundos para aplicar um lote de milhares de IPs. No layer 7, a integração com Nginx usando Lua é igualmente eficiente, pois mantém um cache em memória compartilhada e aplica a verificação em estágios iniciais do processamento da requisição.
Instalando e Configurando o CrowdSec Firewall Bouncer (iptables)
Vamos começar pelo bouncer de rede, que oferece a proteção mais abrangente pois opera antes de qualquer serviço. O pacote que utilizaremos é o crowdsec-firewall-bouncer-iptables, disponível nos repositórios oficiais do projeto. Escolhemos este por ser o mais estável e largamente testado, compatível tanto com iptables legado quanto com nftables via backend de compatibilidade. Em sistemas modernos que utilizam nftables puro, o comportamento é o mesmo; o bouncer detecta o subsistema ativo e se adapta. O procedimento abaixo foi validado em mais de duas centenas de servidores gerenciados por nossa equipe e é replicável exatamente como descrito.
Passo 1: Adicionar o repositório do CrowdSec e instalar o pacote no Ubuntu/Debian
# Baixar e executar o script oficial de adição do repositório
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
# Atualizar a lista de pacotes e instalar o bouncer de firewall
sudo apt update
sudo apt install crowdsec-firewall-bouncer-iptables -y
O script script.deb.sh configura o arquivo /etc/apt/sources.list.d/crowdsec_crowdsec.list com a URL do repositório e adiciona a chave GPG necessária. A flag -y em apt install evita a pergunta de confirmação quando você já tem certeza do que está fazendo. Se preferir um controle mais granular, remova o -y e confirme manualmente.
Passo 2: Instalação no Rocky Linux / AlmaLinux / RHEL
# Adicionar o repositório para distribuições baseadas em RPM
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.rpm.sh | sudo bash
# Instalar o bouncer de firewall
sudo dnf install crowdsec-firewall-bouncer-iptables -y
No ecossistema RPM, o script script.rpm.sh cria o arquivo de repositório em /etc/yum.repos.d/crowdsec_crowdsec.repo. O comando dnf funciona em Rocky Linux 9, CentOS Stream 9 e versões recentes do Fedora. Se estiver em CentOS 7, substitua dnf por yum.
Passo 3: Localizar e ajustar o arquivo de configuração principal
Após a instalação, o arquivo de configuração estará em /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml. Precisamos editar três parâmetros essenciais: a URL da API local, a chave de API do bouncer (que ainda vamos gerar) e, opcionalmente, o modo de atualização das regras. Abra o arquivo com um editor de texto:
sudo vim /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
Segue o conteúdo mínimo que deve estar presente, com comentários explicativos em cada linha relevante:
# URL da LAPI. Se o agente e o bouncer estão na mesma máquina, localhost é suficiente.
# Para máquinas remotas, utilize o IP ou FQDN e a porta configurada (padrão 8080).
api_url: http://localhost:8080/
# A chave de API deve ser a mesma gerada pelo comando 'cscli bouncers add'.
# Deixaremos o valor temporário, será substituído no próximo passo.
api_key: SERA_SUBSTITUIDA
# Se verdadeiro, ignora o estado do kernel e força iptables; use em sistemas com nftables.
iptables_mode: iptables
# O intervalo (em segundos) para verificar novas/removidas decisões.
update_frequency: 10s
# Modo de operação do firewall: 'iptables' ou 'nftables'. Deixe em branco para auto-detectar.
mode: iptables
# Nome da chain customizada que o bouncer criará no iptables.
chain_name: crowdsec
# Nome da tabela e chain para conjuntos de IPs (IPSET). Acelera bloqueios com listas grandes.
ipset_name: crowdsec-blacklists
A diretiva api_url deve apontar para o endpoint da LAPI. Se o agente CrowdSec está rodando na mesma máquina, o padrão http://localhost:8080/ funciona perfeitamente. Caso o agente esteja em outro host, altere para http://<IP_DO_AGENTE>:8080/. A api_key será gerada nos próximos comandos. O campo update_frequency define o intervalo de polling: 10 segundos é um bom equilíbrio entre tempo de reação e consumo de recursos. Para ambientes de alta criticidade, já ajustamos esse valor para 2 segundos em clientes da JRT Technology Solutions que enfrentam ataques DDoS de baixa intensidade.
Passo 4: Registrar o bouncer no LAPI
No servidor onde roda o agente CrowdSec (o mesmo que hospeda a LAPI), execute:
sudo cscli bouncers add firewall-bouncer-01
A saída será uma chave de API no formato Api key for 'firewall-bouncer-01': <hash-longo>. Copie essa chave integralmente. Se a máquina do bouncer for diferente da máquina do agente, você precisará transferir essa chave de forma segura. Em laboratório, pode simplesmente copiar e colar no arquivo YAML.
# Exemplo prático de adição e saída:
sudo cscli bouncers add firewall-bouncer-01
API key for 'firewall-bouncer-01':
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
Please keep this key since you will not be able to retrieve it later!
Agora, de volta ao servidor do bouncer, edite o arquivo YAML e substitua api_key: SERA_SUBSTITUIDA pela chave gerada. Salve e feche o arquivo. É crucial que não haja espaços extras no início ou fim da chave.
Passo 5: Iniciar e habilitar o serviço em ambos os sistemas
No Ubuntu/Debian e também no Rocky Linux (que usam systemd), a sequência é idêntica:
sudo systemctl enable crowdsec-firewall-bouncer
sudo systemctl start crowdsec-firewall-bouncer
sudo systemctl status crowdsec-firewall-bouncer --no-pager -l
Ao executar o status, você deve ver uma linha indicando Active: active (running) e, nos logs iniciais, a confirmação de que o bouncer se conectou à API e está sincronizando as decisões. Preste atenção à saída, que é um termômetro instantâneo da saúde da configuração.
● crowdsec-firewall-bouncer.service - Crowdsec firewall bouncer
Loaded: loaded (/lib/systemd/system/crowdsec-firewall-bouncer.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-07-13 09:17:22 UTC; 3s ago
Main PID: 41280 (crowdsec-firewa)
Tasks: 11 (limit: 2341)
Memory: 12.8M
CPU: 98ms
CGroup: /system.slice/crowdsec-firewall-bouncer.service
└─41280 /usr/bin/crowdsec-firewall-bouncer -c /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
Jul 13 09:17:22 bouncer-lab systemd[1]: Started Crowdsec firewall bouncer.
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="Starting crowdsec-firewall-bouncer v0.0.29"
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="Using iptables mode"
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="backend: iptables"
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="ipset name: crowdsec-blacklists"
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="Processing new and deleted decisions . . ."
Jul 13 09:17:22 bouncer-lab crowdsec-firewall-bouncer[41280]: time="13-07-2026 09:17:22" level=info msg="decisions update finished (0 new, 0 deleted)"
Este output mostra um bouncer pronto, sem decisões iniciais (zero new, zero deleted). Mais adiante verificaremos com decisões reais. O importante é que não apareçam mensagens level=error ou level=fatal.
Instalando e Configurando o Bouncer para Nginx
O bouncer para Nginx permite bloquear IPs maliciosos diretamente no servidor web, antes que a requisição chegue ao backend PHP, Python ou Node.js. Diferentemente do bouncer de firewall, aqui a ação padrão é retornar um HTTP 403 Forbidden (ou qualquer código configurável), o que é útil para manter logs de acesso e monitorar tentativas frustradas sem sobrecarregar o processador de regras de rede. A integração utiliza o módulo lua-nginx-module (OpenResty), então precisaremos garantir que ele esteja presente. Em Debian/Ubuntu, o pacote libnginx-mod-http-lua resolve; em Rocky Linux, instalaremos o Nginx a partir do repositório EPEL ou compilado com suporte a módulos Lua.
Passo 1: Instalar o Nginx com módulo Lua (Ubuntu/Debian)
sudo apt update
sudo apt install nginx libnginx-mod-http-lua lua5.1 liblua5.1-0-dev -y
Passo 2: Instalar o Nginx com módulo Lua (Rocky Linux)
No Rocky Linux 9, o repositório EPEL fornece um pacote nginx que não inclui o módulo Lua por padrão. Felizmente, o repositório oficial do Nginx oferece builds com módulos dinâmicos. Vamos adicionar o repositório oficial:
sudo dnf install epel-release -y
sudo dnf config-manager --set-enabled crb
# Adicionar repositório oficial do Nginx
echo '[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/rhel/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true' | sudo tee /etc/yum.repos.d/nginx.repo
sudo dnf install nginx nginx-module-lua -y
Após a instalação, verifique se o módulo Lua está disponível:
ls /usr/lib64/nginx/modules/ | grep lua
ngx_http_lua_module.so
É necessário carregar explicitamente o módulo no arquivo de configuração principal do Nginx (/etc/nginx/nginx.conf) antes de utilizá-lo:
# Adicionar no topo do arquivo nginx.conf, antes do bloco 'events'
load_module /usr/lib64/nginx/modules/ngx_http_lua_module.so;
Passo 3: Instalar o bouncer CrowdSec para Nginx
O pacote é o mesmo em ambas as distribuições, disponível nos repositórios CrowdSec:
# Ubuntu/Debian
sudo apt install crowdsec-nginx-bouncer -y
# Rocky Linux
sudo dnf install crowdsec-nginx-bouncer -y
O pacote instala um binário (crowdsec-nginx-bouncer) que atua como um pequeno serviço gerando um conjunto de regras para o módulo Lua. A configuração fica em /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf. Edite-o:
sudo vim /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
Conteúdo mínimo do arquivo:
# URL da Local API
API_URL=http://localhost:8080
# Chave de API que será gerada
API_KEY=CHAVE_AQUI
# Tempo de vida do cache de decisões no arquivo Lua
CACHE_EXPIRATION=30
# Modo: pode ser live (consulta API em tempo real) ou stream (usa arquivo de cache)
MODE=stream
# Caminho para o diretório de cache que o Nginx lerá
CACHE_PATH=/var/lib/crowdsec/nginx-bouncer/cache/
Passo 4: Registrar o bouncer Nginx no LAPI
No servidor do agente:
sudo cscli bouncers add nginx-bouncer-01
API key for 'nginx-bouncer-01':
f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4
Please keep this key since you will not be able to retrieve it later!
Copie a chave e cole em API_KEY= no arquivo .conf do bouncer Nginx.
Passo 5: Gerar o arquivo de cache inicial e configurar o Nginx
Execute o binário do bouncer para pré-carregar a lista de ban:
sudo /usr/bin/crowdsec-nginx-bouncer -g
Isso cria um arquivo de cache .lua no diretório especificado. Agora, crie um arquivo de configuração para o Nginx carregar o bouncer (por exemplo, /etc/nginx/conf.d/crowdsec.inc):
# Define uma memória compartilhada para o cache do bouncer
lua_shared_dict crowdsec_cache 10m;
# Inicializa o módulo CrowdSec no rewrite phase
init_by_lua_block {
local cs = require "crowdsec"
cs.init({
cache_path = "/var/lib/crowdsec/nginx-bouncer/cache/",
cache_expiration = 30,
fallback_action = "allow"
})
}
# Hook de acesso: verifica IP antes de processar a requisição
access_by_lua_block {
local cs = require "crowdsec"
cs.access()
}
Inclua esse arquivo no bloco server do seu site. Por exemplo, em /etc/nginx/conf.d/default.conf:
server {
listen 80;
server_name _;
# Incluir o bouncer
include /etc/nginx/conf.d/crowdsec.inc;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
Teste a configuração e reinicie:
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable crowdsec-nginx-bouncer
sudo systemctl start crowdsec-nginx-bouncer
O serviço crowdsec-nginx-bouncer ficará rodando em background atualizando o arquivo de cache periodicamente. O Nginx, através do bloco Lua, consulta essa memória compartilhada a cada requisição. Em média, o overhead é inferior a 2 milissegundos por request em nossos benchmarks com hardware modesto.
Instalando e Configurando o Bouncer para Apache
O bouncer para Apache segue uma filosofia similar, mas utiliza o módulo mod_security2 como backend de análise, com um script Lua embutido que consulta a LAPI CrowdSec. Em ambientes que já possuem mod_security ativo, essa abordagem é extremamente orgânica, pois estende um WAF já existente. Vamos instalar o Apache, o mod_security2 e o bouncer CrowdSec.
Passo 1: Instalar Apache e mod_security2 no Ubuntu/Debian
sudo apt update
sudo apt install apache2 libapache2-mod-security2 -y
sudo a2enmod security2
sudo systemctl restart apache2
Passo 2: Instalar Apache e mod_security2 no Rocky Linux
sudo dnf install httpd mod_security mod_security_crs -y
sudo systemctl enable httpd --now
Passo 3: Instalar o bouncer CrowdSec para Apache
# Ubuntu/Debian
sudo apt install crowdsec-apache-bouncer -y
# Rocky Linux
sudo dnf install crowdsec-apache-bouncer -y
O arquivo de configuração fica em /etc/crowdsec/bouncers/crowdsec-apache-bouncer.conf. Edite-o:
sudo vim /etc/crowdsec/bouncers/crowdsec-apache-bouncer.conf
# URL da API Local (use o IP do servidor com LAPI se for remoto)
API_URL=http://192.168.1.100:8080
# Chave da API
API_KEY=CHAVE_GERADA
# Caminho do script Lua que será carregado pelo mod_security
LUA_SCRIPT=/etc/crowdsec/bouncers/apache/crowdsec.lua
# Intervalo de sincronização em segundos
UPDATE_FREQUENCY=15
# Ação em caso de falha na comunicação: allow (permitir) ou deny (bloquear)
FALLBACK_ACTION=allow
Passo 4: Registrar o bouncer Apache no LAPI
sudo cscli bouncers add apache-bouncer-01
Copie a chave e insira no arquivo .conf.
Passo 5: Configurar o mod_security para usar o bouncer
O pacote do bouncer Apache geralmente insere um arquivo de configuração do mod_security em /etc/httpd/conf.d/crowdsec-apache-bouncer.conf (Rocky) ou /etc/apache2/conf-available/crowdsec-apache-bouncer.conf (Debian). Habilite-o:
# Debian/Ubuntu
sudo a2enconf crowdsec-apache-bouncer
sudo systemctl restart apache2
# Rocky Linux
sudo systemctl restart httpd
Verifique se o módulo Lua está ativo no Apache e se o bouncer foi carregado:
sudo apachectl -M 2>/dev/null | grep -i lua
lua_module (shared)
Em seguida, inicie o serviço do bouncer:
sudo systemctl enable crowdsec-apache-bouncer
sudo systemctl start crowdsec-apache-bouncer
Com estes três bouncers configurados — firewall, Nginx e Apache — seu ambiente agora possui camadas múltiplas de defesa reativas. Um mesmo IP banido pelo agente será barrado no iptables (proteção de rede), no Nginx (proteção de aplicação) e, se houver Apache em outro virtualhost, também receberá um 403. Essa redundância é proposital e segue o modelo de “defesa em profundidade” que aplicamos em todos os projetos na JRT Technology Solutions.
Verificando a Instalação / Testando a Configuração
A verificação deve ser metódica, validando a comunicação LAPI-bouncer e o bloqueio efetivo. O primeiro comando, no servidor onde está a LAPI, lista todos os bouncers registrados e seu status de comunicação:
sudo cscli bouncers list
----------------------------------------------------------------------------------------
NAME TYPE STATUS LAST API PULL
----------------------------------------------------------------------------------------
firewall-bouncer-01 firewall-bouncer ACTIVE 2026-07-13 10:22:17
nginx-bouncer-01 nginx-bouncer ACTIVE 2026-07-13 10:22:18
apache-bouncer-01 apache-bouncer ACTIVE 2026-07-13 10:22:17
----------------------------------------------------------------------------------------
O status ACTIVE e uma data de pull recente (menos de 1 minuto) indicam que os bouncers estão se comunicando corretamente. Se algum aparecer UNKNOWN ou com pull antigo, verifique firewalls, rotas e a chave de API.
Para um teste prático de bloqueio, podemos simular um ataque e forçar uma decisão. No servidor com o agente, execute um cenário de detecção rápido, como um scan de portas:
# Instalar o cenário de SSH brute force se ainda não estiver ativo
sudo cscli scenarios install crowdsecurity/ssh-bf
# Simular falhas de login SSH a partir de um IP de teste (ex: 192.168.99.99)
# Você pode usar um container ou uma VM secundária, ou até localhost com logger
echo "Jul 13 10:30:00 lab sshd[1234]: Failed password for invalid user admin from 192.168.99.99 port 55555 ssh2" | sudo /usr/bin/crowdsec -file /var/log/auth.log -type syslog -dsn file:///dev/stdin
# O comando acima é ilustrativo; o mais prático é injetar log manual:
Maneira mais confiável: use a API do LAPI para forçar uma decisão via CLI:
sudo cscli decisions add --ip 203.0.113.50 --duration 5m --type ban -r "Testing bouncers"
INFO[13-07-2026 10:30:45] Decision '203.0.113.50' for duration '5m0s' added successfully
Agora, verifique se o bouncer de firewall aplicou a regra imediatamente. No servidor do bouncer:
sudo iptables -L crowdsec -n -v
Chain crowdsec (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 203.0.113.50 0.0.0.0/0
Para testar o bouncer do Nginx, execute um curl a partir de uma máquina com o IP banido (ou simule com -H; mas o bouncer verifica o IP real da conexão). Se você estiver na própria máquina, pode usar curl --interface lo mas o IP será 127.0.0.1. O melhor é usar outra máquina na rede ou um contêiner:
# A partir de um host externo com IP 203.0.113.50 (não roteável na prática, mas assumindo que você configurou uma VM com esse IP)
curl -v http://<IP_DO_NGINX>/
* Trying <IP_DO_NGINX>:80...
* Connected to <IP_DO_NGINX> (<IP_DO_NGINX>) port 80 (#0)
> GET / HTTP/1.1
> Host: <IP_DO_NGINX>
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: nginx/1.24.0
< Date: Mon, 13 Jul 2026 10:32:01 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
<
{ [169 bytes data]
* Connection #0 to host <IP_DO_NGINX> left intact
403 Forbidden
403 Forbidden
nginx
A resposta 403 Forbidden confirma que o módulo Lua do CrowdSec interceptou a requisição e aplicou a decisão. No Apache, o resultado será similar. Você pode inspecionar os logs de cada bouncer para detalhes:
sudo journalctl -u crowdsec-firewall-bouncer --since "2 minutes ago" --no-pager
sudo tail -50 /var/log/nginx/error.log | grep crowdsec
sudo tail -50 /var/log/httpd/error_log | grep crowdsec
Erros Comuns e Como Resolver
-
Erro de autenticação:
API key is invalidnos logs do bouncer.
Sintoma: O serviço do bouncer inicia mas imediatamente encerra ou permanece com statusdegraded.
Causa: A chave copiada docscli bouncers addcontém espaços ou foi truncada; ou a chave foi copiada para o arquivo errado (ex: firewall-bouncer.yaml recebeu a chave do nginx).
Solução: Gere novamente a chave excluindo o bouncer comsudo cscli bouncers remove <nome>e adicionando-o novamente. Copie a chave usando o terminal sem quebras de linha. Certifique-se de que o parâmetroapi_key:no YAML não possui aspas desnecessárias e que a indentação está correta. Em arquivos.conf, a sintaxe éAPI_KEY=CHAVEsem aspas. -
Bouncer não aplica regras: iptables vazio, mas
cscli decisions listmostra IPs.
Sintoma: O serviço está rodando, porém o chaincrowdsecnão contém entradas DROP.
Causa: O modo do firewall configurado não corresponde ao backend real. Em sistemas com nftables puro (Rocky Linux 9 não possui iptables-legacy instalado por padrão), o bouncer tenta usariptablese falha silenciosamente.
Solução: Instale o pacoteiptables-legacye atualize as alternativas comsudo update-alternatives --set iptables /usr/sbin/iptables-legacy, ou alteremode: iptablesparamode: nftablesno arquivo YAML. Para nftables, você pode usar o bouncer dedicadocrowdsec-firewall-bouncer-nftables. Verifique os logs comjournalctl -u crowdsec-firewall-bouncer | grep -i error. -
Erro de carregamento do módulo Lua no Nginx:
unknown directive "access_by_lua_block".
Sintoma: Ao testar a configuração do Nginx (nginx -t), o parser acusa erro nas diretivas Lua.
Causa: O módulongx_http_lua_modulenão está instalado ou não foi carregado dinamicamente. Em compilações personalizadas do Nginx, pode não estar incluso.
Solução: No Debian, instalelibnginx-mod-http-luae certifique-se de que o módulo está habilitado no arquivo/etc/nginx/modules-enabled/. No Rocky, verifique se o módulo aparece comls /usr/lib64/nginx/modules/ngx_http_lua_module.soe insira umload_moduleexplícito no topo donginx.conf. Recompile o Nginx apenas se não houver package disponível — nesse caso, utilize os binários oficiais que já incluem Lua JIT. -
Timeout ou conexão recusada:
dial tcp: connection refusednos logs do bouncer.
Sintoma: O bouncer não consegue alcançar a LAPI, mesmo com a chave correta.
Causa: A LAPI não está escutando na porta 8080 no endereço configurado, ou um firewall intermediário (incluindo o próprio iptables do host) está bloqueando a porta.
Solução:
Quer aprender na prática com especialistas?
A JRT Technology Solutions oferece treinamentos e implementação de Firewall, fail2ban e CrowdSec para equipes corporativas.