SSH Agent, Agent Forwarding e Certificados SSH
Nota: Este é o oitavo tutorial da série sobre SSH. Se você perdeu o anterior sobre tunelamento e port forwarding, pode encontrá-lo aqui: Túneis SSH e Redirecionamento de Portas.
Nos tutoriais anteriores, estabelecemos que a autenticação por chave pública é o método preferencial e mais seguro para SSH. Também recomendamos fortemente o uso de uma passphrase para proteger sua chave privada contra roubo ou uso indevido. No entanto, digitar a passphrase toda vez que você usa a chave pode se tornar tedioso, especialmente se você se conecta a muitos servidores ou usa comandos como scp
e rsync
frequentemente.
Felizmente, o OpenSSH fornece uma solução elegante para isso: o ssh-agent
. Além disso, exploraremos o conceito de Agent Forwarding e introduziremos os Certificados SSH, uma abordagem mais escalável para gerenciar o acesso em ambientes maiores.
1. ssh-agent
: Conveniência sem Comprometer a Segurança
O ssh-agent
é um programa auxiliar que roda em segundo plano na sua sessão local. Sua principal função é manter suas chaves privadas SSH descriptografadas na memória, permitindo que o cliente ssh
(e ferramentas relacionadas como scp
, sftp
, rsync
) as utilize sem que você precise digitar a passphrase repetidamente.
Como Funciona:
- Você inicia o
ssh-agent
. - Você adiciona suas chaves privadas ao agente usando
ssh-add
, digitando a passphrase de cada chave apenas uma vez. - O agente mantém as chaves descriptografadas em memória.
- Quando o cliente
ssh
precisa de uma chave para autenticar, ele se comunica com o agente (através de um socket Unix) e pede para ele realizar a operação criptográfica necessária (o desafio-resposta que vimos no Tutorial 3). - O agente realiza a operação usando a chave descriptografada em memória, sem nunca expor a chave privada descriptografada ao cliente
ssh
ou a outros processos.
Benefício: Você combina a segurança de ter uma passphrase forte na sua chave privada com a conveniência de não precisar digitá-la a cada conexão durante sua sessão de trabalho.
Uso Básico:
- Iniciar o Agente: O
ssh-agent
precisa ser iniciado de uma forma que os processos subsequentes (como seu shell) herdem suas variáveis de ambiente (principalmenteSSH_AUTH_SOCK
, que aponta para o socket de comunicação). A maneira mais comum é:1
eval $(ssh-agent -s)
ssh-agent -s
: Inicia o agente e imprime os comandos de shell (export SSH_AUTH_SOCK=...; export SSH_AGENT_PID=...;
) necessários para configurar o ambiente.eval $(...)
: Executa esses comandos no shell atual.- Você verá uma saída como
Agent pid 12345
. - Nota: Muitas distribuições Linux e ambientes de desktop modernos iniciam automaticamente um
ssh-agent
quando você faz login gráfico, então este passo pode não ser necessário. Verifique se a variávelSSH_AUTH_SOCK
já está definida (echo $SSH_AUTH_SOCK
).
- Adicionar Chaves ao Agente (
ssh-add
): Uma vez que o agente está rodando e seu shell sabe como falar com ele, usessh-add
para carregar suas chaves:1 2 3 4
# Adiciona a chave padrão (ex: ~/.ssh/id_ed25519) ssh-add # Ou especifica uma chave: ssh-add ~/.ssh/id_minha_outra_chave
- Ele solicitará a passphrase da chave que você está adicionando.
- Digite a passphrase uma vez.
- Você verá uma mensagem como
Identity added: /home/seu_usuario/.ssh/id_ed25519 (seu_usuario@sua_maquina)
. - Agora, qualquer comando
ssh
subsequente tentará usar as chaves carregadas no agente automaticamente, sem pedir a passphrase novamente (até que o agente seja encerrado ou a chave removida).
- Listar Chaves Carregadas: Para ver quais chaves (suas impressões digitais) estão atualmente carregadas no agente:
1
ssh-add -l
Para ver as chaves públicas completas:
1
ssh-add -L
- Remover Chaves do Agente:
- Remover uma chave específica (use
ssh-add -l
para ver o caminho):1
ssh-add -d ~/.ssh/id_ed25519
- Remover todas as chaves do agente:
1
ssh-add -D
- Remover uma chave específica (use
- Encerrar o Agente: Geralmente, o agente é encerrado quando você faz logout da sua sessão. Se você o iniciou manualmente e quer encerrá-lo:
1
ssh-agent -k
(Isso usará as variáveis de ambiente definidas pelo
eval
para encontrar e matar o processo correto).
2. Agent Forwarding (ssh -A
)
Imagine o cenário da nossa arquitetura de referência: você está na sua Estação de Trabalho e quer conectar ao simulated-device
, o que requer passar pelo kvm-server
e pela eve-ng-vm
. Se você usa autenticação por chave, onde a chave privada deve estar?
Sem Agent Forwarding: Você precisaria ter sua chave privada (ou uma chave específica) copiada para o
kvm-server
para autenticar naeve-ng-vm
, e também copiada para aeve-ng-vm
para autenticar nosimulated-device
. Isso é inconveniente e aumenta a exposição da sua chave privada.Com Agent Forwarding: O Agent Forwarding permite que sua conexão SSH para um servidor intermediário (ex:
kvm-server
) também encaminhe o acesso ao seussh-agent
local (rodando na sua Estação de Trabalho). Quando você, a partir dokvm-server
, tenta conectar ao próximo salto (eve-ng-vm
), o clientessh
nokvm-server
pode pedir ao seussh-agent
local (através do túnel encaminhado) para realizar a autenticação usando a chave que está segura na sua Estação de Trabalho.
Como Habilitar:
- Via Linha de Comando: Use a flag
-A
:1 2 3
ssh -A kvm-server # Agora, dentro da sessão no kvm-server: ssh eve-ng-vm # Usará o agente encaminhado da sua Estação
- Via
~/.ssh/config
: Adicione a diretivaForwardAgent yes
ao blocoHost
relevante:1 2 3 4 5 6 7 8 9 10
Host kvm-server HostName 192.168.0.254 User user_kvm ForwardAgent yes Host eve-ng-vm HostName 192.168.122.50 User user_eve ProxyJump kvm-server # Não precisa de ForwardAgent aqui, pois o ProxyJump já lida com isso
Com esta configuração,
ssh kvm-server
habilitará o forwarding, essh eve-ng-vm
(que usaProxyJump
) também se beneficiará implicitamente do agente para o salto final, se necessário.
Conveniência vs. Risco:
O Agent Forwarding é extremamente conveniente para cenários de múltiplos saltos (jump hosts/bastions). No entanto, ele introduz um risco de segurança: se o servidor intermediário (kvm-server
no exemplo) estiver comprometido, um atacante com privilégios de root nesse servidor poderia, teoricamente, acessar o socket do agente encaminhado e usar seu ssh-agent
local para se autenticar como você em outros servidores aos quais sua chave dá acesso, mesmo sem ter sua chave privada. Eles não podem roubar a chave privada, mas podem usá-la enquanto o forwarding estiver ativo.
Recomendação: Use Agent Forwarding com cautela. Habilite-o apenas quando necessário e apenas para servidores intermediários nos quais você confia completamente. Evite usá-lo como padrão para todos os hosts (ForwardAgent yes
em Host *
). Considere alternativas como ProxyJump
(que geralmente não requer Agent Forwarding explícito para o salto final se a chave estiver no seu agente local) ou Certificados SSH.
3. Certificados SSH: Gerenciamento Escalável
Gerenciar chaves públicas individuais (authorized_keys
em cada servidor para cada usuário) pode se tornar complexo em ambientes com muitos usuários e servidores. É preciso distribuir chaves, revogá-las quando alguém sai, garantir que as permissões estejam corretas, etc.
Os Certificados SSH oferecem uma abordagem mais centralizada e escalável, inspirada nos certificados SSL/TLS usados na web.
Conceito:
- Autoridade Certificadora (CA): Você cria um par de chaves SSH especial que atuará como sua CA interna. A chave privada da CA é mantida extremamente segura.
- Assinatura de Chaves: Em vez de copiar a chave pública de um usuário para todos os servidores, você usa a chave privada da CA para assinar a chave pública do usuário. Isso gera um certificado de usuário SSH (um arquivo
.pub
que contém a chave pública original mais a assinatura da CA e metadados como validade, principais permitidos, etc.). - Confiança na CA: Você configura seus servidores SSH para confiar na chave pública da sua CA (usando a diretiva
TrustedUserCAKeys
nosshd_config
). - Autenticação: Quando um usuário tenta se conectar usando seu certificado assinado:
- O cliente envia o certificado (que contém a chave pública do usuário e a assinatura da CA) para o servidor.
- O servidor verifica se a assinatura no certificado é válida usando a chave pública da CA que ele confia.
- Se a assinatura for válida e os metadados do certificado (validade, etc.) estiverem OK, o servidor prossegue com o desafio-resposta usando a chave pública do usuário contida no certificado (o usuário ainda precisa provar que possui a chave privada correspondente).
Benefícios:
- Gerenciamento Centralizado: Você só precisa distribuir a chave pública da CA para os servidores uma vez. A adição/remoção de usuários é gerenciada assinando/revogando certificados, sem tocar nos arquivos
authorized_keys
dos servidores. - Chaves de Curta Duração: Certificados podem ter um tempo de validade curto (horas, dias), melhorando a segurança. O usuário precisa obter um novo certificado assinado periodicamente.
- Simplificação de
known_hosts
(Certificados de Host): O mesmo conceito pode ser aplicado aos hosts. Você cria uma CA de host, assina as chaves públicas dos seus servidores e configura os clientes para confiar na CA de host (usando@cert-authority
noknown_hosts
). Isso elimina a necessidade de gerenciar chaves de host individuais e evita os avisos de “REMOTE HOST IDENTIFICATION HAS CHANGED” quando um host é provisionado ou sua chave muda legitimamente. - Metadados: Certificados podem conter informações adicionais, como quais nomes de usuário (principals) o certificado permite usar ou opções forçadas (
ForceCommand
).
Como Funciona (Visão Geral):
- Gerar Chave da CA:
1
ssh-keygen -t ed25519 -f ca_user_key # Sem passphrase na CA é comum, mas proteja bem o arquivo!
- Assinar Chave Pública do Usuário:
1 2 3 4
# user_key.pub é a chave pública normal do usuário ssh-keygen -s ca_user_key -I <identificador_certificado> -n <principals_permitidos> -V +<validade> user_key.pub # Ex: ssh-keygen -s ca_user_key -I user_alice_cert -n alice,root -V +8h ~/.ssh/id_ed25519.pub # Isso cria ~/.ssh/id_ed25519-cert.pub (o certificado)
- Configurar Servidor para Confiar na CA:
- Copie a chave pública da CA (
ca_user_key.pub
) para o servidor (ex:/etc/ssh/ca_user_key.pub
). - Adicione ao
/etc/ssh/sshd_config
:1
TrustedUserCAKeys /etc/ssh/ca_user_key.pub
- Reinicie o
sshd
.
- Copie a chave pública da CA (
- Configurar Cliente para Usar Certificado:
- O cliente
ssh
usará automaticamente o arquivo-cert.pub
se ele existir junto com a chave privada correspondente (id_ed25519
eid_ed25519-cert.pub
).
- O cliente
- Certificados de Host (Similar):
- Gerar CA de host (
ca_host_key
). - Assinar chave pública do servidor (
/etc/ssh/ssh_host_ed25519_key.pub
):1 2
ssh-keygen -s ca_host_key -h -I <id_host> -n <hostname_ou_ip_permitido> /etc/ssh/ssh_host_ed25519_key.pub # Cria /etc/ssh/ssh_host_ed25519_key-cert.pub
- Configurar servidor para usar o certificado (adicionar ao
sshd_config
):1
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
- Configurar cliente para confiar na CA de host (adicionar ao
~/.ssh/known_hosts
):1
@cert-authority *.seudominio.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5[...] # Conteúdo de ca_host_key.pub
- Gerar CA de host (
Quando Usar Certificados?
Certificados SSH são mais complexos de configurar inicialmente, mas valem muito a pena em ambientes com um número significativo de usuários e/ou servidores, onde o gerenciamento de chaves individuais se torna impraticável. Para uso pessoal ou em pequenas equipes, o ssh-agent
e o gerenciamento manual de authorized_keys
podem ser suficientes.
Conclusão
O gerenciamento eficaz das chaves SSH é crucial tanto para a segurança quanto para a conveniência. O ssh-agent
nos permite usar chaves protegidas por passphrase sem a inconveniência de digitá-la repetidamente. O Agent Forwarding (-A
) oferece uma maneira de usar chaves locais em saltos remotos, mas deve ser usado com cautela devido aos riscos de segurança.
Para ambientes maiores e mais complexos, os Certificados SSH fornecem uma solução robusta e escalável, centralizando a confiança em uma CA e simplificando o gerenciamento de acesso de usuários e a verificação de hosts.
No próximo tutorial, abordaremos técnicas de hardening e melhores práticas de segurança para fortalecer ainda mais suas configurações de cliente e servidor SSH.