Post

ProxyJump e Redes Complexas

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 como user_kvm.
  • user_eve@192.168.122.50: O destino final.

O cliente ssh fará o seguinte:

  1. Conecta-se a 192.168.0.254 como user_kvm (pedirá autenticação - senha ou chave/agente).
  2. Uma vez conectado, instrui o sshd no KVM a estabelecer uma conexão TCP para 192.168.122.50 na porta 22.
  3. 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 -J ou 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á:

  1. Conecta ao kvm-server.
  2. A partir do kvm-server, conecta à eve-ng-vm (usando o sshd do KVM para encaminhar).
  3. A partir da eve-ng-vm, conecta ao simulated-device (usando o sshd da 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 comando ssh para 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 do ssh) instrui o ssh no bastion a encaminhar stdin/stdout para o host (%h) e porta (%p) do destino final (eve-ng-vm neste 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 ProxyJump nã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.

This post is licensed under CC BY 4.0 by the author.