Reenviar tráfico SSH a través de una máquina central

110

El túnel SSH es muy confuso para mí. Me pregunto si puedo hacer esto en Linux.

Tengo 3 maquinas ..

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

Entonces puedo SSH desde A -> B y desde B -> C, pero no desde A -> C.

¿Hay alguna manera de configurar un túnel SSH de A a B, de modo que cuando ejecuto otros comandos SSH, simplemente funcionan desde mi máquina local A? Básicamente estoy tratando de clonar un repositorio de git del trabajo al hogar (y no puedo instalar git en la máquina B).

Además, una vez configurado ... ¿Cómo lo desarmaría también?


fuente
Creo que hay una pregunta duplicada en alguna parte, pero mi búsqueda es débil hoy.
quack quijote
2
Posible duplicado de un túnel SSH a través de múltiples saltos
Geza Kerecsenyi
Si está ejecutando Linux en la máquina A, use una herramienta llamada sshuttle, que le permite reenviar selectivamente todo el tráfico para C a través del túnel A-> B (suponiendo que C sea visible desde B).
Joat

Respuestas:

128

Coloque esto en su .ssh/configarchivo en hostA (vea man 5 ssh_config para más detalles):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

Ahora el siguiente comando se tunelizará automáticamente a través de hostB

hostA:~$ ssh hostC

Es posible que desee agregar opciones como -oCiphers=arcfoury -oClearAllForwardings=yesacelerar las cosas, ya que envolverlo en el sshinterior sshes computacionalmente más costoso y el esfuerzo adicional y el contenedor no necesitan ser tan seguros cuando está canalizando el tráfico ya cifrado.


Si está utilizando OpenSSH anterior a 5.3, la -Wopción no está disponible. En este caso, puede implementar lo anterior usando netcat ( nc):

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB
efímero
fuente
1
¡Esto es brillante! Gracias. Esto resuelve un problema que me ha estado comiendo durante los últimos 2 días: hostC se encuentra detrás de un firewall y tiene datos a los que quiero acceder desde hostA, una computadora portátil que puede estar en cualquier parte del mundo. hostB también está detrás del mismo firewall con hostC, pero tiene un puerto SSH abierto al mundo. Por lo tanto, puedo ssh desde hostC -> hostB. Configuré un túnel SSH inverso entre hostC y hostB, para que también pueda ssh desde hostB -> hostC (reenviado a través de localhost). ¡Con tu truco puedo ir de hostA -> hostC! ¡Funciona perfectamente con SCP y Fugu en OSX! ¡Gracias!
AndyL
La -Wopción debe usarse en lugar de la ncopción.
vy32
¿Qué SSH debería admitir -W, solo el del hostA (el origen) o también el del hostB (la máquina central)?
gioele
Para obtener información, si tiene varios hosts a los que necesita comunicarse a través del mismo hostB, es posible declarar varias Host hostClíneas por encima, ProxyCommandlo que hace que sea muy fácil acceder a varios hosts a través del servidor central.
fduff
7

Editar: este es el enfoque equivocado. Ver la respuesta de ephemient en su lugar. Esta respuesta funcionará, pero es potencialmente menos segura y definitivamente menos sorprendente.

Parece que quiere una solución como la siguiente:

ssh -L localhost:22:machinec:22 machineb

Esto te pondrá una cáscara machineb. Deja esto solo; minimizar la ventana de terminal.

Ahora, cada vez que realice una conexión ssh localhost, estará conectado a machinectravés de machineb. Cuando haya terminado con el túnel, simplemente cierre la terminal en la que ejecutó el comando anterior.

Tenga en cuenta que necesitará privilegios de superusuario para ejecutar el comando.

Wesley
fuente
+1 Gracias Wesley. Esta es la verdadera respuesta de túnel ssh. Aquí hay un artículo al respecto: securityfocus.com/infocus/1816
Larry K
3
En general, esto es bastante malo ... pero he tenido que hacer esto con versiones antiguas de OpenSSH u otros clientes ssh. Puede elegir un puerto alto como 8022: de esta manera no interfiere con ningún servicio ssh en localhost y no requiere ejecutarse como root. Simplemente agregue -p 8022a sus comandos ssh. Y es muy fácil con git: usa el URI ssh://localhost:8022/path/to/repo.git.
Ephemient
3

Suena como si quisieras un alias de shell en A que hace que ssh ocurra en C

  1. Supongo que en A, puede escribir ssh me @ b "ssh me @ c hostname" y volver a "C"
  2. Haga un alias sshc que expanda sshc foo en ssh me @ b "ssh me @ c foo"
  3. Para conocer la sintaxis exacta de la creación del alias, consulte superuser.com
Larry K
fuente
1
Es posible que tenga que agregar -ta las opciones externas de ssh si desea un shell interactivo, ya que sshsupone -Tsi se le da un comando.
Ephemient
1

Para el shell interactivo, puede usar este comando simple:

ssh -J <user>@<hostB> <user>@<hostC>

Las opciones -J son para saltar .

ssasa
fuente
0

Si su empleador proporciona una VPN, le recomiendo que la use.

De esa manera, no tendrá que configurar ninguna aplicación especialmente (incluso ssh), y puede ver cualquier máquina detrás del firewall. Además, todo su tráfico será encriptado por el software VPN, que agregará seguridad a cualquier tráfico no encriptado de forma inadvertida o deliberada.

Andrew Wagner
fuente
66
A veces es la VPN la razón por la que necesitamos estos trucos ...
Louis
0

YASS, otra solución simple

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • El primer comando abre una conexión ssh con HostB y le dice a HostB que reenvíe las conexiones desde localhost: 2222 a HostC: 22 .
  • el -fparámetro le dice a SSH que vaya al fondo una vez establecida la conexión
  • Segundo comando abre simplemente una conexión de cliente a localhost: 2222
  • La opción HostKeyAlias no es necesaria, pero podría ayudar a evitar la conexión a un host incorrecto
  • Nota: sleep 10se necesitan comandos para mantener la conexión hasta que el segundo comando ssh use el puerto reenviado. Luego, el primer ssh se cerrará cuando el segundo ssh deje el puerto reenviado.

ahora puede ejecutar sesiones ssh posteriores:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

Variante:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

Las sesiones ssh posteriores pueden abrirse ejecutando:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

La principal ventaja de usar -M y -S param es que solo una conexión está abierta de HostA a HostC, la sesión posterior no se autenticará nuevamente y se ejecutará mucho más rápido.

F. Hauri
fuente
0

Caso especial, plataformas mixtas de nix:

  hostA (linux) -> HostB (solaris) -> HostC (linux)

Si necesita una aplicación X en hostC, y el salto intermedio está en la caja de Solaris ... en este caso encontré el netcat (nc) necesario en el ProxyCommand así:

hostA: ~ $ vi .ssh / config:

Host hostC
    ProxyCommand ssh hostB nc% h% p # donde nc es netcat

Entonces el túnel automático funciona:

hostA: ~ $ ssh hostC

nsysdcw
fuente