Guides
Fundamentos ▾
Versionamento ▾
Deploy ▾

Firewall no Ubuntu

Duas ferramentas complementares para proteger o servidor: UFW define o que pode entrar, fail2ban detecta e bane comportamento suspeito em tempo real.

🌐
Internet
Todo tráfego de entrada — legítimo e malicioso
🧱
UFW — Firewall Estático
Bloqueia portas fechadas. Só o que foi explicitamente permitido passa. Regras permanentes.
iptables / nftables
↓ (tráfego permitido)
🚨
fail2ban — IPS Dinâmico
Monitora logs. Detecta tentativas repetidas. Bane IPs automaticamente por tempo determinado.
monitora logs → ban/unban
↓ (tráfego sobrevivente)
⚙️
Serviços
SSH, nginx, PostgreSQL, sua aplicação
📌
Usado neste projeto

UFW e fail2ban são parte do setup padrão do servidor. Ver server/ubuntu-server-setup.md e server/ssl-https.md.

🆚 UFW vs fail2ban

🧱 UFW
Uncomplicated Firewall
Firewall estático — regras manuais
Frontend para iptables/nftables
Define quais portas estão abertas
Regras persistem até você removê-las
Não monitora comportamento
Configurado uma vez, esquecido
🚨 fail2ban
Intrusion Prevention System
IPS dinâmico — reage a eventos
Monitora arquivos de log em tempo real
Detecta N falhas em T segundos
Bane IPs automaticamente por tempo determinado
Desbaneia automaticamente após bantime
Precisa de UFW (ou iptables) para executar o ban
CaracterísticaUFWfail2ban
TipoEstáticoDinâmico
Reage a comportamento❌ Não✅ Sim
Bloqueia portas fechadas✅ Sim❌ Não diretamente
Ban por tempo❌ Não✅ Sim
Auto-desban❌ Não✅ Sim
Lê logs❌ Não✅ Sim
Precisa do outro?NãoSim (para executar o ban)

🧱 UFW — Uncomplicated Firewall

UFW é um frontend para iptables (e nftables em kernels recentes) que simplifica o gerenciamento de regras de firewall no Ubuntu/Debian. Vem instalado por padrão, mas desabilitado.

📋

Regras simples

ufw allow 22/tcp em vez de múltiplos comandos iptables.

🔄

IPv4 + IPv6

Gerencia ambos simultaneamente com os mesmos comandos.

📦

Perfis de app

Pacotes definem perfis com nome (OpenSSH, Nginx Full, etc.).

📂 UFW — Estrutura de Arquivos

/etc/ufw/
⚙️ ufw.conf editar habilitar/desabilitar, logging
📋 user.rules auto regras IPv4 definidas pelo usuário (gerado pelo ufw)
📋 user6.rules auto regras IPv6
🔒 before.rules avançado executadas ANTES das regras do usuário
🔓 after.rules avançado executadas DEPOIS das regras do usuário
📁 applications.d/ editar perfis de aplicação por nome

🚀 UFW — Configuração Inicial

🚨
Libere SSH ANTES de habilitar o UFW

Se habilitar o UFW com política deny incoming sem liberar a porta 22, você perde o acesso remoto ao servidor.

bash — ordem correta
# 1. Política padrão
sudo ufw default deny incoming   # bloqueia tudo que entra
sudo ufw default allow outgoing  # permite tudo que sai

# 2. Liberar SSH ANTES de habilitar
sudo ufw allow 22/tcp
# se mudou a porta:
sudo ufw allow 2222/tcp

# 3. Habilitar
sudo ufw enable

# 4. Verificar
sudo ufw status verbose
ufw enable
Liga o firewall
ufw disable
Desliga (sem regras)
ufw reload
Recarrega regras
ufw status
Status atual
ufw status verbose
Status detalhado
ufw status numbered
Lista com número

📋 UFW — Regras

Sintaxe básica

bash
# Porta + protocolo
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw deny 8080/tcp

# Faixa de portas
sudo ufw allow 8000:9000/tcp

# Por serviço (/etc/services)
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

# Por IP de origem
sudo ufw allow from 203.0.113.10
sudo ufw allow from 10.0.0.0/8

# IP + porta específica
sudo ufw allow from 203.0.113.10 to any port 5432   # PostgreSQL só deste IP
sudo ufw allow from 10.0.0.0/8 to any port 22/tcp   # SSH só da rede interna

# Por interface de rede
sudo ufw allow in on eth0 to any port 80
sudo ufw deny in on eth0 to any port 3306   # MySQL: só interno

allow vs deny vs reject

AçãoComportamentoQuando usar
allow Permite a conexão Serviços públicos (HTTP, HTTPS, SSH)
deny Dropa silenciosamente (DROP) — atacante não sabe se host existe Padrão — política default incoming
reject Envia RST/ICMP unreachable — cliente recebe erro imediato Apps legítimas que precisam de feedback rápido

Gerenciando regras existentes

bash
# Listar com número
sudo ufw status numbered

# Deletar por número
sudo ufw delete 3

# Deletar por descrição (inverso do add)
sudo ufw delete allow 80/tcp

# Inserir em posição específica
sudo ufw insert 1 allow from 10.0.0.0/8

# CUIDADO: reseta tudo (perde SSH se não reconfigurar)
sudo ufw reset

Setup típico — servidor web

bash — SSH + HTTP + HTTPS
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable
sudo ufw status verbose

📦 UFW — Perfis de Aplicação

Pacotes instalados registram perfis em /etc/ufw/applications.d/ com nomes amigáveis para conjuntos de portas.

bash
# Listar perfis disponíveis
sudo ufw app list

# Ver detalhes de um perfil
sudo ufw app info OpenSSH
sudo ufw app info 'Nginx Full'

# Usar perfil
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'    # HTTP + HTTPS (80 + 443)
sudo ufw allow 'Nginx HTTP'    # só porta 80
sudo ufw allow 'Nginx HTTPS'   # só porta 443

Criando perfil customizado

/etc/ufw/applications.d/myapp
[MyApp]
title=My Application
description=My custom application
ports=3000,4000/tcp

📊 UFW — Logging

bash
# Habilitar log
sudo ufw logging on

# Níveis de log
sudo ufw logging low     # conexões bloqueadas
sudo ufw logging medium  # + conexões permitidas inválidas
sudo ufw logging high    # + todas as conexões permitidas
sudo ufw logging full    # absolutamente tudo

# Ver logs
sudo tail -f /var/log/ufw.log
sudo journalctl -k --grep="UFW"

🚨 fail2ban

fail2ban monitora arquivos de log em busca de padrões suspeitos (tentativas de login falhas, scanning, etc.) e bane automaticamente os IPs ofensores usando iptables ou UFW.

👁️

Monitora logs

Lê em tempo real: /var/log/auth.log, logs do nginx, etc.

🎯

Regex por serviço

Cada "jail" tem filtros específicos para detectar falhas de autenticação.

⏱️

Ban temporário

Bane por tempo configurável. Desbaneia automaticamente. Pode incrementar a cada reincidência.

⚙️ fail2ban — Como Funciona

1
Serviço grava log
Ex: SSH registra tentativa de login falha em /var/log/auth.log
2
fail2ban aplica filtro (regex)
Detecta linhas que casam com o padrão de falha. Conta ocorrências do mesmo IP.
3
N falhas em T segundos → action
Quando atinge maxretry dentro do findtime, executa a action: adiciona regra no UFW/iptables bloqueando o IP.
4
IP banido por bantime
Qualquer tráfego do IP é bloqueado pelo tempo configurado.
5
Desban automático após bantime
fail2ban remove a regra. IP pode tentar novamente. Com ban incremental, o próximo ban dura mais.

Terminologia

TermoO que é
jailConfiguração de monitoramento para um serviço específico (ex: sshd, nginx)
filterRegex que detecta linhas de falha no log
actionO que fazer quando detecta falhas (adicionar regra UFW/iptables)
bantimePor quanto tempo o IP fica banido
findtimeJanela de tempo para contar as tentativas
maxretryQuantas falhas antes de banir
ignoreipIPs que nunca serão banidos (whitelist)

📂 fail2ban — Estrutura de Arquivos

⚠️
Nunca editar .conf diretamente

Arquivos .conf são sobrescritos em atualizações. Crie e edite sempre os correspondentes .local.

/etc/fail2ban/
⚙️ fail2ban.conf não editar config do daemon
✏️ fail2ban.local editar overrides do daemon
📋 jail.conf não editar todas as jails padrão
✏️ jail.local editar suas customizações de jail
📁 jail.d/ editar jails modulares (um arquivo por serviço)
📁 filter.d/ geralmente não editar regex por serviço (sshd.conf, nginx-http-auth.conf, ...)
📁 action.d/ geralmente não editar ações de ban (ufw.conf, iptables.conf, ...)

🔧 fail2ban — Instalação e Setup

bash
sudo apt install fail2ban -y

# Criar jail.local a partir do conf
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Habilitar e iniciar
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Verificar
sudo systemctl status fail2ban
sudo fail2ban-client status

jail.local — configuração base ([DEFAULT])

/etc/fail2ban/jail.local
[DEFAULT]
# IPs que NUNCA serão banidos
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8

# Tempo de ban
bantime  = 1h       # aceita: 30 (segundos), 1h, 1d, 1w

# Janela para contar tentativas
findtime = 10m

# Tentativas antes de banir
maxretry = 5

# Backend de leitura de logs
backend  = systemd   # ou: auto, polling, pyinotify

# Action: usar UFW em vez de iptables direto
banaction = ufw

Ban incremental — cada reincidência bane mais tempo

jail.local — [DEFAULT]
bantime.increment   = true
bantime.multiplier  = 2    # dobra a cada ban: 1h → 2h → 4h → 8h...
bantime.maxtime     = 1w   # máximo 1 semana
bantime             = 1h   # tempo inicial

🔒 fail2ban — Configurando Jails

SSH

jail.local
[sshd]
enabled  = true
port     = ssh   # ou 2222
maxretry = 3
bantime  = 1h

Nginx — auth básica

jail.local
[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 5

Nginx — limite de requests

jail.local
[nginx-limit-req]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 10
findtime = 1m
bantime  = 10m

Nginx — bots/scanning

jail.local
[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 2
bantime  = 1d

Ban times recomendados por cenário

🔑 SSH — porta pública
bantime1h
maxretry3
findtime10m
🔐 SSH — servidor crítico
bantime24h
maxretry3
findtime10m
🌐 Nginx — autenticação
bantime1h
maxretry5
findtime10m
🤖 Scanning agressivo
bantime7d
maxretry2
findtime5m

💻 fail2ban — Comandos

bash
# Status
sudo fail2ban-client status              # jails ativas
sudo fail2ban-client status sshd         # detalhes: banned IPs, total

# Ban / Unban manual
sudo fail2ban-client set sshd banip 203.0.113.50
sudo fail2ban-client set sshd unbanip 203.0.113.50

# Listar IPs banidos
sudo fail2ban-client get sshd banip

# Recarregar
sudo fail2ban-client reload              # toda configuração
sudo fail2ban-client reload sshd         # jail específica

# Logs
sudo tail -f /var/log/fail2ban.log
sudo journalctl -u fail2ban -f

# Regras geradas no iptables
sudo iptables -n -L f2b-sshd --line-numbers

# Testar filtro SEM banir
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

🎯 fail2ban — Filtros Customizados

Para proteger uma aplicação que não tem filtro padrão.

/etc/fail2ban/filter.d/myapp.conf
[Definition]
# <HOST> é substituído pelo IP capturado
failregex = ^<HOST> .* "POST /login" 401
ignoreregex =
jail.local — registrar a jail
[myapp-login]
enabled  = true
port     = 443
logpath  = /var/log/nginx/access.log
filter   = myapp
maxretry = 5
bantime  = 1h
bash — testar filtro
# Testa o regex contra o log sem executar nada
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/myapp.conf --print-all-matched

🔗 Integração UFW + fail2ban

fail2ban usa o UFW como "action" — quando detecta um IP malicioso, chama o UFW para inserir a regra de bloqueio.

jail.local — configurar banaction
[DEFAULT]
banaction = ufw   # usa UFW em vez de iptables direto

Com isso, fail2ban executa internamente:

o que fail2ban faz
# ao banir:
ufw insert 1 deny from <IP> to any

# ao desbanir:
ufw delete deny from <IP> to any
Por que banaction = ufw é preferível

Mantém visibilidade: bans aparecem em ufw status. Consistência: tudo passa pelo mesmo mecanismo de firewall. Sem conflito entre regras UFW e iptables direto.

🚀 Setup Completo — Do Zero

Sequência usada no server/ubuntu-server-setup.md deste projeto.

bash — passo a passo
# ─────────────────────────────────────────
# PASSO 1: UFW
# ─────────────────────────────────────────
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp     # SSH — ANTES de habilitar!
sudo ufw allow 80/tcp     # HTTP
sudo ufw allow 443/tcp    # HTTPS
sudo ufw enable
sudo ufw status verbose

# ─────────────────────────────────────────
# PASSO 2: fail2ban
# ─────────────────────────────────────────
sudo apt install fail2ban -y
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# Criar config modular
sudo tee /etc/fail2ban/jail.d/custom.conf > /dev/null << 'EOF'
[DEFAULT]
banaction = ufw
bantime   = 1h
maxretry  = 5
findtime  = 10m

[sshd]
enabled  = true
port     = ssh
maxretry = 3
EOF

# Iniciar
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# ─────────────────────────────────────────
# VERIFICAÇÃO
# ─────────────────────────────────────────
sudo ufw status verbose
sudo fail2ban-client status
sudo fail2ban-client status sshd

📡 Monitoramento e Diagnóstico

bash — UFW
sudo ufw status verbose
sudo ufw status numbered
sudo tail -f /var/log/ufw.log
bash — fail2ban
# Jails e IPs banidos
sudo fail2ban-client status
sudo fail2ban-client status sshd

# Logs em tempo real
sudo tail -f /var/log/fail2ban.log
sudo journalctl -u fail2ban -f

# IPs banidos agora
sudo fail2ban-client get sshd banip

# Ver regras geradas pelo fail2ban no iptables
sudo iptables -n -L f2b-sshd --line-numbers

# Testar filtro sem executar ação
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched

⚡ Referência Rápida

UFW — Controle
habilitar / desabilitar
ufw enable / disable
status
ufw status verbose
ufw status numbered
recarregar
ufw reload
UFW — Regras
abrir / fechar porta
ufw allow 80/tcp
ufw deny 80/tcp
por IP
ufw allow from 10.0.0.0/8
deletar por número
ufw delete 3
deletar por regra
ufw delete allow 80/tcp
fail2ban — Status
jails ativas
fail2ban-client status
detalhes de uma jail
fail2ban-client status sshd
recarregar
fail2ban-client reload
fail2ban — Ban/Unban
banir IP manualmente
fail2ban-client set sshd banip IP
desbanir IP
fail2ban-client set sshd unbanip IP
listar banidos
fail2ban-client get sshd banip
testar filtro
fail2ban-regex LOG FILTER

Documentação relacionada neste projeto


Referências externas

📖

fail2ban docs

fail2ban.org/wiki/MANUAL

🔐

DigitalOcean

Guias de UFW e fail2ban no Ubuntu com exemplos práticos