Linux: Firewall e Segurança — ufw / SSH Hardening / fail2ban
Poucos minutos depois de colocar um servidor Linux novo na internet, ele já vai ser varrido e alvo de tentativas de ataque. Endurecimento de segurança não é opcional — é obrigatório.
📋 Pré-requisitos: Você já deve conhecer
- Aula 23: Fundamentos de Rede
1. O Que Você Vai Aprender
- Configuração básica de regras do ufw
- Autenticação por chave SSH
- Hardening de SSH
- Proteção contra brute-force com fail2ban
- Atualizações automáticas de segurança
2. A História Real de Quem Foi Atacado
(1) O Problema: Tentativas de Brute-Force no Segundo Dia
O Xiaoming comprou um servidor na nuvem pra hospedar o blog dele. No segundo dia, ao olhar os logs, levou um susto:
grep "Failed password" /var/log/auth.log | wc -l
# 1234 tentativas!
Scanners automatizados do mundo inteiro tentavam fazer login na porta 22 do SSH sem parar.
(2) Três Camadas de Hardening
Ele fez três coisas:
# 1. Trocar pra autenticação por chave
ssh-keygen -t ed25519
ssh-copy-id user@server
# 2. Desabilitar login por senha
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
# 3. Instalar o fail2ban: 5 falhas → banimento de 24 horas
sudo apt install fail2ban
sudo systemctl enable fail2ban
(3) O Benefício: Ataques Caíram Para Zero
Depois do hardening, as tentativas com falha no auth.log caíram de mais de 1000 por dia para zero.
3. Pontos-Chave
(1) ufw — Firewall Descomplicado
# Operações básicas
sudo ufw status # Ver o status
sudo ufw enable # Habilitar o firewall
sudo ufw disable # Desabilitar o firewall
sudo ufw reload # Recarregar as regras
# Gerenciamento de regras
sudo ufw allow 22/tcp # Liberar SSH
sudo ufw allow 80/tcp # Liberar HTTP
sudo ufw allow 443/tcp # Liberar HTTPS
sudo ufw deny 23/tcp # Bloquear Telnet
sudo ufw deny from 10.0.0.100 # Bloquear IP específico
# Perfis de aplicação
sudo ufw app list # Listar aplicações
sudo ufw allow "Nginx Full" # Liberar Nginx (80+443)
sudo ufw allow "OpenSSH" # Liberar SSH
# Gerenciamento de regras
sudo ufw status numbered # Mostrar regras numeradas
sudo ufw delete 2 # Apagar a regra 2
allow from 0.0.0.0/0 antes de deny from malicious_ip, o deny nunca dispara — o allow já casou antes. Fique de olho na ordem das regras e use ufw status numbered pra conferir a lista.
ufw allow from pra especificar IPs confiáveis, nunca use 0.0.0.0/0 (libera todo mundo) — é o mesmo que não restringir e anula a função do firewall. Sempre use IPs concretos ou faixas CIDR, tipo ufw allow from 192.168.1.0/24.
Política de Segurança Para Servidor Novo:
ufw default deny incoming significa que toda conexão de entrada é negada por padrão — é uma abordagem de whitelist em que só as portas liberadas com allow ficam acessíveis. É a política padrão mais segura, mas você precisa liberar o SSH (22/tcp) antes de ativar, senão você se tranca pra fora do servidor.
# Negar tudo que vem de fora por padrão
sudo ufw default deny incoming
# Permitir todo o tráfego de saída por padrão
sudo ufw default allow outgoing
# Só abrir as portas necessárias
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
(2) Autenticação Por Chave SSH
# Gerar par de chaves (Ed25519 é o recomendado)
ssh-keygen -t ed25519 -C "seu_email@example.com"
# RSA tradicional (4096 bits)
ssh-keygen -t rsa -b 4096 -C "seu_email@example.com"
# Copiar a chave pública pro servidor
ssh-copy-id usuario@ip-do-servidor
# Ou adicionar manualmente
cat ~/.ssh/id_ed25519.pub | ssh usuario@ip-do-servidor "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Verificar o login por chave
ssh usuario@ip-do-servidor
(3) Hardening do SSH
ufw allow 2222/tcp), senão o firewall bloqueia as conexões na porta nova. Mantenha uma sessão SSH aberta enquanto faz as mudanças, como segurança.
Edite o /etc/ssh/sshd_config:
Port 2222 # Mudar a porta padrão (dribla varreduras automatizadas)
PermitRootLogin no # Desabilitar login direto como root
PasswordAuthentication no # Desabilitar login por senha
PubkeyAuthentication yes # Habilitar login por chave
AllowUsers alice bob # Só permitir usuários específicos
MaxAuthTries 3 # Máximo de tentativas de autenticação
ClientAliveInterval 60 # Intervalo de keepalive do cliente (segundos)
ClientAliveCountMax 3 # Máximo de falhas de keepalive
Validar a configuração e reiniciar:
sudo sshd -t # Testar a sintaxe da config
sudo systemctl restart sshd # Reiniciar o serviço SSH
(4) fail2ban
jail.conf do fail2ban vem com o pacote e pode ser sobrescrito em atualizações. Coloque as configurações customizadas em jail.local ou no diretório /etc/fail2ban/jail.d/ — esses arquivos não são sobrescritos em upgrades e têm prioridade maior.
# Instalar
sudo apt install fail2ban
# Ver o status
sudo fail2ban-client status
sudo fail2ban-client status sshd
# Config padrão (/etc/fail2ban/jail.conf), normalmente não precisa mexer
# [sshd]
# enabled = true
# port = ssh
# filter = sshd
# logpath = /var/log/auth.log
# maxretry = 5
# bantime = 3600
# Criar override local
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo systemctl restart fail2ban
# Ver os IPs banidos
sudo iptables -L f2b-sshd -n
(5) ▶ Exemplo: Configuração Completa do ufw
# Se o SSH está conectado, libere o SSH primeiro
sudo ufw allow 22/tcp
# Configurar políticas padrão
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Abrir portas de serviço
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 2222/tcp # Caso a porta do SSH tenha sido mudada
# Habilitar
sudo ufw enable
sudo ufw status verbose
Saída:
TEXTRule added Rule added Default incoming policy changed to 'deny' Default outgoing policy changed to 'allow' Rule added Rule added Rule added Firewall is active and enabled on system startup Status: active Logging: on (low) To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 2222/tcp ALLOW IN Anywhere
(6) ▶ Exemplo: Criação e Uso de Chaves SSH
# 1. Gerar par de chaves na máquina local
ssh-keygen -t ed25519
# 2. Copiar pro servidor
ssh-copy-id -i ~/.ssh/id_ed25519.pub alice@192.168.1.100
# 3. Testar login sem senha
ssh alice@192.168.1.100
# 4. Usar o arquivo de config do SSH pra simplificar o login
cat >> ~/.ssh/config << 'EOF'
Host myserver
HostName 192.168.1.100
User alice
Port 2222
IdentityFile ~/.ssh/id_ed25519
EOF
# Agora dá pra usar o atalho
ssh myserver
Saída:
TEXTGenerating public/private ed25519 key pair. Enter file in which to save the key (/home/alice/.ssh/id_ed25519): Your identification has been saved in /home/alice/.ssh/id_ed25519 Your public key has been saved in /home/alice/.ssh/id_ed25519.pub The key fingerprint is: SHA256:abc123def456 alice@workstation /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alice/.ssh/id_ed25519.pub" Number of key(s) added: 1 Now try logging into the machine: ssh alice@192.168.1.100 Welcome to Ubuntu 22.04.3 LTS Last login: Tue Jul 7 10:23:45 2026
(7) ▶ Exemplo: Hardening de SSH Na Prática
# Backup da config original
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
# Modificar a configuração
sudo sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
sudo sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
# Validar a configuração
sudo sshd -t
# Reiniciar o SSH
sudo systemctl restart sshd
Saída:
TEXT(sem saída do sshd -t significa que a config está válida)
(8) ▶ Exemplo: Configuração do fail2ban
# Ver o status do fail2ban
sudo fail2ban-client status
# Ver o status da jail SSH
sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# | |- Currently failed: 3
# | |- Total failed: 45
# | `- File list: /var/log/auth.log
# `- Actions
# |- Currently banned: 5
# |- Total banned: 12
# `- Banned IP list: 192.168.1.100 10.0.0.50
# Desbanir manualmente um IP
sudo fail2ban-client set sshd unbanip 192.168.1.100
# Duração customizada de banimento
sudo tee /etc/fail2ban/jail.d/custom-sshd.conf << 'EOF'
[sshd]
enabled = true
maxretry = 3
bantime = 86400 # 24 horas
findtime = 600 # dentro de 10 minutos
EOF
sudo systemctl restart fail2ban
Saída:
TEXTStatus for the jail: sshd |- Filter | |- Currently failed: 3 | |- Total failed: 45 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 5 |- Total banned: 12 `- Banned IP list: 192.168.1.100 10.0.0.50 1 unbanned [sshd] enabled = true maxretry = 3 bantime = 86400 findtime = 600
(9) ▶ Exemplo: Atualizações Automáticas de Segurança
# Instalar o unattended-upgrades
sudo apt install unattended-upgrades
# Configurar
sudo dpkg-reconfigure --priority=low unattended-upgrades
# Ou editar a config manualmente
sudo tee /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}:${distro_codename}-updates";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
EOF
Saída:
TEXTReading package lists... Done Building dependency tree... Done The following NEW packages will be installed: unattended-upgrades 0 upgraded, 1 newly installed, 0 to remove
(10) ▶ Exemplo Abrangente: Hardening de Servidor Novo em Um Clique
#!/bin/bash
# secure-server.sh - Script de hardening de segurança para servidor novo
# Instruções: Rode imediatamente após o primeiro login SSH
# Atenção: Tenha outra sessão SSH aberta num terminal separado, como backup!
set -euo pipefail
SSH_PORT="${1:-2222}"
echo "========================================"
echo " Hardening de Seguranca do Servidor"
echo " Horario: $(date)"
echo "========================================"
# 1. Atualizar o sistema
echo ">>> 1/6 Atualizando o sistema..."
sudo apt update && sudo apt upgrade -y
# 2. Configurar o firewall
echo ">>> 2/6 Configurando o firewall..."
sudo ufw --force disable
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow "$SSH_PORT/tcp" comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw --force enable
echo "Firewall configurado (porta SSH: $SSH_PORT)"
# 3. Configurar chaves SSH
echo ">>> 3/6 Configurando chaves SSH..."
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 4. Hardening do SSH
echo ">>> 4/6 Hardening de seguranca do SSH..."
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
sudo sed -i "s/^#Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config
sudo sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/^#MaxAuthTries 6/MaxAuthTries 3/' /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart sshd
echo "Hardening do SSH concluido"
# 5. Instalar o fail2ban
echo ">>> 5/6 Instalando o fail2ban..."
sudo apt install -y fail2ban
sudo tee /etc/fail2ban/jail.d/sshd.conf << EOF
[sshd]
enabled = true
port = $SSH_PORT
maxretry = 3
bantime = 86400
findtime = 600
EOF
sudo systemctl enable --now fail2ban
# 6. Atualizações automáticas de segurança
echo ">>> 6/6 Configurando atualizacoes automaticas..."
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades -y
echo ""
echo "========================================"
echo "✅ Hardening de seguranca concluido!"
echo ""
echo "Observacoes importantes:"
echo " 1. Porta SSH alterada para $SSH_PORT"
echo " 2. Login de root desabilitado"
echo " 3. Login por senha desabilitado"
echo " 4. Garanta que sua chave publica esta em ~/.ssh/authorized_keys"
echo " 5. Antes de fechar essa sessao SSH, teste a conexao num terminal novo:"
echo " ssh -p $SSH_PORT ${USER}@$(curl -s ifconfig.me)"
echo "========================================"
❓ Perguntas Frequentes
P: O
ufw enablepode me trancar pra fora? R: Pode, se você não tiver liberado o SSH antes. Sempre rodesudo ufw allow 22/tcpantes dosudo ufw enable. Mantenha uma sessão SSH aberta como rede de segurança, e teste num terminal novo antes de fechar a antiga.
P: Chaves SSH ou senhas são mais seguras? R: A autenticação por chave é muito mais segura que senhas. Chaves usam RSA de 4096 bits ou Ed25519, criptografia assimétrica que é praticamente impossível de quebrar por força bruta. Senhas podem ser adivinhadas, atacadas por dicionário ou capturadas por phishing.
P: Os bans do fail2ban são permanentes? R: Não, são temporários por padrão (geralmente 1 hora). Você pode customizar a duração pelo
bantime. Bans permanentes não são recomendados — os IPs dos atacantes mudam o tempo todo, e a lista de banidos cresceria sem limite.
P: Como conectar depois de mudar a porta do SSH? R:
ssh -p 2222 usuario@host. Ou configurePort 2222no~/.ssh/config.
P: Por que manter o login por senha por um tempo? R: Como fallback. Se sua chave for perdida ou corrompida, o login por senha é a sua única saída. Só desabilite depois de confirmar que a autenticação por chave funciona de forma confiável. Sempre tenha um método de acesso alternativo (como o console VNC do seu provedor de nuvem).
📖 Resumo
- ufw:
allow 22/tcp→default deny incoming→enable - Chaves SSH:
ssh-keygen -t ed25519→ssh-copy-id usuario@host→ desabilitar login por senha - Hardening de SSH: trocar porta, desabilitar root, desabilitar senha, restringir usuários
- fail2ban:
maxretry=3,bantime=86400,findtime=600 unattended-upgradespra atualizações automáticas de segurança
📝 Exercícios
- Básico (⭐): Confira o status atual do ufw, abra ou feche uma porta e em seguida gere localmente um par de chaves SSH Ed25519
- Intermediário (⭐⭐): Configure o login por chave SSH num servidor de teste (ou teste em localhost) e instale o fail2ban pra conferir o status da jail SSH
- Desafio (⭐⭐⭐): Escreva um script de hardening de segurança que contemple todos os passos acima (config do ufw, chaves SSH, hardening do SSH, fail2ban), exigindo que cada etapa valide o sucesso antes de seguir adiante, e que faça rollback em caso de falha