SSH agent forwarding: acessando repositórios via jump hosts
1. Fundamentos do SSH Agent Forwarding
SSH agent forwarding é um mecanismo que permite que um servidor remoto utilize as chaves SSH armazenadas no agente da sua máquina local, sem que você precise copiar a chave privada para o servidor intermediário. O funcionamento é simples: quando você se conecta a um host remoto com forwarding habilitado, o servidor cria um canal de comunicação com o agente SSH da sua máquina local. Qualquer tentativa de autenticação SSH feita a partir desse host remoto é redirecionada para o seu agente local, que realiza a assinatura criptográfica e retorna o resultado.
A diferença fundamental entre agent forwarding e cópia de chaves privadas é que, no forwarding, a chave privada nunca sai da sua máquina. Apenas operações de assinatura são delegadas ao agente local. Isso elimina o risco de exposição da chave caso o servidor intermediário seja comprometido.
O cenário típico envolve um desenvolvedor em sua máquina local (workstation) que precisa acessar um servidor Git remoto (como GitHub, GitLab ou Bitbucket) através de um servidor intermediário (jump host ou bastion host). Esse jump host é o único ponto de entrada na rede corporativa, e o servidor Git está acessível apenas a partir dele.
2. Configuração Básica do Ambiente
Primeiro, verifique se o agente SSH está em execução na sua máquina local:
$ ssh-add -l
The agent has no identities.
Se o agente não estiver rodando, inicie-o:
$ eval "$(ssh-agent -s)"
Agent pid 12345
Adicione sua chave privada ao agente:
$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/usuario/.ssh/id_ed25519:
Identity added: /home/usuario/.ssh/id_ed25519 (usuario@exemplo.com)
Configure o arquivo ~/.ssh/config para habilitar o forwarding para o jump host:
Host jump-host
HostName jump.exemplo.com
User usuario
ForwardAgent yes
IdentityFile ~/.ssh/id_ed25519
A diretiva ForwardAgent yes instrui o cliente SSH a encaminhar o agente para a sessão remota. Sem essa configuração, o forwarding não ocorre.
3. Jump Hosts e Acesso a Repositórios Git
A estrutura de conexão típica é: local → jump host → servidor Git remoto. O comando git clone precisa atravessar o jump host para alcançar o repositório.
Exemplo prático usando -J (atalho para ProxyJump):
$ git clone -J usuario@jump.exemplo.com git@github.com:usuario/repositorio.git
Para maior clareza, configure o ~/.ssh/config com o proxy:
Host github.com
HostName github.com
User git
ProxyJump usuario@jump.exemplo.com
ForwardAgent yes
Agora o clone fica simples:
$ git clone git@github.com:usuario/repositorio.git
Para verificar se o forwarding está funcionando, conecte-se ao jump host e execute:
$ ssh usuario@jump.exemplo.com
$ echo $SSH_AUTH_SOCK
/tmp/ssh-XXXXXX/agent.XXXX
$ ssh-add -l
256 SHA256:xxxxxxxxxx usuario@exemplo.com (ED25519)
A presença da variável SSH_AUTH_SOCK e a listagem das chaves confirmam que o agente local foi encaminhado.
4. Segurança e Riscos do Forwarding
O principal risco do SSH agent forwarding é que qualquer usuário com privilégios de root no jump host pode utilizar sua chave para autenticar em outros servidores. Durante o período em que você está conectado, o socket do agente fica acessível no sistema de arquivos remoto.
Boas práticas de segurança:
- Configure
ForwardAgent nocomo padrão no~/.ssh/confige habilite apenas para hosts específicos - Use
ForwardAgent noglobal e habilite apenas para o jump host confiável:
Host *
ForwardAgent no
Host jump-host
ForwardAgent yes
- Nunca use forwarding para hosts públicos ou não confiáveis
- Utilize
ssh -Aapenas quando necessário, não por padrão
Uma alternativa mais segura é usar ProxyJump sem forwarding. Nesse caso, o jump host atua apenas como túnel, sem acesso às suas chaves:
Host github.com
HostName github.com
User git
ProxyJump usuario@jump.exemplo.com
ForwardAgent no
A diferença é sutil: com ProxyJump, a conexão SSH para o servidor Git é estabelecida diretamente da sua máquina, usando um túnel através do jump host. O jump host nunca vê as requisições de autenticação.
5. Solução de Problemas Comuns
Erro "Permission denied (publickey)" mesmo com chave carregada:
$ git clone git@github.com:usuario/repositorio.git
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Diagnóstico passo a passo:
- Teste a conexão SSH manualmente:
$ ssh -T git@github.com
Se falhar, teste a conexão ao jump host:
$ ssh -v usuario@jump.exemplo.com
- Verifique as permissões do diretório
~/.sshe da chave:
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
- Confirme que a chave está no agente:
$ ssh-add -l
- Teste o forwarding conectando ao jump host e verificando o agente remoto:
$ ssh usuario@jump.exemplo.com "ssh-add -l"
Se o comando retornar "The agent has no identities", o forwarding não está funcionando. Verifique se ForwardAgent yes está configurado corretamente.
6. Fluxos Avançados com Múltiplos Saltos
Para ambientes com múltiplos jump hosts (local → host1 → host2 → Git), configure o ProxyJump encadeado:
Host host1
HostName host1.exemplo.com
User usuario1
ForwardAgent yes
IdentityFile ~/.ssh/chave_para_host1
Host host2
HostName host2.exemplo.com
User usuario2
ProxyJump usuario1@host1.exemplo.com
ForwardAgent yes
IdentityFile ~/.ssh/chave_para_host2
Host github.com
HostName github.com
User git
ProxyJump usuario2@host2.exemplo.com
ForwardAgent no
Para usar identidades diferentes em cada salto, utilize ProxyCommand com controle fino:
Host host1
HostName host1.exemplo.com
User usuario1
IdentityFile ~/.ssh/chave_a
ForwardAgent yes
Host host2
HostName host2.exemplo.com
User usuario2
ProxyCommand ssh -W %h:%p host1
IdentityFile ~/.ssh/chave_b
ForwardAgent yes
Host github.com
HostName github.com
User git
ProxyCommand ssh -W %h:%p host2
IdentityFile ~/.ssh/chave_git
Nessa configuração, a chave chave_a autentica no host1, chave_b no host2, e chave_git no servidor Git. O forwarding só é necessário nos hosts intermediários se você precisar autenticar a partir deles.
7. Integração com Credential Helpers e Automação
É importante distinguir entre agent forwarding (para SSH) e credential helpers (para HTTPS). O credential helper armazena credenciais HTTP e não tem relação com o agente SSH.
Para automação, você pode configurar o agente para iniciar automaticamente em sessões SSH. Adicione ao ~/.bashrc ou ~/.zshrc:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi
Para controle fino do comando SSH usado pelo Git, utilize GIT_SSH_COMMAND:
$ GIT_SSH_COMMAND="ssh -o ForwardAgent=yes -J usuario@jump.exemplo.com" git clone git@github.com:usuario/repositorio.git
Isso permite sobrescrever o comportamento padrão sem modificar o ~/.ssh/config. Você pode definir essa variável no ~/.bashrc para sessões específicas:
export GIT_SSH_COMMAND="ssh -o ForwardAgent=yes -J usuario@jump.exemplo.com"
Lembre-se: o forwarding é uma ferramenta poderosa, mas use com discernimento. Prefira ProxyJump sem forwarding sempre que possível, e reserve o agent forwarding apenas para cenários onde o jump host precisa autenticar em seu nome.
Referências
- OpenSSH Manual: ssh_config - ForwardAgent — Documentação oficial da diretiva ForwardAgent e suas opções de configuração
- Git SCM: Git on the Server - Generating Your SSH Public Key — Guia oficial do Git sobre configuração de chaves SSH e agent forwarding
- GitHub Docs: Using SSH agent forwarding — Tutorial oficial do GitHub sobre agent forwarding em cenários corporativos
- DigitalOcean Tutorial: How To Configure SSH Agent Forwarding — Guia prático com exemplos de configuração e solução de problemas
- Red Hat Blog: SSH agent forwarding considered harmful — Análise dos riscos de segurança do agent forwarding e alternativas recomendadas
- Arch Linux Wiki: SSH Keys - Agent forwarding — Documentação comunitária detalhada sobre configuração e boas práticas
- Stack Overflow: How to use git with SSH agent forwarding through jump host — Discussão técnica com soluções para problemas comuns de forwarding em Git