SSH com 2FA: Google Authenticator no Ubuntu Server
Chave SSH roubada ou senha vazada em um dump de credenciais ainda costuma bastar para
entrar num servidor Linux. Um segundo fator fecha essa porta: mesmo com a senha ou a
chave privada em mãos, o invasor também precisaria do código TOTP de 6 dígitos gerado
no celular do administrador, que troca a cada 30 segundos. Este guia configura esse
segundo fator no SSH com o módulo PAM do Google Authenticator, em um Ubuntu Server
atualizado, sem travar sua sessão no meio do caminho.
Por que 2FA no SSH, e não só Fail2Ban ou chave pública
Fail2Ban e CrowdSec bloqueiam quem tenta adivinhar a senha por força bruta — eles
cortam o volume de tentativas, não impedem um login com a credencial certa. Uma chave
SSH sem senha de proteção (passphrase) também vira acesso total se o notebook do
administrador for comprometido ou a chave acabar num repositório público por engano.
O 2FA cobre exatamente esse ponto cego: validade curta (30 segundos), gerado localmente
no celular, sem depender de rede ou SMS.
Instalar o módulo PAM do Google Authenticator
O pacote está nos repositórios padrão do Ubuntu, sem precisar de PPA:
sudo apt update sudo apt install libpam-google-authenticator -y
Confirme que o módulo ficou disponível para o PAM:
dpkg -l | grep google-authenticator
Gerar o segredo TOTP do usuário
Rode como o próprio usuário que vai logar via SSH — nunca como root, a menos que
seja o root mesmo quem loga:
google-authenticator
Responda às perguntas assim:
- Make tokens “time-based”?
y— é o padrão que o app do
celular espera. - Update the .google_authenticator file?
y. - Disallow multiple uses of the same token?
y— impede
reaproveitar um código capturado. - Increase the original generation time limit?
n, a
menos que o relógio do servidor costume desviar. - Enable rate limiting?
y— limita a 3 tentativas por
30 segundos, o que já inviabiliza força bruta contra o código.
O terminal mostra um QR code: escaneie com o app Google Authenticator (ou qualquer
app TOTP, como Authy ou Microsoft Authenticator) e confira se o código de 6 dígitos
gerado no celular bate com a verificação pedida na tela. Sem câmera disponível, digite
manualmente a chave secreta impressa abaixo do QR code.
O comando também imprime 5 códigos de emergência de uso único.
Guarde-os num gerenciador de senhas — eles são o que evita ficar trancado de fora se
o celular for perdido ou formatado. Depois, restrinja a permissão do arquivo gerado:
chmod 600 ~/.google_authenticator
Editar /etc/pam.d/sshd
Faça backup antes de qualquer edição em arquivo de autenticação:
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
Adicione esta linha ao final do arquivo:
auth required pam_google_authenticator.so nullok
O parâmetro nullok deixa quem ainda não configurou o TOTP continuar
logando só com senha ou chave — útil durante a migração, para não trancar todo mundo de
uma vez. Depois que cada conta tiver seu ~/.google_authenticator, remova o
nullok para tornar o segundo fator obrigatório.
Editar /etc/ssh/sshd_config
Backup primeiro, como em qualquer mudança no SSH:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Garanta estas diretivas (em versões anteriores ao Ubuntu 20.04, o nome antigo é
ChallengeResponseAuthentication em vez de KbdInteractiveAuthentication):
KbdInteractiveAuthentication yes UsePAM yes
Para exigir chave pública e o código TOTP — a combinação mais forte,
porque elimina a senha do fluxo — adicione:
PubkeyAuthentication yes PasswordAuthentication no AuthenticationMethods publickey,keyboard-interactive
Se preferir manter senha como primeiro fator (mais simples, menos robusto), use
AuthenticationMethods publickey,password publickey,keyboard-interactive
e deixe PasswordAuthentication yes.
Validar antes de reiniciar — e não fechar a sessão atual
Erro de sintaxe no sshd_config some do radar até o próximo reinício, e aí
é tarde. Teste sempre antes:
sudo sshd -t
Sem erro impresso, reinicie o serviço:
sudo systemctl restart sshd sudo systemctl status sshd
Mantenha a sessão SSH atual aberta e abra uma segunda conexão, em
outro terminal, para testar o login do zero. Se a segunda falhar, a primeira ainda está
viva para desfazer a mudança — fechar a única sessão antes de confirmar que o 2FA
funciona é a forma mais comum de ficar trancado do próprio servidor.
ssh usuario@ip-do-servidor
Com chave pública configurada, o login deve pedir só o código de 6 dígitos — sem
senha. Sem chave, a ordem é senha e depois o código.
Armadilhas que travam o acesso
- Nunca adicione uma regra
pam_succeed_if ... service = sshd
em/etc/pam.d/sshdesperando que ela libere algum caso específico: dentro
desse arquivo o serviço é sempresshd, então a condição bate em todo login
e desativa o 2FA sem avisar. - Relógio do servidor e do celular precisam estar sincronizados — o TOTP é baseado em
tempo. Confirme o NTP:timedatectldeve mostrarSystem clock.
synchronized: yes - Login local no console, acesso serial e IPMI usam o serviço PAM
login,
nãosshd— essas mudanças não afetam esse caminho, o que é útil como rota
de emergência caso o SSH fique inacessível. - Cada código de emergência só funciona uma vez; depois de usado, o arquivo
~/.google_authenticatoro remove da lista.
Recuperando acesso se o celular for perdido
Com um código de emergência guardado, basta usá-lo no lugar do TOTP normal. Sem
nenhum deles em mãos, acesse via console local, VNC do provedor de hospedagem ou IPMI
(esse caminho não passa pelo PAM do sshd) e apague o arquivo da conta
afetada para desativar o 2FA só para ela:
rm ~/.google_authenticator
Depois, rode google-authenticator de novo para gerar um segredo novo.
Perguntas frequentes
O 2FA no SSH substitui a chave pública?
Não — ele se soma à
chave ou à senha como um segundo fator independente. A combinação mais segura é chave
pública mais TOTP, sem senha no meio.
Funciona com Ansible, scripts de automação ou CI/CD que fazem SSH sem
interação humana?
Não diretamente: TOTP exige alguém digitando o código.
Para contas de automação, mantenha autenticação só por chave e isole essas contas com
Match User no sshd_config, sem o segundo fator.
Preciso reconfigurar o 2FA depois de atualizar o Ubuntu?
Não — o
segredo fica em ~/.google_authenticator, fora do pacote. Uma atualização
do sistema não apaga esse arquivo.
Dá para usar outro app além do Google Authenticator?
Sim, qualquer
app compatível com TOTP (RFC 6238) lê o mesmo QR code: Authy, Microsoft Authenticator,
Bitwarden, 1Password.
E se eu perder os códigos de emergência e o celular ao mesmo tempo?
Só resta acesso fora do SSH — console do provedor, KVM/IPMI ou suporte da hospedagem —
para remover o arquivo .google_authenticator da conta manualmente.
Conclusão
O módulo PAM do Google Authenticator custa quinze minutos de configuração e fecha o
cenário mais comum de comprometimento: credencial válida em mãos erradas. Rode em um
usuário de teste antes de aplicar em contas administrativas, mantenha os códigos de
emergência fora do próprio servidor e documente o procedimento de recuperação — é o
que evita um chamado de madrugada quando alguém trocar de celular.