Jump Host en SSH, cómo usar un proxy

Publicado por Diego Córdoba el

Hoy aprenderemos a realizar una conexión con Jump Host en SSH hacia un servidor remoto, mediante la conexión previa a uno o más Jump Hosts o Proxys.

Respondiendo una consulta de mis alumnos del curso de SSH, hoy voy a pasar a explicar el uso de proxys, jump hosts, o servidores intermedios para establecer un canal seguro SSH contra un servidor remoto.

Supongamos el siguiente caso práctico: Tenemos acceso SSH hacia un servidor en Internet, digamos, Server A, y desde ese servidor podemos conectar, también por SSH, a un segundo servidor, Server B.

Veamos una ilustración del caso.

jump host en SSH

Si necesitamos realizar regularmente conexiones hacia el Server B, deberíamos, en cada caso, realizar una conexión previa contra el Server A para, desde ahí, conectar al segundo servidor.

Veamos cómo podemos implementar, mediante el cliente ssh, este salto de manera automática.

Jump Host en SSH: práctica

Supongamos que el acceso SSH hacia el Server A es:

ssh diego@ip_server_A

Mientras que el acceso al Server B desde el Server A es:

ssh juan@ip_server_B

Podríamos utilizar la opción de Jump Host provista por el cliente SSH: -J, de la siguiente forma.

Desde nuestra computadora cliente:

ssh -J diego@ip_server_A juan@ip_server_B

Así, el cliente SSH establecerá primero un túnel seguro contra el Server A, y desde ahí, automáticamente, realizará la conexión contra el Server B, y nos devolverá un prompt del Server B.

Jump Host en SSH con otros comandos

Como sabemos, SSH provee varias utilidades del lado del cliente, entre ellas, una que suelo utilizar mucho: scp (Secure Copy).

Esta herramienta permite copiar archivos, como si se tratase de un simple comando cp, pero en lugar de realizar la copia local, lleva a cabo copias remotas entre hosts de la red.

Veamos un ejemplo simple: voy a copiar el archivo test.txt desde mi directorio local, hacia el directorio home de mi usuario remoto en el sistema 192.168.0.150:

scp test.txt diego@192.168.0.150

De esa forma, mi computadora creará un túnel seguro contra el host 192.168.0.150, y copiará el archivo local, test.txt, dentro del directorio Home del usuario diego en el equipo remoto.

Ahora bien, el comando scp también tiene la posibilidad de usar un Jump Host para copiar archivos hacia y desde un equipo remoto que esté más allá del proxy.

Supongamos que ahora quiero copiar mi archivo local, test.txt, dentro del Server B del caso práctico anterior, y no puedo hacerlo directamente, sino que necesito conectar primero con el jump host Server A.

Esto puede realizarse de la siguiente manera:

scp -J diego@ip_server_A test.txt juan@ip_server_B

Esto también es posible mediante el comando sftp, esta utilidad pseudo-ftp que conecta al host remoto utilizando un túnel SSH.

sftp -J diego@ip_server_A test.txt juan@ip_server_B

Dentro del prompt de sftp ahora se podrán subir o bajar archivos libremente.

En ambos casos, la conexión al jump host intermedio es totalmente transparente para el usuario.

Configuración persistente

SSH permite configurar los jump host de manera persistente, de modo que podríamos pedir una conexión contra un host remoto, y que el cliente ssh automáticamente detecte que dicha conexión es posible mediante un proxy, y realice la conexión previa.

Para ilustrar el caso práctico anterior, supongamos los siguientes dos bloques Host en la configuración de nuestro cliente SSH, ya sea directamente en el archivo ~/.ssh/config, o en un archivo específico dentro de ~/.ssh/config.d.

[...]
Host serverA
    HostName ip_server_A
    User diego

Host serverB
    HostName ip_server_B
    User juan
    ProxyJump serverA
[...]

Así, podríamos establecer la conexión contra el Server B, pasando por el Server A como proxy, utilizando en nuestra terminal algo similar a esto:

ssh serverB

El cliente SSH realizará la conexión previa al Jump Host tal y como lo especificamos en la configuración.

Consideraciones de seguridad

No hemos hablado de la autenticación, y en esto es bastante importante.

Una de las razones por las que solemos utilizar estos Jump Servers, o Bastion Hosts, es para evitar dejar varios servidores con el SSH abierto a Internet. Así, podríamos tener una red de servidores con IP privada, conectados a Internet a través de un host Bastión, con reglas de firewall, e IP pública, de modo que la única manera de acceder, vía SSH, a los servidores internos, sea utilizando el bastión como Jump Server.

Esa seguridad puede verse perjudicada por la autenticación mediante contraseñas, ya que puede permitirle a un usuario malintencionado realizar un ataque de fuerza bruta al servicio.

Siempre es mejor optar por claves asimétricas para realizar la autenticación.

En nuestro caso será recomendable crear dos pares de claves asimétricas (idealmente ed25519, como explico acá):

  • Un par para autenticarse con el bastion host.
  • Otro par para autenticarse con el servidor interno.

Los pasos deberían ser:

  1. Crear el par de claves del jump server.
  2. Copiar la clave pública del jump server en el archivo .ssh/authorized_keys del directorio home del usuario de conexión.
  3. Crear el par de claves del servidor privado.
  4. Copiar la clave pública del servidor privado en el archivo .ssh/authorized_keys del directorio home del usuario de conexión.

Cómo crear las claves? Podés verlo en este artículo del blog o en este video en el canal de YouTube).

Una vez creadas las claves, podemos añadir la configuración a nuestros bloques Host mediante la entrada IdentityFile de esta forma:

[...]
Host serverA
    HostName ip_server_A
    User diego
    IdentityFile ~/.ssh/serverr_A

Host serverB
    HostName ip_server_B
    User juan
    IdentityFile ~/.ssh/serverr_B
    ProxyJump serverA
[...]

Varios Jump Hosts en SSH?

Dato adicional, si entre origen y destino tuviéramos varios proxys o Jump Hosts, podemos cargarlos separando por comas en los comandos SSH anteriores, por ejemplo:

ssh -J diego@ip_server_A, miusuario@otro_proxy juan@ip_server_B

Para el caso de la configuración persistente, sólo será cuestión de añadir otro bloque de configuración al anterior:

[...]
Host serverA
    HostName ip_server_A
    User diego

Host otro_proxy
    HostName ip_otro_proxy
    User miusuario
    ProxyJump serverA

Host serverB
    HostName ip_server_B
    User juan
    ProxyJump otro_proxy
[...]

Conclusiones

Y hemos llegado al final! Espero que les resulte útil y práctico este tip de SSH, y les sirva para conocer una opción un tanto «rara» del cliente SSH.

Un dato adicional, como mencioné en el apartado de autenticación, yo en ningún momento he tenido que escribir la contraseña de mis servidores para realizar todos los túneles, dado que tengo configurado el acceso mediante clave pública y privada. De no tener estas configuraciones, el cliente ssh nos solicitará la contraseña de autenticación contra cada uno de los Jump Hosts y contra el server final.

Si quieren saber dónde pueden obtener más info, nunca está de mas consultar el man ssh 🙂 #RTFM

Sin más, cualquier comentario saben dónde encontrarnos, no será molestia.

Será hasta la próxima!

Material adicional (embed)


¿Querés aprender más? 📚

👉 Visitá nuestros cursos!
💬 Y si tenés dudas, o querés dejarnos tus comentarios sumate a la Comunidad JuncoTIC en Telegram!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mgtr. Teleinformática - Instructor GNU/Linux, Programación, Redes TCP/IP, criptografía y ciberseguridad. - (Ex) Docente universitario e investigador