¿Cómo reenviar un puerto de una máquina a otra?

19

Considere la siguiente situación:

En mi casa, tengo un enrutador (que está conectado a Internet), un servidor (S) y mi máquina principal (M). Se puede acceder a S desde Internet (tiene IP estática), y está activo las 24 horas, los 7 días de la semana, mientras que M no.

A veces, quiero que alguna aplicación (que escucha en algún puerto en M, por ejemplo 8888) sea accesible desde Internet externo.

Para eso, quería configurar algún puerto en S (2222) para reenviarlo al puerto 8888 de M, para que cualquiera que acceda a S: 2222 sienta que está accediendo a M: 8888.

Traté de usar el reenvío de puertos ssh, mi mejor intento fue el siguiente:

ssh -L 2222:M:8888 -N M

Pero eso solo me permite acceder al puerto 2222 desde el servidor mismo, no desde otras máquinas.

¿Hay alguna forma de hacerlo correctamente? Preferiblemente, me gustaría que fuera un comando simple, que podría iniciar y cerrar con ^ C cuando ya no necesite ese reenvío.

Rogach
fuente
Prueba localhost.run, que es un sitio web al que puedes acceder en localhost.run. Creo que hay una manera de sacar tu producto a la
venta

Respuestas:

16

Sí, esto se llama GatewayPortsen SSH. Un extracto de ssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

Y puede usarlo en localhostlugar de Men el reenvío, ya que reenvía a la misma máquina a la que está enviando SSH, si entiendo su pregunta correctamente.

Entonces, el comando se convertirá en esto:

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

y se verá así en netstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

Ahora, cualquiera que acceda a esta máquina en el puerto 2222 TCP en realidad hablará con localhost: 8888 como se ve en la máquina M. Tenga en cuenta que esto no es lo mismo que el reenvío simple al puerto 8888 de M.

gertvdijk
fuente
1
¡Gracias! ¡Eso funciona! Pero hay algo extraño: por alguna razón, la salida contiene la línea "bind: Dirección ya en uso". ¿Qué podría significar eso?
Rogach
1
Ya tienes algún proceso ejecutándose en ese puerto. Use el mismo netstatcomando para averiguar exactamente qué. Probablemente otro SSH similar todavía se ejecuta en segundo plano y lo mata usando el PID netstat te dice.
gertvdijk
Lo divertido es que ya lo hice: no hay procesos en esos puertos, tanto en S como en M. Si hubiera algunos, entonces toda la construcción probablemente no hubiera funcionado.
Rogach
10

Hay otra manera Puede configurar el reenvío de puertos de S: 2222 a W: 8888 con iptables. Comando único:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

donde 1.2.3.4 es la dirección IP de M. Se llama NAT (traducción de direcciones de red).

Gevial
fuente
1
Como solo está haciendo NAT de destino aquí (en oposición a NAT de origen), esto solo funcionará de manera confiable en situaciones específicas y podría requerir modificar las tablas de enrutamiento. Sin embargo, para el reenvío a máquinas virtuales (M) que se ejecutan en el host (S), esto podría funcionar bien.
gertvdijk
Este comando debe emitirse en la puerta de enlace. Supongo que S y M están en la misma LAN. Source NAT se realizaría automáticamente mediante el rastreador de conexiones en los núcleos modernos de Linux. Tengo esa configuración en la red de mi oficina y funciona perfectamente. Sin embargo, es posible hacer que el comando sea más específico (por ejemplo, decirle a iptables -i eth0 donde eth0 es la interfaz externa).
Gevial
Si S y M están en la misma LAN, no necesita reenvío de puertos allí, ya que ningún tráfico entre ellos pasa por la puerta de enlace.
gertvdijk
1
Sí, pero supongo que la conexión a M: 8888 se realiza desde Internet. Alguien forma Internet -> S: 2222 -> M y S enrutador LAN con iptables -> M: 8888
Gevial