Verificar minha conexão

Guias · Investigar um IP

Tentativas de login SSH nos meus logs: estou sendo invadido?

Você entra no servidor, dá uma olhada no /var/log/auth.log e encontra milhares de linhas Failed password for root vindas de endereços do mundo todo. Parece um cerco. É basicamente o clima.

A porta 22 é a porta mais previsível da internet, então scripts automáticos batem nela sem parar, em todo lugar, o dia inteiro. Eles não estão mirando você. Testam uma lista curta de nomes de usuário (root, admin, oracle, ubuntu, test) com as senhas que as pessoas mais escolhem e seguem em frente. Uma tentativa falha não custa nada a eles e só diz a você que o SSH está acessível. O seu trabalho é responder a duas perguntas: alguma tentativa deu certo, e alguma futura poderia dar?

Onde olhar

No Debian e no Ubuntu com rsyslog, o SSH grava em /var/log/auth.log. No Red Hat, Fedora, Rocky e Alma, é /var/log/secure. Instalações mais novas do Debian podem nem gravar esse arquivo e manter tudo no journal do systemd. O journal funciona em qualquer lugar com systemd; o serviço se chama ssh no Debian e no Ubuntu e sshd na família Red Hat:

sudo journalctl -u ssh --since today        # Debian, Ubuntu
sudo journalctl -u sshd --since "1 hour ago" # Red Hat, Fedora, Rocky, Alma

Três contagens contam a maior parte da história:

sudo grep -c "Failed password" /var/log/auth.log
sudo grep "Accepted" /var/log/auth.log
sudo grep "Failed password" /var/log/auth.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn | head

A primeira mostra o tamanho do ruído. A segunda é a que importa: cada login bem-sucedido. A terceira mostra quais endereços insistem mais.

Um exemplo real: uma noite numa VPS pequena

Doze linhas de um servidor chamado web1. Os dois endereços de pessoas (o atacante que tenta admin e o dono entrando na manhã seguinte) são endereços de documentação, então nenhuma pessoa real aparece aqui. Os outros são de infraestrutura pública.

O log de exemplo (12 linhas)
Nov  6 03:12:41 web1 sshd[24811]: Invalid user admin from 203.0.113.77 port 51022
Nov  6 03:12:43 web1 sshd[24811]: Failed password for invalid user admin from 203.0.113.77 port 51022 ssh2
Nov  6 03:12:44 web1 sshd[24811]: Connection closed by invalid user admin 203.0.113.77 port 51022 [preauth]
Nov  6 03:12:50 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:53 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:55 web1 sshd[24815]: Disconnected from authenticating user root 185.220.101.1 port 40122 [preauth]
Nov  6 03:14:02 web1 sshd[24830]: Invalid user oracle from 3.5.140.1 port 33412
Nov  6 03:14:04 web1 sshd[24830]: Failed password for invalid user oracle from 3.5.140.1 port 33412 ssh2
Nov  6 03:14:04 web1 sshd[24830]: Received disconnect from 3.5.140.1 port 33412:11: Bye Bye [preauth]
Nov  6 03:20:17 web1 sshd[24902]: Connection closed by 167.94.138.35 port 49212 [preauth]
Nov  6 08:41:09 web1 sshd[25510]: Accepted publickey for deploy from 198.51.100.20 port 52814 ssh2: ED25519 SHA256:k3X0exampleexampleexampleexampleexampleexa
Nov  6 08:41:09 web1 sshd[25510]: pam_unix(sshd:session): session opened for user deploy(uid=1001) by (uid=0)

Passados pelo verificador de logs do iplover, os cinco endereços se separam assim:

Endereço IPLinhasCategoriaTipo de rede
203.0.113.773Privados ou reservadosEndereço privado ou reservado (não verificado)
185.220.101.13Nós de saída TorNó de saída Tor
3.5.140.13Nuvem e hospedagemHospedagem, nuvem ou data center
167.94.138.351Scanners da internetNão identificado
198.51.100.201Privados ou reservadosEndereço privado ou reservado (não verificado)

(Os dois endereços de documentação aparecem como reservados; no seu próprio log, os endereços reais seriam verificados.) Agora leia as linhas, porque as categorias só dizem quem bateu, não se a porta abriu.

Veredito: um login aceito, e é do dono. Ninguém entrou. Mas o root ainda aceita senhas, então as tentativas da quarta linha poderiam dar certo um dia se a senha do root for fraca. É isso que precisa ser corrigido.

Alguém entrou mesmo?

Confira cada linha Accepted. Para cada uma, pergunte: é o meu usuário, a minha chave ou senha, e um endereço que eu reconheço (casa, escritório, VPN)? Depois compare com os registros de login:

last -a | head -20     # logins bem-sucedidos recentes, com o endereço remoto
sudo lastb | head -20  # falhas recentes (nos sistemas que as guardam)
who                     # quem está logado agora

Algumas distribuições mais novas substituíram last e lastb por outras ferramentas; se eles não existirem, o journal e o auth.log têm a mesma informação.

Uma linha Accepted password ou Accepted publickey que você não consegue explicar é o único resultado que muda tudo. Nesse caso, considere a conta comprometida:

Se você vir isto, faça isto

O que você vêO que significaO que fazer
Invalid user … para nomes que você não temTentativas que não têm como funcionarNada urgente. Some quando as senhas forem desativadas.
Failed password for root ou para outra conta realTentativas contra uma conta que existeDesative o login por senha (veja abaixo), ou pelo menos o do root.
Connection closed by … [preauth] sem nenhuma senha testadaUm scanner lendo o seu banner SSHNada.
Milhares de falhas por dia vindas de poucos endereçosBots persistentesInstale o fail2ban, ou libere o SSH só para os seus próprios endereços.
Linhas Accepted … que são todas suasNinguém mais entrouNada, além de reforçar a segurança.
Accepted … de um endereço ou usuário que você não consegue explicarUma provável invasãoSiga os passos acima, começando pelo authorized_keys.

Torne a adivinhação inútil: só chaves

Uma senha pode ser adivinhada; uma chave SSH, na prática, não. Quando só chaves são aceitas, os bots podem tentar para sempre.

Primeiro, crie uma chave no seu computador e copie para o servidor. O macOS e o Linux já vêm com o cliente OpenSSH. No Windows, ele é um recurso opcional, muitas vezes já instalado; se o ssh não for reconhecido, o guia da Microsoft Introdução ao OpenSSH para Windows mostra como adicioná-lo:

ssh-keygen -t ed25519
ssh-copy-id voce@seu-servidor     # no Windows, cole ~/.ssh/id_ed25519.pub no ~/.ssh/authorized_keys do servidor

Depois, no servidor, defina isto em /etc/ssh/sshd_config:

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password

prohibit-password só deixa o root entrar com chave; use no para manter o root totalmente fora do SSH. Antes de reiniciar, confira o que o SSH vai realmente usar. Os arquivos em /etc/ssh/sshd_config.d/ também são lidos, e algumas imagens de nuvem trazem um que reativa as senhas. Na maioria das opções, vale o primeiro valor que o sshd lê:

sudo sshd -T | grep -Ei "passwordauthentication|kbdinteractive|permitrootlogin"

Reinicie o SSH (sudo systemctl restart ssh, ou sshd na família Red Hat) e mantenha a sessão atual aberta enquanto testa um novo login numa segunda janela. Se o novo login falhar, você ainda pode consertar pela sessão antiga.

Corte o ruído: fail2ban e firewalls

As chaves tornam a adivinhação inofensiva. O fail2ban torna o log legível: ele observa falhas repetidas e bloqueia esses endereços por um tempo no firewall. No Debian e no Ubuntu, sudo apt install fail2ban, e depois crie /etc/fail2ban/jail.local:

[sshd]
enabled  = true
maxretry = 5
findtime = 10m
bantime  = 1h
# Sem /var/log/auth.log (Debian mais novo), leia o journal:
# backend = systemd

Reinicie com sudo systemctl restart fail2ban e confira com sudo fail2ban-client status sshd.

Se só você precisa do SSH, o filtro de ruído mais forte é uma regra de firewall que libera a porta 22 apenas para os seus próprios endereços, ou uma VPN na frente do servidor. Mudar o SSH de porta também corta bastante o ruído, mas é camuflagem, não proteção: um scanner vai encontrá-lo do mesmo jeito.

O que os endereços não conseguem dizer

Os endereços no auth.log são de onde vieram as conexões: muitas vezes uma saída do Tor, um servidor de nuvem alugado ou a máquina sequestrada de outra pessoa. Eles não identificam uma pessoa, e bloqueá-los um por um nunca vai dar conta. Denunciar ataques persistentes ao contato de abuso da rede (a consulta de IP mostra qual é) faz sentido para um servidor de nuvem que martela você por dias; para alguns logins falhos, não vale o seu tempo.

Fontes

Documentos oficiais que usamos para conferir os fatos deste guia.