SSH certificate authentication eliminates passwords - secure server access with public key certificates

SSH Certificate Authentication: Substitua Senhas de Uma Vez por Todas

SSH Certificate Authentication: O Método Que Substitui Senhas e Funciona de Verdade

Eu perdi três dias debugging um problema de SSH. Três dias. Tinha um script de deploy que funcionava perfeito em produção, mas no servidor de staging? “Permission denied (publickey)”. Mudei a chave, depois mudei de novo, verifiquei o authorized_keys, conferi as permissões do .ssh/, reiniciei o sshd, lí o /var/log/auth.log mais vezes do que eu gostaria de admitir.

O problema? Uma chave SSH com 2048 bits que tinha expirado silenciosamente. Sem aviso. Sem erro claro. Só o famigerado “Permission denied” que não diz nada útil.

Depois disso, eu decidi que nunca mais queria depender de senhas SSH — e definitivamente nunca mais queria descobrir que uma chave expirou só quando o deploy falhasse às 2h da manhã. A solução que encontrei se chama SSH Certificate Authentication, e é o assunto desse post.

O Que É SSH Certificate Authentication?

É um método de autenticação SSH onde, em vez de confiar diretamente na chave pública do usuário (o modelo tradicional de “aqui está minha chave, me deixa entrar”), você assina digitalmente essa chave com um Certificate Authority (CA) privado. O servidor SSH confia na CA — não na chave individual.

Traduzindo: você tem uma autoridade certificadora que assina as chaves dos usuários. Quando alguém tenta fazer login, o servidor verifica a assinatura da CA, não a chave do usuário diretamente.

A grande sacada? Você pode definir uma data de expiração no certificado. Depois disso, ele simplesmente para de funcionar. Sem drama, sem surpresas às 2h da manhã.

Por Que Não Usar Só Chave Pública Tradicional?

O modelo tradicional funciona, mas tem três problemas chatos:

  • Sem expiração: Uma chave SSH nunca expira por padrão. Se alguém Roubar essa chave, tem acesso vitalício ao seu servidor.
  • Revogação manual: Precisa remover a chave pública do authorized_keys de todos os servidores quando alguém sai da equipe ou perde um laptop. Em 50 servidores, isso é um inferno.
  • Escalabilidade horrível: Adicionar um novo desenvolvedor significa copiar a chave para N servidores. Com certificados, você só assina o certificado — todos os servidores que confiam na CA já estão prontos.

Arquitetura: Entendendo as Peças

A autenticação por certificado SSH funciona com dois componentes principais:

1. User Certificate

É a chave pública do usuário assinada pela sua CA. Contém:

  • Chave pública do usuário
  • ID do usuário (quem é)
  • ID da CA que assinou
  • Tipo de chave (ssh-rsa, ecdsa-sha2-nistp256, etc.)
  • Serial (único por certificado)
  • Período de validade (timestamps de início e expiração)
  • Permissões críticas (opções como permit-pty, permit-X11-forwarding)
  • Assinatura da CA sobre tudo isso

2. Host Certificate

Similar ao user certificate, mas para o servidor. Garante que você está se conectando ao servidor real, não a um ataque man-in-the-middle. O cliente SSH verifica a assinatura do host certificate contra a CA pública configurada.

O Perrengue Real: Quando a CA Venceu

Passo a Passo: Implementando SSH Certificate Authentication

Passo 1: Gerar a CA do Servidor

# Gere a chave privada da CA (NUNCA copie essa chave pra nenhum server)
ssh-keygen -t ed25519 -f ~/ca_user -C "CA Usuario - AutoMente"

# Gere a CA de host (essa também fica só no seu CA server)
ssh-keygen -t ed25519 -f ~/ca_host -C "CA Host - AutoMente"

# Configure permissões mínimas na chave privada
chmod 600 ~/ca_user ~/ca_host

Passo 2: Configurar o Servidor SSH para Confiar na CA

# No servidor, edite /etc/ssh/sshd_config:

# Caminho para a chave pública da CA de usuários
TrustedUserCAKeys /etc/ssh/ca_user.pub

# Caminho para o certificado de host (auto-assinado pela sua CA de host)
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub

# Desabilite autenticação por senha (opcional, mas recomendado)
PasswordAuthentication no

# Recarregue o sshd
sudo systemctl reload sshd

Passo 3: Assinar a Chave do Usuário

# Assinar a chave pública do usuário com a CA
ssh-keygen -s ~/ca_user \
  -I "usuario-devops@empresa.com" \
  -n devops \
  -V '+1d' \
  -z 1001 \
  ~/.ssh/id_ed25519.pub

# Flags explicadas:
# -s: chave privada da CA para assinar
# -I: ID do certificado (identificação)
# -n: principal(s) — usuário(s) unix que pode usar esse cert
# -V: validade (+1d = 1 dia, +52w = 52 semanas, -5m = -5 minutos)
# -z: número de série (único por certificado na CA)

Isso gera um arquivo id_ed25519-cert.pub ao lado da sua chave pública. Esse é o certificado que você distribui junto com a chave.

Passo 4: Distribuir e Testar

# No cliente, configure ~/.ssh/config para usar certificado:
Host *.example.com
    IdentityFile ~/.ssh/id_ed25519
    CertificateFile ~/.ssh/id_ed25519-cert.pub

# Teste a conexão
ssh -v usuario@servidor01.example.com

No debug output, procure por Server accepts key e Certificate.

Revogação: O Problema Que Atrapalha Muita Gente

Uma dúvida comum: “OK, mas se o cara sair, como eu revogo o acesso na hora?”

Existem duas estratégias:

Estratégia 1: RevokedKeys (legacy mas funcional)

# No servidor, edite sshd_config:
RevokedKeys /etc/ssh/revoked_keys

# Para revogar um certificado, adicione a linha ao arquivo:
ssh-ed25519 AAAA... revoked

Estratégia 2: Principals (mais elegante)

Se você usa o campo -n ao assinar, o certificado só é válido para Principals específicos. Remover alguém é questão de não incluir mais esse principal na hora de assinar.

# Assinar sem o principal do usuário que saiu
ssh-keygen -s ~/ca_user \
  -I "novo-devops@empresa.com" \
  -n devops,deploy \
  -V '+30d' \
  ~/.ssh/id_ed25519.pub

Cronograma de Validade: Quanto Tempo Colocar?

Essa é uma decisão de segurança vs. conveniência:

  • +1h a +8h: Para pipelines de CI/CD automatizados. Curto, mas você precisa de automação pra assinar.
  • +1d a +7d: Para workstations de devs. Curto o bastante pra limitar dano se perder laptop.
  • +30d a +1y: Para service accounts que precisam de acesso confiável e estável.

Minha recomendação: Use +7d como padrão para humanos e +1d para pipelines. Crie rotação automática de certificados via script ou ferramenta como Cloudflare’s ssh-ca.

Integrando Com Infraestrutura Real

Com Ansible

# roles/ssh-ca/tasks/main.yml
- name: Deploy CA public key
  copy:
    dest: /etc/ssh/ca_user.pub
    content: "{{ ssh_ca_public_key }}"
    owner: root
    group: root
    mode: '0644'

- name: Configure sshd to trust CA
  lineinfile:
    path: /etc/ssh/sshd_config
    line: "TrustedUserCAKeys /etc/ssh/ca_user.pub"
    state: present
  notify: reload sshd

Com Terraform (AWS EC2)

resource "aws_instance" "server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  
  # User data para configurar SSH CA no primeiro boot
  user_data = <<-EOF
    #!/bin/bash
    echo "${tls_self_signed_cert.ca_public_key}" > /etc/ssh/ca_user.pub
    echo "TrustedUserCAKeys /etc/ssh/ca_user.pub" >> /etc/ssh/sshd_config
    systemctl reload sshd
  EOF
}

Comparando: Senhas vs Chave Tradicional vs Certificates

Aspecto Senhas Chave Tradicional Certificate Auth
Expiração Manual Nunca Automática
Revogação Mudar senha Remover de todos servers Parar de assinar
Escalabilidade Péssima Razoável Excelente
Proteção contra MITM Nenhuma Parcial Completa (c/ host cert)
Setup inicial Trivial Fácil Médio

Erro Comum: O Principals Mismatch

Se você assinar com -n devops mas tentar fazer login como root, vai tomar um Permission denied (publickey) silencioso. O SSH não diz “principals mismatch” — ele só nega.

Debug:

# Verifique o que tem no certificado
ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub

Isso mostra todos os principals permitidos. Se não aparecer o usuário que você está tentando usar, é esse o problema.

Automação: Assinando Certificados Via Script

#!/bin/bash
# sign_ssh_key.sh - Assina chaves SSH automaticamente

CA_KEY="/opt/ca/keys/ca_user"
DAYS_VALID="${1:-7}"
PRINCIPALS="${2:-devops}"
PUB_KEY="${3:-/dev/stdin}"

serial=$(date +%s)

ssh-keygen -s "$CA_KEY" \
  -I "cert-$(whoami)-$(hostname)" \
  -n "$PRINCIPALS" \
  -V "+${DAYS_VALID}d" \
  -z "$serial" \
  "$PUB_KEY"

Conclusão: É Mais Trabalho, Mas Compensa

Sim, configurar SSH Certificate Authentication toma tempo. Você precisa de um servidor de CA, rotação de chaves, scripts de assinatura, talvez até uma dashboard pra gerenciar tudo.

Mas a alternativa — ficar gerenciando authorized_keys em 50 servidores, descobrir que alguém saiu três meses depois porque ainda tinha acesso, perder uma manhã debugando um “Permission denied” — é pior.

Eu implementei isso num projeto com 12 servidores e 8 desenvolvedores. O setup inicial levou um dia. Depois disso, adicionar um novo desenvolvedor leva 5 minutos: gerar chave, assinar, entregar o certificado. Zero configuração em qualquer servidor.

Se você trabalha com infraestrutura, deploy automation ou qualquer coisa que envolva SSH em múltiplas máquinas, dá uma chance. Eu não voltei pra modelo tradicional depois que experimentei.


🔧 E você? Qual automação relacionado a servidores, deploy ou segurança você gostaria de ver aqui no AutoMente? Me conta nos comentários — pode ser que o próximo post resolva exatamente o seu problema. Se já usa Certificate Authentication, compartilha o perrengue que você enfrentou na implementação. Ajuda mais gente do que você imagina.

Categoria: Fortaleza Digital

Posts Similares