¿Cómo funciona el túnel de SSH inverso?

350

Según tengo entendido, los firewalls (suponiendo una configuración predeterminada) niegan todo el tráfico entrante que no tiene tráfico saliente correspondiente anterior.

Basado en revertir una conexión ssh y hacer un túnel SSH fácil , se puede usar un túnel SSH inverso para sortear las molestas restricciones de firewall.

Me gustaría ejecutar comandos de shell en una máquina remota. La máquina remota tiene su propio firewall y está detrás de un firewall adicional (enrutador). Tiene una dirección IP como 192.168.1.126 (o algo similar). No estoy detrás de un firewall y sé la dirección IP de la máquina remota como se ve desde Internet (no la dirección 192.168.1.126). Además, ssh (something)primero puedo pedirle a alguien que se ejecute como root en la máquina remota.

¿Podría alguien explicarme, paso a paso, cómo funciona el túnel de SSH inverso para sortear los firewalls (firewalls de máquinas locales y remotas y el firewall adicional entre ellos)?

¿Cuál es el papel de los interruptores ( -R, -f, -L, -N)?

Ali
fuente

Respuestas:

403

Me encanta explicar este tipo de cosas a través de la visualización. :-)

Piense en sus conexiones SSH como tubos. Tubos grandes Normalmente, alcanzará a través de estos tubos para ejecutar un shell en una computadora remota. El shell se ejecuta en una terminal virtual (tty). Pero ya conoces esta parte.

Piense en su túnel como un tubo dentro de un tubo. Todavía tiene la gran conexión SSH, pero la opción -L o -R le permite configurar un tubo más pequeño dentro de ella.

Cada tubo tiene un principio y un final. El gran tubo, su conexión SSH, comenzó con su cliente SSH y termina en el servidor SSH al que se conectó. Todos los tubos más pequeños tienen los mismos puntos finales, excepto que la función de "inicio" o "fin" está determinada por si los usó -Lo -R(respectivamente) para crearlos.

(No lo ha dicho, pero voy a suponer que la máquina "remota" que ha mencionado, la que está detrás del firewall, puede acceder a Internet usando la Traducción de direcciones de red (NAT). Esto es algo importante, así que corrija esta suposición si es falsa).

Cuando crea un túnel, especifica una dirección y un puerto en el que responderá, y una dirección y un puerto al que se entregará. La -Lopción le dice al túnel que responda en el lado local del túnel (el host que ejecuta su cliente). La -Ropción le dice al túnel que responda en el lado remoto (el servidor SSH).

direcciones del túnel ssh

Entonces ... Para poder SSH desde Internet en una máquina detrás de un firewall, necesita la máquina en cuestión para abrir una conexión SSH al mundo exterior e incluir un -Rtúnel cuyo punto de "entrada" sea el lado "remoto" de Su conexión.

De los dos modelos que se muestran arriba, desea el de la derecha.

Del anfitrión con cortafuegos:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

Esto le dice a su cliente que establezca un túnel con un -Rpunto de entrada de emote. Cualquier cosa que se conecte al puerto 22222 en el extremo más alejado del túnel alcanzará realmente el "puerto localhost 22", donde "localhost" es desde la perspectiva del punto de salida del túnel (es decir, su cliente ssh).

Las otras opciones son:

  • -f le dice a ssh que se ejecute en segundo plano una vez que se autentica, para que no tenga que sentarse a ejecutar algo en el servidor remoto para que el túnel permanezca vivo.
  • -Ndice que desea una conexión SSH, pero en realidad no desea ejecutar ningún comando remoto. Si todo lo que está creando es un túnel, entonces incluir esta opción ahorra recursos.
  • -T deshabilita la asignación de pseudo-tty, lo cual es apropiado porque no está intentando crear un shell interactivo.

Habrá un desafío de contraseña a menos que haya configurado claves DSA o RSA para un inicio de sesión sin contraseña.

Tenga en cuenta que se recomienda ENCARECIDAMENTE que utilice una cuenta desechable (no su propio inicio de sesión) que configuró solo para este túnel / cliente / servidor.

Ahora, desde su caparazón en su publichost , establezca una conexión con el host con cortafuegos a través del túnel:

ssh -p 22222 username@localhost

Obtendrá un desafío clave de host, ya que probablemente nunca haya golpeado este host antes. Luego obtendrá un desafío de contraseña para la usernamecuenta (a menos que haya configurado claves para iniciar sesión sin contraseña).

Si va a acceder a este host de forma regular, también puede simplificar el acceso agregando algunas líneas a su ~/.ssh/configarchivo:

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Ajustar remotehostnamey remoteusernameadaptar. El remoteusernamecampo debe coincidir con su nombre de usuario en el servidor remoto, pero remotehostnamepuede ser cualquier nombre de host que le convenga, no tiene que coincidir con nada que se pueda resolver.

(Para exponer el punto final inverso en una IP no localhost , consulte esta publicación )

ghoti
fuente
2
¿Qué pasa con ssh -D. Por favor explique usando el mismo método.
BigSack
66
Los proxies SOCKS no son lo mismo que los túneles. Si tiene alguna pregunta sobre cómo usarlos, pregúntela .
ghoti
12
Me está costando mucho seguir esta explicación debido a la falta de uso de los términos: servidor, cliente, máquina local, máquina remota, host, yourpublichost, localhost, nombrehost remoto. Con todos estos términos sueltos e indefinidos, se podría suponer que alguien necesitaría hasta 8 computadoras para configurar esto. Lo digo porque en todos los demás aspectos parece una muy buena explicación. Por favor, reduzca y defina los términos.
Rucent88
44
@ Rucent88, no estoy seguro de qué reducción sería posible. Un cliente establece una conexión a un servidor. Esa es una terminología común en todo el mundo de las redes. Las máquinas locales y remotas parecen bastante evidentes. Si está confundido acerca de SSH o la terminología general de Unix después de leer la documentación, estoy seguro de que no tendrá problemas para encontrar personas aquí muy dispuestas a responder cualquier pregunta que pueda tener.
ghoti
99
@ghoti Es realmente confuso, porque las máquinas locales y remotas son relativas. Cuando me siento en el lugar de trabajo, la computadora de mi casa es el control remoto, cuando me siento en casa, la computadora del lugar de trabajo es remota. El servidor y el cliente también son confusos cuando se habla de túneles. Por ejemplo, si me conecto a casa desde el trabajo con ssh -R. Me conecto a mi trabajo desde la computadora de la casa conectando localhost. Entonces, desde la perspectiva de los sockets, el servidor es la computadora de la casa. Pero lógicamente me conecté a mi computadora de trabajo. Eso es confuso
Calmarius
357

He dibujado algunos bocetos

La máquina, donde se escribe el comando ssh tunnel se llama »su host« .

túnel ssh a partir de local


túnel ssh a partir de remoto

Introducción

  1. local: -L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHostsignifica: conectarse con ssh a connectToHost, y reenviar todos los intentos de conexión al puerto local en la máquina llamada , a la que se puede acceder desde la máquina.sourcePortonPortforwardToHostconnectToHost

  2. remoto: -R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHostsignifica: conectarse con ssh a connectToHost, y reenviar todos los intentos de conexión al puerto remoto en la máquina llamada , a la que se puede acceder desde su máquina local.sourcePortonPortforwardToHost

Opciones adicionales

  • -f le dice a ssh que se ejecute en segundo plano una vez que se autentica, para que no tenga que sentarse a ejecutar algo en el servidor remoto para que el túnel permanezca vivo.
  • -Ndice que desea una conexión SSH, pero en realidad no desea ejecutar ningún comando remoto. Si todo lo que está creando es un túnel, entonces incluir esta opción ahorra recursos.
  • -T deshabilita la asignación de pseudo-tty, lo cual es apropiado porque no está intentando crear un shell interactivo.

Su ejemplo

La tercera imagen representa este túnel. Pero la computadora azul llamada »su host« representa la computadora donde alguien inicia el túnel ssh, en este caso la máquina cortafuegos.

Entonces, pídale a alguien que inicie una conexión de túnel ssh a su máquina. El comando debería verse básicamente

ssh -R 12345:localhost:22 YOURIP

Ahora se abre el túnel. Ahora puede conectarse mediante ssh a la máquina cortafuegos a través del túnel con el comando

ssh -p 12345 localhost

que se conectará a su propia localhost(su máquina) en el puerto 12345, pero el puerto 12345se reenvía a través del túnel al puerto 22 del host local de la computadora con firewall (es decir, la computadora con firewall).

erik
fuente
99
¡Gran respuesta! Lo usaré en una presentación.
Isaiah Turner
44
Gracias. De nada. Si quieres las imágenes vectoriales (svg o pdf) escríbeme un mensaje.
erik
1
@erik, ¿cómo dibujaste estas imágenes?
Pacerier
31
¡Oh hombre, desearía que las páginas del manual pudieran tener explicaciones como esta! ¡Gracias!
Lucas Pottersky
30
Sabes que ? Ni siquiera tuve que leer la explicación del texto. Buen trabajo !
deppfx
21

El túnel ssh funciona utilizando la conexión ssh ya establecida para enviar tráfico adicional.

Cuando se conecta a un servidor remoto, generalmente solo tiene 1 canal para la interacción normal del usuario (o 3 canales si considera que STDIN / STDOUT / STDERR están separados). En cualquier momento, el proceso ssh local o remoto puede abrir canales adicionales en la conexión existente. Estos canales envían / ​​reciben el tráfico del túnel. Al enviar o recibir tráfico, el proceso ssh simplemente dice "este tráfico es para el canal foobar".

Básicamente funciona así:

  1. Le dice a ssh que comience a escuchar en el puerto XXXX y que cualquier tráfico recibido debe ser tunelizado, y luego configurado en YYYY en el puerto ZZZZ.
  2. El ssh local comienza a escuchar en el puerto XXXX (generalmente activado 127.0.0.1, pero se puede cambiar).
  3. Algunas aplicaciones abren una conexión al puerto XXXX en la máquina local.
  4. El ssh local abre un canal al ssh remoto y dice "cualquier tráfico en este canal va a AAAA: ZZZZ
  5. El ssh remoto se conecta a YYYY: ZZZZ y devuelve el mensaje "OK, el canal está abierto"
  6. Ahora, cualquier tráfico enviado a lo largo de la conexión al puerto XXXX en la máquina local es enviado por ssh a YYYY: ZZZZ.

Este proceso es exactamente el mismo para la tunelización directa e inversa (solo intercambie las palabras 'local' y 'remoto' en el procedimiento anterior). Cualquier lado puede comenzar el túnel. Ni siquiera tiene que ser cuando comienzas ssh por primera vez. Puede abrir túneles mientras ssh ya se está ejecutando (ver ESCAPE CHARACTERS, específicamente ~C).

Para el papel de -R, -f, -L, y -N, lo que realmente debe consultar la página del manual, que le da la mejor explicación posible. Pero lo mencionaré -Ry -L.
-Rle dice al ssh remoto que escuche las conexiones, y que el ssh local debe conectarse al destino real. -Lle dice al ssh local que escuche las conexiones, y que el ssh remoto debe conectarse al destino real.

Tenga en cuenta que esta es una descripción muy cruda, pero debería darle suficiente información para saber qué está pasando

Patricio
fuente
16

Esto se explica en el manual de SSH, especialmente las diferencias entre -L(local) y -R(remoto).


-L

-L [bind_address:]port:host:hostport

Especifica que el puerto dado en el host local (cliente) debe reenviarse al host y puerto dados en el lado remoto .

Esto funciona mediante la asignación de un socket para escuchar el puerto en el lado local, opcionalmente vinculado a la dirección de enlace especificada.

Cada vez que se realiza una conexión a este puerto, la conexión se reenvía a través del canal seguro y se realiza una conexión al hostpuerto hostportdesde la máquina remota .

El siguiente ejemplo hace un túnel de una sesión IRC desde la máquina cliente 127.0.0.1( localhost) usando el puerto 1234 al servidor remoto server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Nota: La -fopción fondos ssh y el comando remoto sleep 10se especifica para permitir una cantidad de tiempo para iniciar el servicio que se va a hacer un túnel.

Ejemplo:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Después de conectarse, simplemente cuelgue allí (no obtendrá un indicador de shell)

    No ejecute un comando remoto.

  • -L 22000La conexión se originará en el puerto 22000 de su, personal L máquina vecinal

  • localhost:11000- remote.server.comse asegurará de que el otro extremo del túnel sea localhost, puerto11000

ssh -N -L 22000: 192.168.1.2: 11000 remote.server.com

Fuente: Una guía ilustrada, tutorial, procedimientos, sobre túneles ssh .


-R

-R [bind_address:]port:host:hostport

Especifica que el puerto dado en el host remoto (servidor) debe reenviarse al host y puerto dados en el lado local .

Esto funciona mediante la asignación de un zócalo para escuchar porten el lado remoto, y cada vez que se realiza una conexión a este puerto, la conexión se reenvía a través del canal seguro y se realiza una conexión al hostpuerto hostportdesde la máquina local .

Ejemplo:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Después de conectarse, simplemente cuelgue allí (no obtendrá un indicador de shell)

    No ejecute un comando remoto.

  • -R22000 La conexión se originará en el puerto 22000 de la computadora R emote (en este caso, remote.server.com)

  • localhost:11000su computadora personal local se asegurará de que el otro extremo del túnel sea localhostpuerto11000

ssh -N -R 22000: localhost: 11000 remote.server.com

Fuente: Una guía ilustrada, tutorial, procedimientos, sobre túneles ssh .

kenorb
fuente
66
¡El oído y la boca dejan en claro quién habla y quién escucha!
Thufir
1
¡Me encantan tus ilustraciones!
mcantsin