ProxyJump e Redes Complexas
Nota: Este é o nono tutorial da série sobre SSH. Se você perdeu o anterior sobre ssh-agent e gerenciamento de chaves, pode encontrá-lo aqui: SSH Agent, Agent Forwarding e Certificados SSH.
Em muitos ambientes de rede corporativos ou complexos, por razões de segurança, os servidores críticos não são diretamente acessíveis pela internet ou mesmo de todas as partes da rede interna. Em vez disso, o acesso é canalizado através de servidores intermediários especialmente designados, conhecidos como Bastion Hosts ou Jump Hosts (ou Jump Servers).
Esses servidores atuam como um ponto de entrada controlado e monitorado para segmentos de rede mais seguros. Para acessar um servidor final (destino), você primeiro se conecta ao bastion host e, a partir dele, estabelece uma segunda conexão para o destino.
Fazer isso manualmente (conectar ao bastion, depois digitar ssh destino dentro dessa sessão) funciona, mas é inconveniente, especialmente para transferências de arquivos (scp, rsync) ou se houver múltiplos saltos. Felizmente, o OpenSSH (versão 7.3 e posteriores) oferece uma maneira muito mais elegante e transparente de lidar com isso: a diretiva ProxyJump (e sua flag de linha de comando correspondente -J).
O Conceito: Salto Transparente
O ProxyJump permite que o cliente ssh estabeleça automaticamente a conexão com o servidor intermediário (bastion) e, em seguida, use o comando sshd nesse intermediário para encaminhar a conexão TCP para o destino final, tudo dentro de um único comando ssh iniciado na sua máquina local.
Para o usuário, parece que ele está se conectando diretamente ao host de destino, embora a conexão esteja sendo seguramente tunelada através do(s) bastion(s).
Conectando Através de Um Salto (Bastion Host)
Vamos usar nossa arquitetura de referência. Queremos conectar da nossa Estação de Trabalho (192.168.0.10) para a VM EVE-NG (192.168.122.50), mas só podemos acessar diretamente o Servidor KVM (192.168.0.254), que funciona como nosso bastion host.
Método 1: Usando a Flag -J (Jump Host)
A flag -J permite especificar o(s) jump host(s) diretamente na linha de comando.
1
ssh -J <usuario_bastion>@<host_bastion> <usuario_destino>@<host_destino>
No nosso exemplo, execute na Estação de Trabalho:
1
ssh -J user_kvm@192.168.0.254 user_eve@192.168.122.50
-J user_kvm@192.168.0.254: Especifica que devemos primeiro conectar ao Servidor KVM comouser_kvm.user_eve@192.168.122.50: O destino final.
O cliente ssh fará o seguinte:
- Conecta-se a
192.168.0.254comouser_kvm(pedirá autenticação - senha ou chave/agente). - Uma vez conectado, instrui o
sshdno KVM a estabelecer uma conexão TCP para192.168.122.50na porta 22. - Encaminha a comunicação entre sua máquina local e a VM EVE-NG através do túnel estabelecido com o KVM.
Você será solicitado a autenticar para o destino final (user_eve@192.168.122.50) como se estivesse conectando diretamente (novamente, usando senha ou chave/agente).
Método 2: Usando ~/.ssh/config (Recomendado)
Como vimos no Tutorial 5, podemos definir isso de forma permanente e mais limpa no nosso arquivo ~/.ssh/config usando a diretiva ProxyJump.
Relembrando nossa configuração:
1
2
3
4
5
6
7
8
9
10
11
# ~/.ssh/config
Host kvm-server
HostName 192.168.0.254
User user_kvm
Host eve-ng-vm
HostName 192.168.122.50
User user_eve
# Especifica o alias do bastion host
ProxyJump kvm-server
Com esta configuração, basta executar na Estação de Trabalho:
1
ssh eve-ng-vm
O cliente ssh lerá a configuração, verá a diretiva ProxyJump kvm-server, resolverá kvm-server para suas configurações (HostName 192.168.0.254, User user_kvm) e realizará o salto automaticamente.
Vantagens de usar ~/.ssh/config:
- Não precisa lembrar a sintaxe do
-Jou os detalhes do bastion host. - Funciona transparentemente com outras ferramentas SSH como
scp,sftp,rsync:1 2
scp meu_arquivo.txt eve-ng-vm:/caminho/remoto/ # Funciona! rsync -avz local_dir/ eve-ng-vm:~/remote_dir/ # Funciona!
Conectando Através de Múltiplos Saltos
O ProxyJump e a flag -J suportam elegantemente múltiplos saltos intermediários. Basta listar os jump hosts na ordem em que devem ser atravessados, separados por vírgula.
Vamos ao nosso exemplo de dois saltos: conectar da Estação de Trabalho (192.168.0.10) para o Dispositivo Simulado (10.240.0.50) passando primeiro pelo Servidor KVM (192.168.0.254) e depois pela VM EVE-NG (192.168.122.50).
Método 1: Usando a Flag -J
1
ssh -J <user_bastion1>@<host_bastion1>,<user_bastion2>@<host_bastion2> <user_destino>@<host_destino>
No nosso exemplo, execute na Estação de Trabalho:
1
ssh -J user_kvm@192.168.0.254,user_eve@192.168.122.50 user_device@10.240.0.50
O cliente ssh fará:
- Conecta ao
kvm-server. - A partir do
kvm-server, conecta àeve-ng-vm(usando osshddo KVM para encaminhar). - A partir da
eve-ng-vm, conecta aosimulated-device(usando osshdda EVE-NG para encaminhar).
Você será solicitado a autenticar em cada salto, se necessário (KVM, depois EVE-NG, depois Dispositivo Simulado).
Método 2: Usando ~/.ssh/config
O ~/.ssh/config lida com isso de forma ainda mais transparente. Se um host especificado em ProxyJump também tiver sua própria diretiva ProxyJump, o cliente encadeará os saltos automaticamente.
Relembrando nossa configuração completa do Tutorial 5:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ~/.ssh/config
Host kvm-server
HostName 192.168.0.254
User user_kvm
Host eve-ng-vm
HostName 192.168.122.50
User user_eve
ProxyJump kvm-server # Salto 1
Host simulated-device
HostName 10.240.0.50
User user_device
ProxyJump eve-ng-vm # Salto 2 (que por sua vez usa Salto 1)
Com esta configuração, para conectar ao destino final (Dispositivo Simulado), basta executar na Estação de Trabalho:
1
ssh simulated-device
O cliente ssh resolverá a cadeia: simulated-device precisa pular por eve-ng-vm, e eve-ng-vm precisa pular por kvm-server. Ele então executará a sequência de conexões necessária automaticamente.
Menção: Método Legado com ProxyCommand
Antes da introdução do ProxyJump (OpenSSH 7.3), a maneira padrão de configurar jump hosts no ~/.ssh/config era usando a diretiva ProxyCommand. Ela é mais genérica e poderosa, mas também mais complexa e propensa a erros de configuração.
ProxyCommand instrui o cliente ssh a executar um comando específico para estabelecer a conexão com o servidor, em vez de fazer uma conexão TCP direta. O comando deve receber dados na entrada padrão (stdin) e enviar dados para a saída padrão (stdout), que o ssh então usa para a comunicação.
Exemplo (equivalente a ProxyJump kvm-server para eve-ng-vm):
1
2
3
4
5
Host eve-ng-vm
HostName 192.168.122.50
User user_eve
# Método legado:
ProxyCommand ssh kvm-server -W %h:%p
ssh kvm-server: Executa um novo comandosshpara conectar ao bastion host (kvm-server, que deve estar definido em outro lugar no config ou ser resolvível).-W %h:%p: Esta é a parte crucial. A flag-W(disponível em versões mais recentes dossh) instrui osshno bastion a encaminhar stdin/stdout para o host (%h) e porta (%p) do destino final (eve-ng-vmneste caso), sem alocar um pty ou executar um shell no bastion.
Para múltiplos saltos com ProxyCommand, a configuração se torna ainda mais complexa, muitas vezes exigindo encadear múltiplos ssh -W ou usar ferramentas como netcat (nc) dentro do ProxyCommand.
Quando usar ProxyCommand hoje?
- Se você precisa de compatibilidade com versões do OpenSSH anteriores à 7.3.
- Em cenários muito específicos onde você precisa de lógica customizada para estabelecer a conexão que
ProxyJumpnão cobre (ex: usar um túnel diferente, executar um script de autenticação customizado antes de conectar).
Para a maioria dos casos de uso de bastion/jump hosts, ProxyJump (ou -J) é a abordagem moderna, mais simples e recomendada.
Conclusão
Navegar por redes complexas com múltiplos segmentos e firewalls é um desafio comum. Os bastion hosts fornecem um ponto de acesso seguro, e o ProxyJump do OpenSSH torna a conexão através desses intermediários uma tarefa transparente e eficiente.
Seja usando a flag -J para conexões ad-hoc ou, preferencialmente, configurando a diretiva ProxyJump no seu ~/.ssh/config, você pode simplificar enormemente o acesso a hosts remotos que não estão diretamente acessíveis, fazendo com que múltiplos saltos pareçam uma conexão direta.
No próximo tutorial, abordaremos técnicas de hardening e melhores práticas de segurança para cliente e servidor SSH.