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

1. O Que Você Vai Aprender


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:

BASH
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:

BASH
# 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

BASH
# 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
⚠️ Atenção: As regras do ufw/iptables são avaliadas em ordem — a primeira regra que bater já vale. Se você escrever 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.

⚠️ Atenção: Ao usar 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:

⚠️ Atenção: O 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.

BASH
# 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

BASH
# 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

⚠️ Atenção: Antes de mudar a porta do SSH (por exemplo, pra 2222), garanta que você tem um método alternativo de acesso. Se a sua nuvem oferece console VNC, use como backup. Depois de mudar a porta, lembre de liberar a porta nova no ufw (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:

TEXT
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:

BASH
sudo sshd -t                   # Testar a sintaxe da config
sudo systemctl restart sshd    # Reiniciar o serviço SSH

(4) fail2ban

💡 Dica: O 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.

BASH
# 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

BASH
# 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:

TEXT
Rule 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

BASH
# 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:

TEXT
Generating 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

BASH
# 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

BASH
# 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:

TEXT
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
1 unbanned

[sshd]
enabled = true
maxretry = 3
bantime = 86400
findtime = 600

(9) ▶ Exemplo: Atualizações Automáticas de Segurança

BASH
# 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:

TEXT
Reading 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

BASH
#!/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 enable pode me trancar pra fora? R: Pode, se você não tiver liberado o SSH antes. Sempre rode sudo ufw allow 22/tcp antes do sudo 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 configure Port 2222 no ~/.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


📝 Exercícios

  1. Básico (⭐): Confira o status atual do ufw, abra ou feche uma porta e em seguida gere localmente um par de chaves SSH Ed25519
  2. 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
  3. 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
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%