Guia de Início Rápido — EzyShield
Coloque o EzyShield rodando no seu servidor em menos de 5 minutos.
1. Requisitos
| Requisito | Versão mínima |
|---|---|
| Linux | kernel 4.x+ |
| nftables | 0.9+ |
2. Instalação
Instalação rápida (recomendado)
curl -sfL https://get.ezyshield.com | sudo shIsso baixa os binários mais recentes ezyshield e ezyshield-enforcer, verifica a assinatura cosign do checksum quando o cosign está instalado (caindo para uma verificação de checksum SHA-256 simples caso contrário), e os instala.
Para instalar uma versão específica:
curl -sfL https://get.ezyshield.com | sudo EZYSHIELD_VERSION=v0.1.0 shBuild from source
Requer Go 1.26+.
git clone https://github.com/evertramos/ezy-shield.git
cd ezy-shield
go build -o ezyshield ./cmd/ezyshield
go build -o ezyshield-enforcer ./cmd/ezyshield-enforcer
sudo mv ezyshield ezyshield-enforcer /usr/local/bin/Verificar
ezyshield version3. Setup inicial
ezyshield init
Executa o wizard interativo: detecta o ambiente, grava arquivos de configuração, instala units systemd e inicia o EzyShield em modo dry-run.
sudo ezyshield initIsso cria:
/etc/ezyshield/config.yaml/etc/ezyshield/policy.yaml/etc/ezyshield/rules.d/(customizações de regras via drop-in; instalações WordPress também recebem um template de tuning comentado10-wordpress.yaml)/etc/ezyshield/.env(chave de API do AI, modo 0600)/etc/systemd/system/ezyshield.service.d/env.conf(drop-in systemd)/var/lib/ezyshield/(dados de runtime, SQLite)
Dica: Se os arquivos de config já existirem,
ezyshield initsai imediatamente listando os caminhos conflitantes. Remova-os e rode novamente.
Chave de API do provedor de AI
Quando você ativa a análise por AI, o wizard solicita sua chave de API. A chave é armazenada em /etc/ezyshield/.env (modo 0600) — nunca em arquivos de configuração ou logs.
Provedores suportados:
| Provedor | Variável de ambiente |
|---|---|
anthropic | ANTHROPIC_API_KEY |
openai | OPENAI_API_KEY |
ollama | (sem chave) |
Use --yes para modo não-interativo (grava um placeholder que você edita depois).
ezyshield doctor
Valida a configuração e verifica dependências:
sudo ezyshield doctorSaída esperada:
[PASS] config.yaml: exists
[PASS] config.yaml: parses
[PASS] policy.yaml: exists
[PASS] policy.yaml: parses
[PASS] nft: binary present
[PASS] journald: readable
[PASS] enforcer: socket connectivity4. Configuração — config.yaml
Arquivo principal em /etc/ezyshield/config.yaml.
Collectors (fontes de log)
collectors:
- kind: journald
unit: sshd
- kind: file
path: /var/log/nginx/access.logTipos disponíveis:
journald— requer campounit(nome do serviço systemd)file— requer campopath(caminho do arquivo de log)
Enforce (enforcement local)
enforce:
nftables:
table: inet ezyshield
set: blockedO helper privilegiado (ezyshield-enforcer) lida com todas as escritas no firewall via unix socket. O daemon re-sincroniza o conjunto completo de bans para o enforcer sempre que o daemon reinicia, então os bans sobrevivem a reinícios do daemon. Reiniciar apenas o helper ezyshield-enforcer não dispara essa re-sincronização por si só — o conjunto de bans se atualiza no próximo ciclo periódico de expiração de bans, ou no próximo reinício do daemon.
AI (opcional)
ai:
provider: anthropic
model: claude-haiku-4-5-20251001
api_key: env:ANTHROPIC_API_KEY
ambiguous_band: [30, 75]
token_budget_daily: 500000Importante: Segredos devem usar referências
env:NOME_DA_VARIAVEL. Valores inline são rejeitados na carga do config.
5. Configuração — policy.yaml
Arquivo em /etc/ezyshield/policy.yaml. Controla o comportamento de bloqueio.
armed (modo de operação)
armed: false # dry-run (padrão) — nenhum bloqueio real
# armed: true # ativar somente após validar com 'ezyshield doctor'Allowlist
IPs e CIDRs que nunca serão bloqueados:
allowlist:
- 192.168.1.0/24
- 10.0.0.1
admin_cidrs:
- 203.0.113.50/32 # seu IP de acesso SSHStrike table (escalação de bans)
strikes:
- ttl: 5m # strike 1 — 5 minutos
- ttl: 1h # strike 2 — 1 hora
- ttl: 24h # strike 3 — 24 horas
- ttl: 168h # strike 4 — 7 dias
- ttl: 0 # strike 5 — permanenteCada strike representa um episódio de ataque, não uma requisição individual. Enquanto um IP já está banido, novas detecções são suprimidas até o ban expirar.
Thresholds
ban_threshold: 70 # score ≥ 70 → aplica strike
observe_threshold: 40 # score 40–69 → log/notifica, sem ban
max_bans_per_minute: 30 # segurança: pausa enforcement se exceder6. Regras customizadas — drop-ins em rules.d
As regras de detecção são embutidas no binário e atualizam com ele. Para ajustar ou adicionar regras, coloque um arquivo *.yaml em /etc/ezyshield/rules.d/ — as entradas fazem merge sobre as regras embutidas por name e sobrevivem a updates. Guia completo: Customizando Regras de Detecção.
Estrutura de uma regra
rules:
- name: ssh_bruteforce
description: "Falhas de autenticação SSH repetidas"
kinds: [ssh_fail, ssh_invalid_user]
window: 60s
threshold: 5
score: 85
category: bruteforceCampos
| Campo | Descrição |
|---|---|
name | Identificador único da regra |
description | Descrição legível |
kinds | Tipos de evento que ativam a regra |
window | Janela de tempo para contagem |
threshold | Ocorrências para disparar |
score | Pontuação atribuída (0–100) |
category | Categoria (bruteforce, scanner, etc.) |
field | Campo do evento para filtro (opcional) |
value | Valor exato do campo (opcional) |
contains | Match de substring (opcional) |
contains_any | Match de substring qualquer-um (opcional) |
field e um matcher (value, contains ou contains_any — mutuamente exclusivos) só funcionam em par: uma regra que define um sem o outro é rejeitada no carregamento. Sem essa checagem de par, um matcher sozinho contaria todo evento dos kinds listados, e um field sozinho nunca dispararia.
Exemplo: bloquear scanners de API
- name: api_scanner
description: "Varredura de endpoints inexistentes"
kinds: [http_request]
field: status
value: "404"
window: 30s
threshold: 15
score: 75
category: scannerNota: Um drop-in só toca as regras que ele nomeia — todo o resto continua recebendo updates do binário. Um drop-in inválido impede o daemon de iniciar (fail-closed). O
rules_pathlegado (substituição do arquivo inteiro) está deprecated.
7. Notificações
Telegram
- Crie um bot via @BotFather e obtenha o token.
- Adicione o bot ao grupo/canal e obtenha o
chat_id. - Configure em
config.yaml:
notify:
rate_limit_per_minute: 5
dedup_window_sec: 600
telegram:
bot_token: env:EZYSHIELD_TELEGRAM_BOT_TOKEN
chat_ids:
- "-1001234567890"
severity: [] # vazio = todas; ou: [warn, critical]Email (SMTP)
email:
from: ezyshield@seudominio.com
to:
- admin@seudominio.com
host: smtp.seudominio.com
port: 587
username: ezyshield@seudominio.com
password: env:EZYSHIELD_SMTP_PASSWORD
tls: starttls # starttls | tls | none
severity: []8. Testar notificações
Valide o envio sem precisar de um evento real:
sudo ezyshield test notifier telegram
sudo ezyshield test notifier email9. Rodar o daemon
sudo ezyshield runEnquanto armed: false, o EzyShield opera em dry-run: processa tudo, registra strikes e bans simulados para que a escalada espelhe a produção exatamente (ADR-0009), e registra o que seria bloqueado, sem tocar no firewall.
Como serviço (systemd)
sudo systemctl enable --now ezyshield-enforcer
sudo systemctl enable --now ezyshieldChecklist antes de armar
- ✅
ezyshield doctor— sem erros - ✅
allowlistcom seus IPs de acesso - ✅
admin_cidrscom seu IP SSH - ✅ Notificações testadas com
test notifier - ✅ Rodou em dry-run, revisou os logs
- ⬜ Rodar
sudo ezyshield arm --for 1h(pre-flight + janela de auto-reversão), depoissudo ezyshield arm --keepquando estiver confiante