Túnel de puerto inverso

59

Necesito mostrarle a alguien un sitio web que se ejecute en mi máquina local mañana. Normalmente lo lograría mediante el reenvío de puertos en mi enrutador local, pero gracias al hardware defectuoso y su reemplazo es horrible, mi enrutador actual no me permite hacer el reenvío de puertos.

Entonces, atascado con este retraso y sin querer empujar todo en un servidor adecuado, tuve una idea loca: ¿puedo enviar mi puerto a un servidor externo a través de SSH?

He hecho túneles de puerto antes, pero generalmente lo hago de la manera correcta:

  • Me conecto a una caja remota y solicito que el puerto 12345 aparezca en mi máquina local en el puerto 12345.
  • Comienzo algo en P12345 en la máquina remota
  • Puedo acceder a través de localhost: 12345

Lo que quiero hacer

  • Conéctese a una PC remota y solicite que su P12345 local busque cosas de mi P12345 local (a través del túnel)
  • Comienzo algo en mi computadora local en P12345
  • Otras personas pueden acceder al control remoto: 12345 y ver mi host local: 12345
Oli
fuente

Respuestas:

97

El comando para reenviar el puerto 80 desde su máquina local ( localhost) al host remoto en el puerto 8000 es:

ssh -R 8000:localhost:80 oli@remote-machine

Esto requiere un ajuste adicional en el servidor SSH, agregue las líneas a /etc/ssh/sshd_config:

Match User oli
   GatewayPorts yes

A continuación, vuelva a cargar la configuración ejecutando el servidor sudo reload ssh.

La configuración GatewayPorts yeshace que SSH enlace el puerto 8000 en la dirección comodín, por lo que estará disponible para la dirección pública de remote-machine( remote-machine:8000).

Si necesita tener la opción de no vincular todo en la dirección comodín, cambie GatewayPorts yesa GatewayPorts clientspecified. Debido a que se sshvincula a la dirección de bucle de retorno de forma predeterminada, debe especificar un vacío bind_addresspara vincular la dirección comodín:

ssh -R :8000:localhost:80 oli@remote-machine

El :antes 8000es obligatorio si GatewayPortsestá configurado en clientspecifiedy desea permitir el acceso público a remote-machine:8000.

Extractos manuales relevantes:

ssh (1)

-R [bind_address:] port: host: hostport
Especifica que el puerto dado en el host remoto (servidor) se debe reenviar al host y puerto dados en el lado local. Esto funciona mediante la asignación de un socket para escuchar el puerto en 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 puerto host del puerto host desde la máquina local. Por defecto, el socket de escucha en el servidor estará vinculado únicamente a la interfaz de bucle invertido. Esto puede anularse especificando un bind_address. Un bind_address vacío, o la dirección '*', indica que el socket remoto debe escuchar en todas las interfaces. La especificación de una dirección de enlace remota solo tendrá éxito si la opción GatewayPorts del servidor está habilitada (consulte sshd_config (5)).

sshd_config (5)

GatewayPorts
Especifica si los hosts remotos pueden conectarse a los puertos reenviados para el cliente. GatewayPorts se puede usar para especificar que sshd debe permitir que los reenvíos de puertos remotos se unan a direcciones que no son de bucle invertido, permitiendo así que otros hosts se conecten. El argumento puede ser 'no' para forzar que los reenvíos de puertos remotos estén disponibles solo para el host local, 'sí' para forzar los reenvíos de puertos remotos para que se unan a la dirección comodín, o 'clientes especificados' para permitir que el cliente seleccione la dirección a la que el reenvío está obligado. El valor predeterminado es 'no'.

Ver también:

Lekensteyn
fuente
77
GatewayPortsfue la bala mágica aquí. Me gusta que hayas encontrado una versión que me permita limitar esta técnica bastante poderosa a ciertos usuarios.
Oli
1
Lo que me resultó confuso fue que los GatewayPorts se deben configurar en la máquina que ejecuta el comando ssh real para iniciar el túnel inverso (local). En mi opinión, de alguna manera era más lógico que el otro extremo (remoto) se ocupara de dónde aceptar las conexiones, ya que es allí desde donde se conecta y se le redirige. Me llevó años superar eso.
Ars Magika
2
@ArsMagika No estoy seguro si te entiendo. GatewayPorts debe establecerse en el servidor SSH, no en su máquina local que ejecuta el sshcomando. Configura si otros clientes pueden comunicarse con los puertos reenviados en el servidor.
Lekensteyn
Desventaja de esta solución: pierde la capacidad de determinar la dirección IP del cliente en el registro de acceso del servidor web. ¿Alguna forma de resolver esa molestia también?
Twonky
@Twonky Si no necesita saber la dirección IP exacta del cliente (solo que era remota y no "localhost"), y su servidor local está escuchando la dirección comodín (es decir, acepta conexiones desde cualquier dirección), entonces puede intentar reenviar a -R :8000:127.0.1.1:80(o cualquier otra 127.x.x.xdirección). De lo contrario, no, no podrá aprender la dirección IP remota.
Lekensteyn el
14

Si el servidor lo ha hecho GatewayPorts no, puede lograr el mismo resultado ejecutando ssh -g -L 8001:localhost:8000 oli@remote-machineen el servidor una vez que haya ejecutado el ssh -Rcomando en el cliente. Esto hará que el puerto de bucle invertido 8000 en el servidor sea accesible en todas las interfaces en el puerto 8001.

FaST4
fuente