Sesión SSH a través de jumphost a través de reenvío de puerto remoto

Tenemos un problema al hacer conexiones SSH a través del reenvío de puertos remotos.

El escenario es una networking empresarial, donde un server en la networking interna (llamémoslo "origen") debe iniciar session a través de SSH a un server en la DMZ ("destino"). Dado que el server de destino en la DMZ está bloqueado para las conexiones desde la networking interna (y ni siquiera se puede ver desde la networking interna), tenemos un host de salto en la DMZ por el que pasamos ("jumphost"). Hacemos esto configurando el reenvío de puertos remotos en Jumphost.

Ejecutamos este command desde el server de origen en la networking interna, hasta el jumphost:

origin> ssh -R *:1234:target:22 myusername@jumphost 

Esto es para establecer una session SSH en jumphost, hacer que comience a escuchar en el puerto 1234 (solo un ejemplo de número de puerto arbitrario) y reenviar conexiones en ese puerto al puerto 22 del server de destino (SSH).

Luego establecemos una segunda session de SSH, aún desde el server de origen hasta el Jumphost, en el puerto 1234, que luego se conecta al server de destino en el puerto 22: esta es nuestra session SSH 'real' donde podemos hacer nuestro trabajo en el server de destino:

 origin> ssh jumphost -P 1234 

Configuración

El host de salto se ha configurado para permitir el reenvío de puertos remotos, con la siguiente configuration en sshd_config:

 AllowTcpForwarding yes GatewayPorts yes 

Además, existen aperturas de cortafuegos entre el server de origen y el host de salto, para el puerto 22 (para la connection SSH inicial para configurar el reenvío de puerto remoto) y el puerto 1234 (para la connection SSH posterior en el puerto reenviado). También hay un cortafuegos entre Jumphost y el objective, que se ha abierto en el puerto 22.

Salir

Cuando establecemos la segunda connection (una a través del puerto reenviado), la connection se cierra inmediatamente ('connection cerrada por el host remoto').

La ejecución de tcpdump en el server de destino no muestra actividad, es decir, parece que la connection se bloquea.

Sin embargo, podemos establecer con éxito una session regular de SSH desde Jumphost al objective. Solo cuando se ingresa por el puerto reenviado se cierra la connection, aunque ambos se conectan al objective en el puerto 22.

Además, si hacemos que el punto de reenvío del puerto a un server en la networking interna (es decir, una connection desde el origen en la networking interna, al jumphost en la DMZ y de vuelta a un tercer server en la networking interna), entonces el SSH la session se establece con éxito.

Especulación y preguntas

Todo esto me lleva a pensar que hay una cierta configuration de security de la networking en juego, que impide la connection a través del puerto reenviado en el server de salto al server de destino dentro de la DMZ. Desafortunadamente no estoy lo suficientemente informado como para saber:

(1) ¿Está una connection SSH proveniente del server de origen, a través de un puerto reenviado en el server de salto, 'diferente', desde el punto de vista de la política de security de la networking, que técnicamente podría estar bloqueada y, de ser así, cómo? ¿Y qué debería hacerse para eliminar esa restricción?

(2) Cualquier otra razón por la que no se permite esta connection: configuration del firewall, configuration del enrutador, configuration de SSH en el origen o Jumphost, ¿alguna otra cosa?

(3) ¿Podría fallar porque el server de origen no conoce el server de destino y, por lo tanto, el primer command ssh no funciona como se esperaba? En otras palabras, ¿el nombre de host especificado en el primer command ssh ("objective") se interpreta en el cliente (origen) o en el server al que nos estamos conectando para crear el túnel (el Jumphost)?

Lo que más me sorprende es que se puede establecer una session regular de SSH desde el Jumphost al objective, creo que la connection SSH que entra por el puerto reenviado sería la misma, pero de alguna manera no lo es.

Cualquier input muy apreciada.

Parece que debe usar el reenvío de puertos local en lugar del reenvío de puertos remoto. Es posible que desee consultar la siguiente publicación de blog útil de Dirk Loss:

  • Reenvío de puerto SSH visualizado

Incluye el siguiente diagtwig ilustrativo:

reenvío de puertos ssh: local vs remoto

Para leer el diagtwig, debe saber que describe las relaciones entre 4 roles diferentes involucrados en la creación y utilización de un túnel SSH:

  • un cliente ssh ( ssh ) utilizado para establecer el túnel;
  • un server ssh ( sshd ) utilizado para mantener el otro extremo del túnel;
  • un server de aplicaciones (por ejemplo, otro server ssh o un server http);
  • un cliente de aplicación (por ejemplo, otro cliente ssh o un browser web) que quiere acceder al server de aplicaciones a través del túnel.

También es importante entender que los dos types diferentes de reenvío corresponden a dos casos de uso diferentes:

  • Reenvío local: donde el cliente de la aplicación se conecta a través del cliente ssh

  • Reenvío remoto: donde el cliente de la aplicación se conecta a través del server ssh

El reenvío remoto se denomina así porque el reenvío se realiza de forma remota (en el server ssh) en lugar de localmente (en el cliente ssh). También encuentro que "reenvío remoto = reenvío inverso" es un mnemónico útil.

Como puede ver, para iniciar una connection desde un cliente ssh en el host de origin través de un server sshd en un jumphost proxy a un tercer host de target , tendría que usar el reenvío de puertos local. El reenvío de puertos remotos es para el caso en el que desea ubicar el punto de input al túnel en el host que ejecuta el server sshd en lugar de en el host que ejecuta el cliente ssh .

En la página de manual, la syntax de reenvío de puertos local se escribe de la siguiente manera:

 ssh -L [bind_address:]port:host:hostport user@remote 

Esto se puede escribir de manera más intuitiva como el siguiente:

 ssh -L [local_bind_address:]local_port:remote_host:remote_host_port user@proxy_host 

O, usando sus convenciones de nombres:

 ssh -L [origin_bind_address:]origin_port:target_host:target_host_port user@jump_host 

Si modificamos su command para usar el reenvío de puertos local, entonces terminamos con lo siguiente:

 user@origin:~$ ssh -L *:1234:target:22 myusername@jumphost