Acceso SSH al host de la oficina detrás del enrutador NAT

33

Me gustaría acceder al puerto ssh del host de Linux de mi oficina desde casa. Lamentablemente, el host se encuentra detrás de un enrutador NAT. Por lo tanto, la dirección IP no está disponible públicamente. Sin embargo, hay acceso a otro host de Internet (Servidor) que desafortunadamente es solo acceso no root. Después de un tiempo de búsqueda, no encuentro una solución adecuada.

Siguiente configuración:

  • PC de Office (Linux, acceso raíz) detrás de NAT (IP no pública) pero acceso completo a Internet.
  • Servidor PC (Linux, sin acceso de root) IP estática y pública y acceso completo a Internet.
  • PC doméstica (Linux, acceso raíz) detrás de NAT (IP no pública) pero acceso completo a Internet.

Conexiones posibles: PC de oficina -> Servidor <- PC de casa

No es posible: Office PC <-X- Server -X-> Home PC

Ni la PC doméstica ni el servidor pueden iniciar el acceso a la PC de Office. Pero tanto la PC de Office como la PC doméstica pueden iniciar conexiones al Servidor.

El túnel SSH inverso no es posible: probé un método llamado túnel ssh inverso. Desafortunadamente, esto requiere que GatewayPorts en el servidor esté configurado en "yes" en / etc / ssh / sshd_config, donde no tengo acceso de root.

En principio debería ser posible:

0) En el servidor, inicio un programa de espacio de usuario que escucha en 2 puertos (1 entrante, 1 saliente)

1) En la PC de mi oficina ejecuto otro programa que mantiene una conexión TCP abierta al puerto de salida del servidor.

2) Desde casa me conecto al puerto de entrada del servidor.

Debería haber una solución estándar para esto.

¿Cuál es la solución más rápida y limpia para resolver esto?

Franco

ritter
fuente
1
¿Puede la PC de trabajo conectarse a la casa configurando un túnel ssh? en.gentoo-wiki.com/wiki/Autossh
Puede usar FileZilla con sftp y reenvío de puertos. Echa un vistazo a: superuser.com/a/1286681/141314
Noam Manos

Respuestas:

31
youatwork@officepc$ autossh -R 12345:localhost:22 notroot@serverpc

Más tarde:

you@homepc$ autossh -L 23456:localhost:12345 notroot@serverpc

you@homepc$ ssh youatwork@localhost -p 23456

Lo que podría hacer es esto: en el paso 1, reenvíe un puerto remoto desde la PC de la oficina al servidor ( 12345se usa como ejemplo, cualquier puerto> 1024 debería hacerlo). Ahora, conectarse a 12345 en el servidor debería conectarlo al puerto 22 en officepc.

En el paso 2, reenvíe el puerto 23456 desde su máquina doméstica a 12345 en el servidor (desde donde se reenvía a officepc: 22, como se configuró en el paso 1)

En el paso 3, se conecta al puerto local 23456 con el inicio de sesión de la PC de su oficina . Esto se reenvía en el paso 2 al puerto 12345 en su servidor y en el paso 1 a la PC de su oficina.

Tenga en cuenta que estoy usando autossh para los reenvíos, ya que es un contenedor ssh que vuelve a conectar automáticamente el túnel si se desconecta; sin embargo, ssh normal también funcionaría, siempre que la conexión no se caiga.

Existe una posible vulnerabilidad: cualquiera que pueda conectarse a localhost: 12345 en serverpc ahora puede conectarse a officepc: 22 e intentar hackearlo. (Tenga en cuenta que si está ejecutando un servidor SSH, de todos modos debe asegurarlo por encima de las protecciones básicas que están activadas de manera predeterminada; recomiendo al menos deshabilitar el inicio de sesión de root y deshabilitar la autenticación de contraseña; consulte, por ejemplo, esto )

Editar : He verificado esto con la misma configuración, y funciona. GatewayPorts nosolo afecta a los puertos abiertos al mundo en general, no a los túneles locales. Esto es lo que son los puertos reenviados:

homepc:
  outgoing ssh to serverpc:22
  listening localhost:23456 forwarded through ssh tunnel
serverpc:
  listening ssh at *:22
  incoming localhost ssh tunnel (from homepc) forwarded to localhost:12345
  listening localhost ssh tunnel (from officepc) forwarded from localhost:12345
officepc:
  outgoing ssh to serverpc:22
  incoming localhost through ssh tunnel (from serverpc) forwarded to localhost:22

Entonces, en lo que respecta a la pila de red, es todo el tráfico local en las respectivas interfaces de bucle invertido (más conexiones ssh a serverpc); por lo tanto, GatewayPortsno está marcado en absoluto.

Sin embargo, existe la directiva AllowTcpForwarding: si es así no, esta configuración fallará ya que no se permite ningún reenvío, ni siquiera a través de la interfaz de bucle invertido.

Advertencias :

  • si usa autossh y ssh reciente, es posible que desee usar ssh ServerAliveIntervaly ServerAliveCountMaxpara mantener el túnel en funcionamiento. Autossh tiene un control incorporado, pero aparentemente tiene algunos problemas en Fedora. -M0deshabilita eso y -oServerAliveInterval=20 -oServerAliveCountMax=3comprueba si la conexión está activa : prueba cada 20 segundos, si falla 3 veces seguidas, detiene ssh (y autossh crea una nueva):

    autossh -M0 -R 12345:localhost:22 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
    
    autossh -M0 -L 23456:localhost:12345 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
    
  • puede ser útil reiniciar el túnel ssh si falla el reenvío, utilizando -oExitOnForwardFailure=yes: si el puerto ya está vinculado, puede obtener una conexión SSH que funcione, pero no un túnel reenviado.

  • ~/.ssh/configes aconsejable usar para las opciones (y puertos), de lo contrario las líneas de comando se vuelven demasiado detalladas. Por ejemplo:

    Host fwdserverpc
        Hostname serverpc
        User notroot
        ServerAliveInterval 20
        ServerAliveCountMax 3
        ExitOnForwardFailure yes
        LocalForward 23456 localhost:12345
    

Entonces puede usar solo el alias del servidor:

    autossh -M0 fwdserverpc
Piskvor
fuente
Creo que este método que supones se llama "túnel ssh inverso". Desafortunadamente, esto requiere que GatewayPorts en el servidor esté configurado en "yes" en / etc / ssh / sshd_config. Este servidor no tiene puertos de puerta de enlace habilitados y no tengo acceso raíz allí.
3
@ Frank: En realidad, no lo creo: GatewayPorts norestringe los puertos abiertos para que solo sean accesibles en la interfaz de bucle invertido; tenga en cuenta que en el paso 2 está reenviando en la interfaz de bucle invertido (de hecho, ambos reenvíos son "solo localhost"), por lo que esto podría funcionar ( AllowTcpForwarding noen la configuración sshd se rompería esto).
Piskvor
3
@Frank: Sí, confirmado. Esto funciona incluso con GatewayPorts no; editó la respuesta. Tenga en cuenta que hay otras directivas (como PermitOpeny AllowTcpForwarding) que pueden romper esta configuración: manpagez.com/man/5/sshd_config
Piskvor
1
Excelente respuesta! ¡Funciona, salvaste mi fin de semana! ¡¡Muchas gracias!!
1
mi versión de autossh (Fedora Core) no podría ejecutarse desde la terminal sin -M. También me he vinculado a otra persona que experimentó eso. Tiene razón en que en el manual está marcado como argumento opcional. Bien si funciona para muchas personas, lástima que no para todos.
Yaroslav Nikitenko
4

Si puede enviar ssh al servidor interno desde su casa y desde el servidor interno a la máquina Linux de su oficina, entonces desde su casa puede usar la ssh ProxyCommandpara rebotar silenciosamente a través del servidor a la máquina interna a través de nc(netcat)

# ~/.ssh/config on your home machine:
Host internalpc 
   ForwardAgent yes 
   ProxyCommand ssh [email protected] exec nc internal.pc.example.com %p

Luego, usted ssh user@internalpcy usted se reenvían silenciosamente a través de la máquina del servidor, no se requiere la apertura de puertos o túneles en ninguno de los extremos.

Miguel
fuente
1
Gracias por tu respuesta. Desafortunadamente, ni la PC doméstica ni el servidor pueden iniciar el acceso a la PC de Office. Pero tanto la PC de Office como la PC doméstica pueden iniciar conexiones al Servidor.
4

Instale Robo-TiTO en la computadora a la que desea acceder SSH de forma remota.

  • Esto le permitirá acceder a SSH utilizando desde Google Talk Client Apps en cualquier lugar.
  • No hay necesidad de una dirección IP pública o configuración especial.
  • Es gratis y de código abierto, ya no paga ningún servicio de aplicación.
  • No es necesario abrir el puerto SSH (mantenga su computadora segura).
  • No es necesario abrir ningún túnel (por ejemplo, VPN o algo así)

Las siguientes instrucciones de instalación son obsoletas, ya que el sitio se ha movido. La nueva URL es https://github.com/formigarafa/robotito

Hice un script (probado en mi sistema operativo Raspbian en Raspberry Pi) para que pueda instalar fácilmente Robo-TiTO en Raspberry Pi, Debian o Ubuntu Box (distribución de paquetes Debian). Estos son los pasos para que su caja de Linux sea remota:

  1. Abra el comando Shell o puede llamarlo Terminal, vaya a su carpeta de inicio, descargue el script de instalación por comando:

    $ wget https://opengateway.googlecode.com/files/robotito
    
  2. después de eso, ejecute el script ingresando el comando:

    $ sudo ./robotito
    
  3. y luego puede editar el archivo credentials.rbdesde la carpeta de configuración de Robo-TiTO usando su cuenta GTalk y guardarlo presionando Ctrl+ Xy Y. El valor predeterminado es usar nano editor.

  4. ejecutar el Robo-TiTO desde la carpeta Robo-TiTO por comando

    $ cd robotito
    $ ./jabbershd start
    
  5. Ahora que está hecho, puede usar SSH desde cualquier cliente de Google Talk. No olvide agregar la cuenta Robo-TiTO GTalk a su cuenta de Google Talk y probarla con el chat antes de usar la cuenta.

Rolly Maulana Awangga
fuente
55
Tengo un problema grave con "No es necesario abrir el puerto SSH (mantenga su computadora guardada )": el bot de shell sobre jabber que propone está asegurado con, entre comillas CLIENT_PASSPHRASE = "logmein", en texto sin formato . Eso es literalmente cero seguridad: estás haciendo un agujero del tamaño de un camión para que cualquiera pueda entrar. Contraste con la autenticación de clave pública SSH: me autentico a través de un canal seguro , utilizando credenciales que nunca cruzan el cable. ¿Quién está manteniendo su computadora segura ahora?
Piskvor
@Piskvor, robotito solo ejecutará comandos desde contactos incluidos en la lista blanca. github.com/formigarafa/robotito/blob/master/config/…
formigarafa
Nunca me encuentro con ningún problema debido a la autenticación basada en la lista blanca. Si no me equivoco, la transferencia del mensaje se cifra cuando se usa con GTalk. De una forma u otra, lo cambié recientemente y ahora usa una contraseña de un solo uso de una herramienta como Google Authenticator o similar para permitir el acceso.
formigarafa
1
@formigarafa: (1) Si está o ha estado involucrado en el desarrollo de este producto, debe decirlo explícitamente. Usar el mismo nombre no es suficiente; la mayoría de la gente no se dará cuenta de eso. (Puede mencionarlo en su perfil ). (2) Cuando edita una publicación, debe corregirla lo más que pueda. Por ejemplo, intente detectar errores tipográficos como "I'ts". Y, si un enlace se ha caído, no lo etiquete simplemente como un enlace muerto; poner la nueva URL en la publicación . Las personas no deberían tener que buscar en los comentarios para encontrar la información correcta.
G-Man dice 'reinstalar a Monica' el
@ G-Man, La respuesta y edición originales no fueron mías. Y nunca tuve la intención de hacerlo parecer mío. Noté un enlace muerto en la respuesta, tampoco creé el enlace. Estaba realmente interesado en ver su contenido y traté de seguirlo. Lamentablemente no pude encontrar el recurso. Marqué como un enlace muerto con la esperanza de que quien escribió la respuesta sea notificado por el cambio e intente solucionarlo.
formigarafa
3

La solución de Piskvor funciona y es agradable. Sin embargo, mantiene abiertos los terminales con colgantes de inicio de sesión. No muy bien

Siempre he usado este pequeño script que escribí para conectarme a un servidor y mantenerlo conectado ejecutándolo en cron:

#!/bin/bash
TARGET_HOST=${1:-myserver.example.com}
TARGET_PORT=${2:-7777}
TUNNEL_PORT=${3:-22}
T_USER="odin"

#Check that we have an active connection to the remote system
ACTIVE_PROCESS=`ps -ef | \
    grep "ssh $TARGET_HOST -l $T_USER -R $TARGET_PORT:127.0.0.1:$TUNNEL_PORT" | \
    grep -v grep | \
    wc -l`
if [ $ACTIVE_PROCESS -lt 1 ]; then
    echo "`date` : establishing connection to $TARGET_HOST on port $TARGET_PORT"
    screen -m -d ssh $TARGET_HOST -l $T_USER -R $TARGET_PORT:127.0.0.1:$TUNNEL_PORT > /dev/null
fi

Apuesto a que podríamos solucionar la solución de Piskvor usando el autossh más elegante junto con una pantalla separada o usar los argumentos ssh -NT para mantener la conexión en segundo plano.

odinho - Velmont
fuente
Gracias por los cumplidos :) Para mis casos de uso, regularmente necesito el acceso de shell, así como los reenvíos; Además, he tratado de mostrar el caso mínimo aquí (es posible simplificar lo anterior en dos comandos con salto de host SSH transparente, pero eso requeriría una configuración adicional en la homepccomputadora).
Piskvor
2

Para mí, parece que, en lugar de un túnel SSH, deberías probar una VPN: del tipo que funciona usando un servidor en el exterior para proxy, como Hamachi . Hay otros softwares gratuitos como este, pero Hamachi es mi favorito.

djangofan
fuente
1
Ahora que la 5.0.0.0/8red tiene direcciones IPv4 públicas asignadas, Hamachi está en problemas (si Hamachi se está ejecutando, no puede acceder a una parte de Internet algo aleatoria). Además, Hamachi ya no es de uso gratuito.
Piskvor