Adicionar 101-Hardening-Linux-Servers.MD

This commit is contained in:
Richard Nixon 2026-05-29 01:19:33 +02:00
commit d2bc5eab4d

View file

@ -0,0 +1,328 @@
# Guia de Hardening do Servidor Linux
> **Sobre este documento:** Template explicativo das etapas de hardening aplicadas em servidores Ubuntu 24.04 LTS. Substitua os valores entre `<ANGULARES>` pelos dados do servidor alvo antes de executar.
---
## Variáveis a Substituir
| Placeholder | Descrição | Exemplo |
|-------------|-----------|---------|
| `<USUARIO_ADMIN>` | Nome do usuário administrador a criar | `deploy`, `sysadmin` |
| `<SEU_EMAIL>` | E-mail do responsável (usado como comentário na chave SSH) | `admin@empresa.com` |
| `<CHAVE_PUBLICA_SSH>` | Chave pública SSH ed25519 do seu laptop | `ssh-ed25519 AAAA...` |
| `<IP_DO_SERVIDOR>` | IP público do servidor | `203.0.113.10` |
| `<CHAVE_PUBLICA_WG>` | Chave pública WireGuard gerada no servidor | resultado de `wg pubkey` |
| `<IP_TUNEL_VPN>/<PREFIXO>` | IP atribuído ao servidor dentro da VPN | `10.14.0.2/16` |
| `<ENDPOINT_VPN>` | Endereço do servidor VPN (hostname:porta) | `servidor.vpn.com:51820` |
| `<CHAVE_PUBLICA_PEER_VPN>` | Chave pública do servidor VPN (fornecida pelo provedor) | resultado do painel da VPN |
| `<DNS_PRIMARIO>` | DNS primário fornecido pelo provedor VPN | `1.1.1.1` |
| `<DNS_SECUNDARIO>` | DNS secundário fornecido pelo provedor VPN | `8.8.8.8` |
---
## 1. Criação do Usuário Admin
```bash
useradd -m -s /bin/bash -G sudo <USUARIO_ADMIN>
echo "<USUARIO_ADMIN>:$(openssl rand -base64 32)" | chpasswd
mkdir -p /home/<USUARIO_ADMIN>/.ssh
chmod 700 /home/<USUARIO_ADMIN>/.ssh
echo "<CHAVE_PUBLICA_SSH>" > /home/<USUARIO_ADMIN>/.ssh/authorized_keys
chmod 600 /home/<USUARIO_ADMIN>/.ssh/authorized_keys
chown -R <USUARIO_ADMIN>:<USUARIO_ADMIN> /home/<USUARIO_ADMIN>/.ssh
echo "<USUARIO_ADMIN> ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/<USUARIO_ADMIN>
chmod 440 /etc/sudoers.d/<USUARIO_ADMIN>
```
**Motivo:** Servidores recém-provisionados têm apenas o usuário `root` ativo. Login direto como root é um vetor de ataque comum — bots fazem brute force em root 24/7. Criamos um usuário dedicado com chave SSH (ed25519), desabilitamos senha e bloqueamos login root no passo seguinte. O arquivo `/etc/sudoers.d/<USUARIO_ADMIN>` garante privilégios de administração sem precisar de senha (NOPASSWD), seguro pois a única forma de acesso é via chave SSH.
---
## 2. Atualização do Sistema e Instalação de Ferramentas
```bash
apt-get update -qq
apt-get upgrade -y -qq
apt-get install -y ufw fail2ban unattended-upgrades wireguard wireguard-tools
```
**Motivo:** Manter o sistema atualizado fecha vulnerabilidades conhecidas (CVEs). As ferramentas instaladas formam a base do hardening:
- `ufw`: firewall simplificado sobre iptables
- `fail2ban`: bane IPs após tentativas de força bruta
- `unattended-upgrades`: atualizações de segurança automáticas
- `wireguard`/`wireguard-tools`: VPN moderna e performática
---
## 3. Firewall UFW
```bash
ufw --force reset
ufw default deny incoming # bloqueia tudo que entra
ufw default allow outgoing # permite tudo que sai
ufw default deny forward # bloqueia pacotes roteados
ufw allow 22/tcp # permite SSH
ufw allow out on wg0 # permite tráfego VPN saindo
ufw allow in on wg0 # permite tráfego VPN entrando
ufw allow out 51820/udp # permite UDP para o endpoint VPN
ufw --force enable
```
**Motivo:** A política `deny incoming` fecha todas as portas por padrão — apenas o que for explicitamente permitido entra. A porta 22 é a única entrada permitida. As regras do `wg0` e porta `51820/udp` são necessárias para o túnel WireGuard funcionar.
> **Atenção:** Verifique se está conectado ao servidor via SSH antes de habilitar o UFW. Execute os comandos em sequência e confirme que a porta 22 está liberada **antes** de rodar `ufw enable`.
---
## 4. Hardening SSH
Arquivo: `/etc/ssh/sshd_config`
```
PermitRootLogin no # bloqueia login direto como root
PubkeyAuthentication yes # permite autenticação por chave
PasswordAuthentication no # desabilita senha (força uso de chave)
PermitEmptyPasswords no # bloqueia senhas vazias
KbdInteractiveAuthentication no
AllowUsers <USUARIO_ADMIN> # apenas o usuário admin pode fazer login
MaxAuthTries 3 # máximo 3 tentativas antes de desconectar
MaxSessions 5 # limita sessões simultâneas
LoginGraceTime 30 # 30s para autenticar, depois desconecta
ClientAliveInterval 300 # detecta conexões mortas em 5 minutos
ClientAliveCountMax 2
X11Forwarding no # desabilita X11 (desnecessário em servidor)
AllowAgentForwarding no # desabilita SSH agent forwarding
AllowTcpForwarding no # desabilita port forwarding via SSH
PermitTunnel no # desabilita criação de túneis SSH
LogLevel VERBOSE # log detalhado para auditoria
```
```bash
# Faça backup antes de aplicar
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
sshd -t # valida a config antes de aplicar
systemctl reload ssh # recarrega sem derrubar conexões ativas
```
**Motivo:** Cada linha desabilitada remove uma superfície de ataque. `AllowUsers <USUARIO_ADMIN>` garante que mesmo que outro usuário seja criado indevidamente, ele não consegue fazer SSH. `LogLevel VERBOSE` registra a impressão digital de chave em cada conexão, útil para forense.
> **Atenção:** Teste o login com o novo usuário em uma **segunda sessão SSH** antes de fechar a sessão atual. Se algo estiver errado, você ainda consegue corrigir.
---
## 5. Hardening do Kernel (sysctl)
Arquivo: `/etc/sysctl.d/99-hardening.conf`
```bash
# Anti-spoofing: verifica se o IP de origem faz sentido pela interface
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Desabilita source routing (permite manipular o caminho dos pacotes)
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Ignora ICMP redirects (evita ataques de roteamento)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Não envia ICMP redirects
net.ipv4.conf.all.send_redirects = 0
# Loga pacotes "marcianos" (IPs impossíveis/suspeitos)
net.ipv4.conf.all.log_martians = 1
# Proteção contra SYN flood (ataque de negação de serviço)
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_syn_backlog = 4096
# Desabilita IP forward (máquina não é roteador)
net.ipv4.ip_forward = 0
# Ignora ping broadcast (mitigação ataque Smurf)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Desabilita IPv6 (se não utilizado no ambiente)
net.ipv6.conf.all.disable_ipv6 = 1
# Restringe acesso a ponteiros do kernel e dmesg
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
# Restringe ptrace (evita que processos inspecionem outros)
kernel.yama.ptrace_scope = 1
# Desabilita core dumps de binários SUID
fs.suid_dumpable = 0
# ASLR máximo: randomiza endereços de memória
kernel.randomize_va_space = 2
```
```bash
sysctl -p /etc/sysctl.d/99-hardening.conf # aplica imediatamente
```
**Motivo:** Configurações padrão do kernel são permissivas por compatibilidade. Cada parâmetro fecha um vetor específico: `rp_filter` previne IP spoofing, SYN cookies protegem contra flood, `kptr_restrict` impede que atacantes usem vazamentos de ponteiros do kernel para exploits locais.
> **Nota:** Se o servidor for um roteador ou usar IPv6, ajuste `ip_forward` e `disable_ipv6` de acordo.
---
## 6. fail2ban
Arquivo: `/etc/fail2ban/jail.local`
```ini
[DEFAULT]
bantime = 3600 # bane por 1 hora
findtime = 600 # janela de 10 minutos para contar tentativas
maxretry = 3 # 3 falhas = banido
[sshd]
enabled = true
port = ssh
maxretry = 3
bantime = 86400 # SSH: bane por 24 horas
```
```bash
systemctl enable fail2ban
systemctl restart fail2ban
```
**Motivo:** Bots fazem brute force SSH 24/7. O fail2ban monitora os logs e bane automaticamente IPs que excedem as tentativas. O `bantime` de 24h para SSH é mais agressivo que o padrão (1h) porque ataques SSH são persistentes e os IPs usados não são reutilizados rapidamente.
---
## 7. Desabilitação de Serviços Desnecessários
```bash
systemctl disable --now ModemManager # gerenciador de modem (sem uso em servidor)
systemctl disable --now fwupd # atualizações de firmware (interface desktop)
systemctl disable --now snapd # sistema de pacotes snap (desnecessário)
systemctl disable --now udisks2 # montagem de discos (desnecessário)
```
**Motivo:** Cada serviço rodando é uma superfície de ataque potencial. Serviços de desktop como `ModemManager` e `udisks2` não têm função em um servidor Linux headless. Menos código rodando = menos vulnerabilidades expostas.
> **Dica:** Use `systemctl list-units --type=service --state=running` para auditar todos os serviços ativos e desabilitar outros que não sejam necessários ao ambiente.
---
## 8. VPN WireGuard com Killswitch
### Geração de chaves
```bash
wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
chmod 600 /etc/wireguard/private.key
cat /etc/wireguard/public.key # registre esta chave no painel do provedor VPN
```
### Arquivo de configuração
`/etc/wireguard/wg0.conf` (permissão 600):
```ini
[Interface]
Address = <IP_TUNEL_VPN>/<PREFIXO>
PrivateKey = <conteúdo de /etc/wireguard/private.key>
DNS = <DNS_PRIMARIO>, <DNS_SECUNDARIO>
# ── Killswitch ──────────────────────────────────────────────────────────
# Regra 1: respostas de conexões ENTRANTES (ex: SSH) saem pelo eth0
PostUp = ip rule add from <IP_DO_SERVIDOR> table main priority 100
# Regra 2: bloqueia qualquer tráfego de saída que não seja:
# - pelo tunnel wg0
# - pacotes marcados pelo WireGuard (os próprios pacotes UDP cifrados)
# - respostas ESTABLISHED/RELATED (replies de conexões recebidas)
# - endereços LOCAL (loopback)
PostUp = iptables -I OUTPUT ! -o %i \
-m mark ! --mark $(wg show %i fwmark) \
-m conntrack ! --ctstate ESTABLISHED,RELATED \
-m addrtype ! --dst-type LOCAL \
-j REJECT
PreDown = ip rule del from <IP_DO_SERVIDOR> table main priority 100
PreDown = iptables -D OUTPUT ! -o %i \
-m mark ! --mark $(wg show %i fwmark) \
-m conntrack ! --ctstate ESTABLISHED,RELATED \
-m addrtype ! --dst-type LOCAL \
-j REJECT
[Peer]
PublicKey = <CHAVE_PUBLICA_PEER_VPN>
AllowedIPs = 0.0.0.0/0
Endpoint = <ENDPOINT_VPN>
PersistentKeepalive = 25
```
### Ativar no boot
```bash
systemctl enable wg-quick@wg0
wg-quick up wg0
```
**Como funciona o killswitch:**
- **VPN UP:** todo tráfego novo vai pelo `wg0` (tunnel). A regra `ip rule from <IP_DO_SERVIDOR> table main` garante que respostas SSH saiam pelo `eth0` (não pelo tunnel), mantendo acesso ao servidor.
- **VPN cai:** o `wg0` permanece up mas não encaminha pacotes. A regra iptables `REJECT` bloqueia qualquer tentativa de sair pelo `eth0`. Nenhum dado vaza para fora da VPN.
- `PersistentKeepalive = 25`: mantém o tunnel ativo através de NATs e firewalls.
### Verificação pós-ativação
```bash
wg show # status do tunnel (handshake, bytes transferidos)
curl https://api.ipify.org # deve retornar o IP do provedor VPN, não o IP real do servidor
```
---
## Resumo do Estado Final (preencher após execução)
| Item | Antes | Depois |
|------|-------|--------|
| Firewall | Inativo | UFW ativo, deny all |
| Login root SSH | Permitido | Bloqueado |
| Autenticação SSH | Senha + chave | Chave apenas |
| fail2ban | Não instalado | Ativo |
| Serviços rodando | _(contar antes)_ | _(contar depois)_ |
| IP externo | `<IP_DO_SERVIDOR>` | IP do provedor VPN |
| Killswitch VPN | N/A | Ativo via iptables |
| Kernel hardening | Padrão permissivo | sysctl endurecido |
---
## Comandos de Manutenção
```bash
# Status da VPN
wg show
systemctl status wg-quick@wg0
# Reiniciar VPN
wg-quick down wg0 && wg-quick up wg0
# Status do firewall
ufw status verbose
# IPs banidos pelo fail2ban
fail2ban-client status sshd
# Logs SSH (últimas 50 linhas)
journalctl -u ssh -n 50 --no-pager
# Conectar ao servidor (do seu laptop)
ssh <USUARIO_ADMIN>@<IP_DO_SERVIDOR>
# Auditar serviços rodando
systemctl list-units --type=service --state=running
```