Dia 21: Segurança de Rede — IDS/IPS, Suricata e Zeek
ℹ Curso de Redes em 30 Dias — Dia 21 de 30. No Dia 20 falámos de monitorização com SNMP, Zabbix e PRTG; hoje subimos o nível para segurança activa. Um firewall bloqueia tráfego por regras, mas não detecta intrusões que passam por portas legítimas. IDS (Intrusion Detection System) e IPS (Intrusion Prevention System) vão mais além: analisam o conteúdo dos pacotes à procura de padrões maliciosos. Este artigo cobre as duas ferramentas open-source mais usadas em PME: Suricata (motor IDS/IPS de alta performance) e Zeek (framework de análise de tráfego orientada a scripts). Para cada uma: conceitos, instalação, configuração prática e verificação.
ℹ IDS detecta e alerta; IPS detecta e bloqueia. A diferença crítica está na posição na rede: IDS em modo promíscuo (passivo), IPS inline (activo, pode parar tráfego).
Neste artigo
- IDS vs IPS — Conceitos Fundamentais
- Suricata — Instalação e Configuração Base
- Passo 1 — Regras e Assinaturas no Suricata
- Passo 2 — Suricata em Modo IPS Inline
- Zeek — Instalação e Análise de Tráfego
- Passo 3 — Logs Zeek e Detecção de Anomalias
- Suricata vs Zeek — Comparação Prática
- Erros Comuns e Lista de Verificação
1. IDS vs IPS — Conceitos Fundamentais
Um firewall filtra pacotes por endereço, porta e estado da ligação — é a primeira linha de defesa. Mas um firewall não inspeciona o conteúdo dos pacotes. Um ataque HTTP que passa pela porta 80 legítima não é bloqueado pelo firewall. Aqui entram IDS e IPS: sistemas que analisam o payload dos pacotes à procura de assinaturas conhecidas de ataques, anomalias de protocolo ou comportamentos suspeitos.
Analogia: o firewall é o guarda do portão que verifica a identidade de quem entra. O IDS é a câmara de vigilância que regista tudo e alerta se vir algo suspeito. O IPS é o guarda dentro do edifício que pode parar um intruso a meio da acção.
| Característica | IDS (Detection) | IPS (Prevention) |
|---|---|---|
| Posição na rede | Modo promíscuo (porta SPAN/mirror) | Inline (tráfego passa pelo sensor) |
| Acção sobre tráfego malicioso | Apenas alerta (log + notificação) | Bloqueia ou derruba a ligação |
| Impacto na rede se falhar | Nenhum — tráfego continua a fluir | Pode parar todo o tráfego (ponto único de falha) |
| Latência introduzida | Zero (não está no caminho) | Pequena (análise em tempo real) |
| Caso de uso típico | Auditoria, forense, detecção pós-facto | Protecção activa em tempo real |
A escolha entre IDS e IPS depende da tolerância a latência e do risco de falsos positivos. Num ambiente de produção onde um falso positivo bloqueia tráfego legítimo, começa-se com IDS (passivo) para afinar as regras e só depois migra-se para IPS (activo). O Suricata suporta ambos os modos com a mesma configuração base — basta mudar a interface de captura (documentação oficial Suricata).
O Zeek (anteriormente Bro) tem uma abordagem diferente: não é um motor de assinaturas como o Suricata, mas sim um framework de análise de tráfego que regista metadados detalhados de todas as ligações. Em vez de procurar padrões conhecidos, o Zeek permite escrever scripts que detectam comportamentos anómalos — por exemplo, ligações DNS para domínios recém-registados, transferências de ficheiros grandes fora de horas, ou scans de portas internas (documentação oficial Zeek).
2. Suricata — Instalação e Configuração Base
O Suricata é um motor IDS/IPS de alta performance desenvolvido pela Open Information Security Foundation (OISF). Suporta inspecção de tráfego em multi-thread, processamento a 10+ Gbps e integração com Emerging Threats para regras actualizadas. É a alternativa open-source mais utilizada em PME e em soluções comerciais como OPNsense (site oficial, GitHub).
Pré-requisitos: um servidor Linux com pelo menos 2 GB de RAM, uma interface de rede com suporte para captura em modo promíscuo (para IDS) ou NFQueue (para IPS), e acesso root.
| Requisito | Detalhe |
|---|---|
| Sistema operativo | Debian 12+, Ubuntu 22.04+, RHEL 9+, Fedora 39+ |
| RAM mínima | 2 GB (4 GB recomendado para IPS em produção) |
| Dependências | libpcap, libnetfilter-queue, libnfnetlink, python3, jq |
| Permissões | root para instalação; utilizador suricata para execução |
A instalação varia conforme a distribuição. Em Debian/Ubuntu, o pacote nos repositórios oficiais é funcional mas pode não ser a versão mais recente. Para produção, recomenda-se o PPA oficial Suricata (Debian package, Arch Wiki).
# Ubuntu/Debian — instalar Suricata via PPA oficial
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update
sudo apt install suricata jq
# Fedora/RHEL
sudo dnf install suricata jq
# Arch Linux
sudo pacman -S suricata jq
O que cada linha faz:
add-apt-repository ppa:oisf/suricata-stable— adiciona o repositório oficial da OISF com a versão estável mais recentejq— processador JSON necessário para ler os alertas do EVE JSON (formato de saída do Suricata)
Após a instalação, verificar a versão e o ficheiro de configuração principal:
# Verificar versao instalada
suricata --build-info | head -5
# Configuracao principal em /etc/suricata/suricata.yaml
# Verificar interface de captura pre-definida
grep -E "interface|af-packet" /etc/suricata/suricata.yaml | head -10
3. Passo 1 — Regras e Assinaturas no Suricata
O Suricata sem regras não detecta nada. As regras (assinaturas) são padrões que descrevem tráfego malicioso — semelhante às assinaturas de um antivírus. Existem três fontes principais: o conjunto Emerging Threats (ET Open, gratuito), o conjunto ET Pro (subscrição) e regras customizadas. A ferramenta suricata-update gere a transferência e actualização automática (documentação de regras, Emerging Threats).
# Actualizar fontes de regras
sudo suricata-update update-sources
# Listar fontes disponiveis
sudo suricata-update list-sources
# Adicionar ET Open (gratuito) — ja vem por defeito
sudo suricata-update enable-source et/open
# Adicionar ET Pro Telemetry (gratuito com registo)
sudo suricata-update enable-source et/telemetry
# Transferir e aplicar regras
sudo suricata-update
# Verificar numero de regras carregadas
sudo suricata-update --list-rules | wc -l
O que cada comando faz:
update-sources— actualiza o índice de fontes de regras disponíveis no repositório Suricataenable-source et/open— activa o conjunto Emerging Threats Open (gratuito, ~30 000 regras)suricata-update— transfere as regras, converte formato se necessário, e instala em/var/lib/suricata/rules/
A sintaxe de uma regra Suricata segue o formato padronizado de assinaturas de IDS. Uma regra típica tem cabeçalho (acção, protocolo, endereços, portas) e opções (mensagem, conteúdo, referências):
# Exemplo: detectar tentativa de SQL injection em HTTP
alert http any any -> $HOME_NET any (msg:"SQL Injection Attempt - UNION SELECT"; content:"UNION"; nocase; content:"SELECT"; nocase; distance:within 50; sid:1000001; rev:1; classtype:web-application-attack;)
# Exemplo: detectar scan de portas TCP SYN
alert tcp $EXTERNAL_NET any -> $HOME_NET any (flags:S,12; detection_filter:track by_src, count 30, seconds 10; msg:"TCP Port Scan"; sid:1000002; rev:1; classtype:attempted-recon;)
# Regra personalizada para detectar ficheiros executaveis em HTTP
alert http any any -> $HOME_NET any (msg:"Windows Executable Transfer over HTTP"; file_data; content:"MZ"; byte_test:2,=,0x5a4d,0; sid:1000003; rev:1;)
Explicação dos campos principais:
alert— acção: gerar alerta. Outras opções:drop(bloquear em IPS),pass(ignorar),reject(rejeitar com RST)$HOME_NET— variável definida no suricata.yaml que representa a rede interna a protegercontent:"UNION"— procura a string “UNION” no payloadnocase— case-insensitive (procura “union”, “Union”, “UNION”)sid— Suricata ID, identificador único da regra (1000000+ para regras customizadas)classtype— categoria da regra (web-application-attack, attempted-recon, trojan-activity, etc.)
⚠ Atenção: regras com drop em modo IPS bloqueiam tráfego em tempo real. Testar sempre em modo IDS (alert) primeiro para evitar falsos positivos que cortam ligações legítimas.
4. Passo 2 — Suricata em Modo IPS Inline
O modo IDS usa captura passiva (porta SPAN no switch ou modo promíscuo na interface) — não interfere com o tráfego. O modo IPS coloca o Suricata no caminho do tráfego usando NFQueue (Netfilter Queue) no Linux. Isto permite que o Suricata bloqueie pacotes maliciosos antes de chegarem ao destino. A configuração inline requer duas peças: o suricata.yaml e as regras de nftables/iptables que enviam tráfego para a queue (configuração Suricata YAML).
Analogia: no modo IDS, o Suricata é um observador que vê o tráfego passar e toma nota. No modo IPS, é um controlador de fronteira: todo o tráfego tem de passar por ele para ser analisado antes de continuar.
# 1. Editar suricata.yaml para modo NFQ
sudo nano /etc/suricata/suricata.yaml
# Na secao nfq, garantir:
nfq:
mode: accept
repeat-mark: 1
repeat-cnt: 3
route-queue: -2
batchcount: 20
batchsize: 16000
# 2. Regras nftables para enviar tráfego para a queue
# Criar ficheiro /etc/nftables.d/suricata-ips.nft
table inet suricata-ips {
chain input {
type filter hook input priority -10; policy accept;
counter queue num 0 bypass
}
chain forward {
type filter hook forward priority -10; policy accept;
counter queue num 0 bypass
}
chain output {
type filter hook output priority -10; policy accept;
counter queue num 0 bypass
}
}
# 3. Aplicar regras nftables
sudo nft -f /etc/nftables.d/suricata-ips.nft
# 4. Iniciar Suricata em modo NFQ
sudo suricata -c /etc/suricata/suricata.yaml -q 0 -D
# 5. Verificar processo activo
ps aux | grep suricata
sudo journalctl -u suricata -f --no-pager | head -20
O que cada elemento faz:
mode: accept— se o Suricata falhar, o tráfego continua a fluir (bypass). A alternativamode: repeatre-envia pacotes não verificadosqueue num 0 bypass— envia pacotes para a queue 0;bypassgarante que se o Suricata parar, o tráfego não fica bloqueado-q 0— escuta na NFQueue número 0 (mesma queue das regras nftables)-D— modo daemon (corre em background)
⚠ Atenção: o modo IPS inline torna o Suricata um ponto único de falha. Se o processo parar com mode: repeat (sem bypass), todo o tráfego para. Usar sempre bypass nas regras nftables em produção e monitorizar o processo com systemd ou supervisor.
5. Zeek — Instalação e Análise de Tráfego
O Zeek (anteriormente Bro) é um framework de análise de tráfego de rede desenvolvido originalmente no Lawrence Berkeley National Laboratory. Ao contrário do Suricata, que é orientado a assinaturas (procurar padrões conhecidos), o Zeek é orientado a scripts: regista metadados de todas as ligações e permite escrever lógica customizada para detectar comportamentos anómalos. É a ferramenta preferida para análise forense e detecção de ameaças avançadas (site oficial, GitHub).
Analogia: o Suricata é um cão de caça treinado para reconhecer ladrões específicos (assinaturas). O Zeek é uma câmara inteligente que regista tudo o que se passa e permite definir regras personalizadas: “alerta se alguém entrar fora de horas” ou “alerta se houver transferências grandes para o exterior”.
# Ubuntu/Debian — instalar Zeek via repositorio oficial
sudo wget -O /etc/apt/trusted.gpg.d/zeek.gpg https://download.zeek.org/gpg/key
echo "deb [signed-by=/etc/apt/trusted.gpg.d/zeek.gpg] https://download.zeek.org/debian stable main" | sudo tee /etc/apt/sources.list.d/zeek.list
sudo apt update
sudo apt install zeek
# Fedora/RHEL
sudo dnf install zeek
# Arch Linux (via AUR)
yay -S zeek
Após a instalação, adicionar o directório de binários ao PATH e verificar:
# Adicionar ao PATH (Ubuntu/Debian)
export PATH=$PATH:/opt/zeek/bin
# Verificar versao
zeek --version
# Configurar interface de captura em /opt/zeek/etc/node.cfg
# Para modo standalone com captura na interface eth0:
sudo nano /opt/zeek/etc/node.cfg
[zeek-logger]
type=logger
host=localhost
[zeek-manager]
type=manager
host=localhost
[zeek-proxy-1]
type=proxy
host=localhost
[zeek-worker-1]
type=worker
host=localhost
interface=eth0
# Iniciar Zeek em modo cluster
sudo /opt/zeek/bin/zeekctl deploy
# Verificar status
sudo /opt/zeek/bin/zeekctl status
O que cada componente do cluster faz:
- logger — recebe e escreve os ficheiros de log de todos os workers (centralização)
- manager — coordena o cluster, mantém estado global, distribui configuração
- proxy — intermediário de comunicação entre manager e workers (reduz carga no manager)
- worker — processo que captura e analisa tráfego numa interface; pode haver múltiplos (um por interface ou por CPU core)
6. Passo 3 — Logs Zeek e Detecção de Anomalias
O Zeek gera dezenas de ficheiros de log em formato TSV (tab-separated), cada um cobrindo um aspecto do tráfego. Estes logs ficam em /opt/zeek/logs/current/ durante a execução e são arquivados diariamente em /opt/zeek/logs/YYYY-MM-DD/. A documentação completa de todos os logs está no manual de referência do Zeek.
| Ficheiro de Log | Conteúdo | Caso de Uso |
|---|---|---|
| conn.log | Todas as ligações (IP origem/destino, porta, duração, bytes) | Base para qualquer análise de tráfego |
| dns.log | Queries e respostas DNS | Detectar DNS tunneling, C2, domínios suspeitos |
| http.log | Pedidos e respostas HTTP (URL, user-agent, MIME) | Detectar downloads maliciosos, C2 HTTP |
| ssl.log | Ligações TLS/SSL (SNI, cipher, certificado) | Detectar certificados auto-assinados, JA3 fingerprinting |
| files.log | Ficheiros transferidos via HTTP, FTP, SMB, etc. | Detectar transferências de executáveis, exfiltração |
| weird.log | Comportamentos anómalos de protocolo | Detectar scans, floods, ataques de protocolo |
Para análise prática, o log conn.log é o ponto de partida. Contém todas as ligações de rede com timestamps, IPs, portas, duração e volumes de dados transferidos. Com jq ou zeek-cut podemos extrair padrões:
# Listar logs activos
ls -la /opt/zeek/logs/current/
# Top 10 IPs de origem com mais ligacoes
zeek-cut id.orig_h < /opt/zeek/logs/current/conn.log | sort | uniq -c | sort -rn | head -10
# Ligacoes para portas nao standard (suspeitas de C2)
zeek-cut id.orig_h id.resp_h id.resp_p < /opt/zeek/logs/current/conn.log | awk '$3 < 1024 || $3 > 49151' | sort | uniq -c | sort -rn | head -20
# Queries DNS para dominios com TLD suspeito
zeek-cut query < /opt/zeek/logs/current/dns.log | grep -E '\.(xyz|top|click|loan|work)$' | sort | uniq -c | sort -rn
# Transferencias de ficheiros executaveis via HTTP
zeek-cut id.orig_h id.resp_h mime_type < /opt/zeek/logs/current/http.log | grep -i executable
# Ligacoes SSH para IPs externos
zeek-cut id.orig_h id.resp_h < /opt/zeek/logs/current/ssh.log | sort | uniq -c | sort -rn
O que cada comando faz:
zeek-cut id.orig_h— extrai a coluna do IP de origem do conn.log (formato TSV)sort | uniq -c | sort -rn— conta ocorrências por IP e ordena por frequência descendente (top talkers)- O filtro
awk '$3 < 1024 || $3 > 49151'— destaca ligações para portas fora das gamas standard (0-1023 bem conhecidas, 49152+ efémeras) grep -E '\.(xyz|top|click...)'— procura TLDs frequentemente associados a malware e phishing
O Zeek também suporta scripts personalizados para detecção em tempo real. Um script básico para alertar sobre scans de portas internas:
# Ficheiro: /opt/zeek/share/zeek/site/detect-port-scan.zeek
@load base/protocols/conn
global port_scan_threshold = 20;
global port_scan_window: interval = 60sec;
global port_scans: table[addr] of count = {};
event new_connection(c: connection)
{
if (c$id$orig_h !in 10.0.0.0/8 && c$id$orig_h !in 192.168.0.0/16)
return;
if (c$id$resp_h in 10.0.0.0/8 || c$id$resp_h in 192.168.0.0/16)
{
if (c$id$orig_h in port_scans)
port_scans[c$id$orig_h] += 1;
else
port_scans[c$id$orig_h] = 1;
if (port_scans[c$id$orig_h] == port_scan_threshold)
{
print fmt("ALERTA: Possivel scan de portas de %s (%d ligacoes em 60s)",
c$id$orig_h, port_scans[c$id$orig_h]);
}
}
}
event zeek scheduled port_scan_cleanup()
{
port_scans = {};
}
schedule port_scan_cleanup { port_scan_window };
Este script conta ligações por IP de origem numa janela de 60 segundos. Quando um IP interno excede 20 ligações para outros hosts internos, gera um alerta. Para activar o script, adicioná-lo ao local.zeek:
# Adicionar a /opt/zeek/share/zeek/site/local.zeek
@load detect-port-scan
# Reiniciar Zeek para carregar o script
sudo /opt/zeek/bin/zeekctl restart
# Verificar alertas no log de notificacoes
tail -f /opt/zeek/logs/current/notice.log
7. Suricata vs Zeek — Comparação Prática
Embora ambos analisem tráfego de rede, Suricata e Zeek têm filosofias diferentes e são frequentemente usados em conjunto. O Suricata é um motor de assinaturas optimizado para performance e blocking em tempo real. O Zeek é um framework de análise que regista metadados ricos e permite detecção comportamental customizada. A combinação dos dois é o padrão em Security Operations Centers (SOC) de PME.
| Critério | Suricata | Zeek |
|---|---|---|
| Tipo principal | IDS/IPS por assinaturas | Framework de análise de tráfego |
| Modo IPS inline | Sim (NFQueue) | Não (apenas passivo) |
| Detecção | Padrões conhecidos (assinaturas) | Comportamentos anómalos (scripts) |
| Formato de saída | EVE JSON (alertas + metadados) | TSV (dezenas de logs por protocolo) |
| Performance | 10+ Gbps com multi-thread | 1-10 Gbps consoante scripts activos |
| Curva de aprendizagem | Média (sintaxe de regras padronizada) | Alta (linguagem de scripts própria) |
| Integração SIEM | EVE JSON nativo (Splunk, ELK, Wazuh) | TSV convertível; json-streams disponível |
| Melhor para | Protecção activa, compliance, blocking | Forense, threat hunting, baseline de tráfego |
A estratégia recomendada para PME é usar os dois em camadas: Suricata em modo IPS no perímetro (firewall/gateway) para bloquear ameaças conhecidas, e Zeek em modo passivo (SPAN do switch core) para análise comportamental e forense. O Dia 20 deste curso cobre plataformas de monitorização que podem receber os logs de ambos.
8. Erros Comuns e Lista de Verificação
Os problemas mais frequentes ao implementar Suricata e Zeek em ambientes PME:
| Problema | Causa | Solução |
|---|---|---|
| Suricata não gera alertas | Interface de captura incorrecta no suricata.yaml | Confirmar interface com ip a e corrigir a secção af-packet |
| Alertas em excesso (milhares por hora) | Regras ET Open sem filtro; $HOME_NET mal definido | Definir $HOME_NET corretamente no suricata.yaml; usar threshold.conf para suprimir regras ruidosas |
| Zeek não regista tráfego | Interface em node.cfg incorrecta ou sem permissões | Verificar interface em /opt/zeek/etc/node.cfg; correr zeekctl status |
| IPS bloqueia tráfego legítimo | Falsos positivos em regras drop |
Mudar regras problemáticas para alert; testar em IDS antes de IPS |
| Performance degradada em IPS | Batch size pequeno; CPU insuficiente | Aumentar batchsize no suricata.yaml; afinar runmode: workers |
| Logs Zeek ocupam demasiado espaço | Rotação não configurada | Configurar LogRotationInterval e compressão; arquivar logs antigos |
Antes de considerar a implementação completa, confirmar cada ponto:
- ✓ Suricata instalado e versão verificada com
suricata --build-info - ✓ Regras ET Open actualizadas com
suricata-update - ✓ Variável $HOME_NET definida correctamente no suricata.yaml
- ✓ Interface de captura confirmada (IDS passivo ou IPS via NFQueue)
- ✓ EVE JSON a ser gerado em
/var/log/suricata/eve.json - ✓ Zeek instalado e cluster activo (
zeekctl statusmostra workers running) - ✓ Logs Zeek a ser escritos em
/opt/zeek/logs/current/ - ✓ Rotação de logs configurada (evitar disco cheio)
- ✓ IPS testado em modo IDS antes de activar blocking
- ✓ Scripts Zeek customizados testados em ambiente de staging
- ✓ Integração com SIEM/monitorização configurada (ver Dia 20)
# Verificacao rapida do Suricata
sudo systemctl status suricata
sudo tail -5 /var/log/suricata/eve.json | jq . | head -30
# Verificacao rapida do Zeek
sudo /opt/zeek/bin/zeekctl status
ls -la /opt/zeek/logs/current/conn.log
No próximo dia (Dia 22) abordaremos redes overlay — VXLAN, GENEVE e SD-WAN, tecnologias que criam redes virtuais por cima de infraestruturas existentes. Para complementar este artigo, o Dia 27 do Curso de Linux cobre hardening de sistema com fail2ban, auditd e Lynis — a camada de segurança do host que complementa a segurança de rede abordada aqui.
Artigos relacionados:
- Dia 11: Firewalls de Rede — iptables, nftables, pfSense e OPNsense
- Dia 19: Diagnóstico de Rede — tcpdump, Wireshark e traceroute
- Dia 20: Monitorização de Rede — SNMP, Zabbix e PRTG
- OPNsense: Firewall Open-Source com IDS/IPS para PME
- Dia 27 (Curso Linux): Segurança e Hardening — CIS, fail2ban e Lynis