¿Cómo hago SSH para maquinar A a través de B en un comando?

103

Quiero acceder a una computadora, por ejemplo, la máquina A, que se basa en la red de mi universidad. Sin embargo, esta computadora solo es accesible a través de la red interna de la universidad, por lo que no puedo usar SSH en esta computadora directamente desde mi casa.

Esto es lo que hago ahora:

  1. Inicie sesión en una máquina universitaria diferente, digamos máquina B

    (Se puede acceder a esta máquina B a través de SSH desde la computadora de mi casa).

  2. Use SSH en B para conectarse a A.

¿Hay alguna manera de hacerlo más rápido? Usando solo un comando ssh.

nikosdi
fuente
relacionado: ssh a través de múltiples hosts
Trevor Boyd Smith

Respuestas:

97

Sí, usando ProxyCommanden su configuración SSH.

Cree un archivo de configuración SSH en su directorio de inicio (a menos que quiera hacer esto en todo el sistema) ~/.ssh/config:

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

Ahora puede llegar a la Máquina A directamente usando

ssh user@internalmachine

También tenga en cuenta que ahora tiene un único nombre de destino de host SSH para él, también puede usarlo en otras aplicaciones. P.ej:

  • SCP para copiar archivos.

    scp somefile user@internalmachine:~/
    
  • En sus aplicaciones GUI:

    utilizar sftp://user@internalmachine/como ubicación para navegar en la máquina.

    Basado en KDE (Dolphin): uso fish://user@internalmachine/

Notas

Cambie hostname.or.IP.address.internal.machiney el puerto ( 22) a la máquina que desea alcanzar como si fuera desde la unibrokermáquina.

Dependiendo de las versiones de netcat en el host unibroker, la -q0opción debe omitirse. En cuanto a la autenticación; básicamente está configurando dos conexiones SSH desde su estación de trabajo. Esto significa que tanto el host del unibroker como el host de la máquina interna se verifican / autentican uno tras otro (tanto para el par de claves / contraseña como para la verificación de la clave del host).

Explicación

Este enfoque del uso de ProxyCommandy 'netcat' es solo una forma de hacerlo. Me gusta esto, porque mi cliente SSH habla directamente con la máquina de destino para que pueda verificar la clave de host de mi cliente y puedo usar mi autenticación de clave pública sin usar otra clave en el intermediario.

Cada uno Hostdefine el inicio de una nueva sección de host. Hostnamees el nombre de host de destino o la dirección IP de ese host. Useres lo que proporcionaría como parte del usuario ssh user@hostname.

ProxyCommandse utilizará como tubería para la máquina de destino. Al usar SSH en la primera máquina y configurar directamente un 'netcat' ( nc) al objetivo desde allí, esto es básicamente un texto sin formato hacia la máquina interna desde el intermediario entre ellos. Las -qopciones son silenciar cualquier salida (solo una preferencia personal).

Asegúrese de tener netcat instalado en el agente (generalmente disponible de forma predeterminada en Ubuntu), ya sea netcat-openbsdInstalar netcat-openbsd o netcat-traditionalInstalar netcat-tradicional .

Tenga en cuenta que todavía está utilizando SSH con cifrado dos veces aquí. Si bien el canal netcat es de texto sin formato, su cliente SSH en su PC configurará otro canal cifrado con la máquina de destino final.

gertvdijk
fuente
44
Tuve que eliminar la opción -q0 ya que no era compatible con la máquina que estaba usando. Aparte de eso, todo funcionó. Este es un consejo fantástico. Muchas gracias. :)
Gerry
Me encontré con un problema, su respuesta me funciona bien desde la terminal, pero no puedo hacerlo usando la interfaz gráfica de usuario (sftp), dice: mensaje de error no manejado, se agotó el tiempo de espera al iniciar sesión.
Vikash B
@VikashB Bueno, realmente debería funcionar. Considere crear una NUEVA pregunta para manejar su situación específica.
gertvdijk
Lo que hice aquí es la pregunta: askubuntu.com/questions/688567/…
Vikash B
1
Para complementar la sabia palabra de @gertvdijk, hay un gran wikibook sobre el tema de los servidores proxy ssh y hosts de salto que pueden servir como una referencia invaluable.
Travis Clarke
51

Salta de una vez

Una alternativa obvia al enfoque de ProxyCommand que proporcioné en mi otra respuesta sería 'saltar' directamente a la máquina de destino:

ssh -t user@machineB ssh user@machineA

Tenga -ten cuenta el en el primer sshcomando. Sin ella, fallará:

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

Obligará a que se asigne un TTY real

La desventaja de esto es que ahora toda la configuración, verificación y autenticación se lleva a cabo en la Máquina B, lo que realmente no me gusta en mi situación por razones de seguridad. Me gusta mi par de llaves en mi propia PC y autenticar y verificar la máquina de destino final desde mi propia PC. Además, solo puede usar el shell interactivo para SSH, por lo que no se ocupará de otras herramientas como SCP o el uso de su administrador de archivos GUI.

Por todas las razones antes mencionadas, recomiendo encarecidamente el enfoque ProxyCommand , pero para una conexión rápida, esto funciona bien.

gertvdijk
fuente
¿Por qué no tener una respuesta con las soluciones 'One Off' y Permanente?
recatada
55
@demure Así es como funcionan los sitios de StackExchange ... Ver: ¿Cuál es la etiqueta oficial para responder una pregunta dos veces? dice "Es mejor publicar dos respuestas diferentes, que ponerlas en una sola respuesta". . Y no considero que sea la misma solución. Permanente / temporal no es lo que hace que este enfoque sea diferente, en mi opinión.
gertvdijk
Otras guías dicen usar, además, el interruptor -A, pero indican que esto tiene implicaciones de seguridad. ¿Sabe lo que significa reenviar o no la conexión del agente de autenticación?
Diagon
@gertvdijk super ninja aquí! Tienes las DOS mejores soluciones. Nunca he visto eso antes. Super guay. mucho mejor que crear una solución mega larga con N soluciones (que es lo que generalmente veo).
Trevor Boyd Smith
Esto es mucho más conveniente que configurar una configuración que también obstaculizará otros ssh.
Nikhil Sahu
37

Puede usar la -Jopción de línea de comando:

ssh -J user@machineB user@machineA

De man ssh:

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

Se introdujo en OpenSSH versión 7.3 (lanzado en agosto de 2016). Está disponible en Ubuntu 16.10 y posterior.

Erik Sjölund
fuente
3
+1 porque esto funciona incluso si necesita especificar el archivo de clave para la máquina A
Duelo
1
+1, esta es la mejor versión en comparación con mi respuesta de ProxyCommand si todos sus hosts están ejecutando una versión de OpenSSH lo suficientemente reciente.
gertvdijk
¿El servidor OpenSSH debe instalarse en las máquinas A y B en este caso? ¿Estoy bien entendido?
Mikhail
17

Intenta usar

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

en tu ~ / .ssh / config y hazlo todo de una vez con las claves que solo residen en tu computadora.

Ayuda SSH
fuente
1
Esto es más limpio que introducir netcat en la mezcla. Además, la clave SSH privada tampoco necesita existir en la Bmáquina.
danemacmillan
1

Esta es una sugerencia muy útil. Después de jugar durante horas, encontré esta nota y confirmó que funciona exactamente como se documenta. Para conectar a través de la máquina A a la máquina B, desde la máquina remota C:

por ejemplo: [xuser @ machineC ~] ssh -t MachineA ssh MachineB

El "-t" es crítico, ssh falla si no está presente. Se le solicitará dos veces, primero la contraseña en MachineA, luego la segunda en MachineB. Además, tenga en cuenta que esto supone que tiene el usuario "xuser" definido en las tres máquinas. Si no, simplemente use la sintaxis ssh: "yuser @ MachineA ...". También tenga en cuenta que, si lo desea, puede usar IP # s sin procesar con cuatro puntos. Esto es útil si se conecta a través de una red local privada que utiliza IP que no están expuestas al mundo, es decir. no en su archivo de host local ni en ningún DNS. Para obtener un archivo de MachineB, a machineC remoto, puede scp de MachineB a MachineA, luego de MachineA a machineC remoto. (Por ejemplo, la máquina remota C puede hacer ping a la máquina A, pero no a la máquina B.) Advertencia: probé con Fedora y Windows XP, MachineA es un XP-box que ejecuta ICS (Conexión compartida a Internet), mientras que MachineB y machineC remota son cajas Fedora-Linux. Esta sugerencia resolvió un problema clave para mí, es decir. acceso remoto restringido y monitoreado a mi sitio remoto lan. Tenga en cuenta también que cuando "cierre sesión" desde MachineB, debería ver dos "Conexión a xxx.xxx.xxx.xxx cerrada". mensajes

Mcl
fuente
Si configura y configura la autenticación de clave pública, no necesita preocuparse por ingresar sus contraseñas. Pero -taún se requiere.
Felipe Alvarez
@FelipeAlvarez ¡Aún debe preocuparse por ingresar la segunda contraseña si no confía en que la máquina B tenga un inicio de sesión sin contraseña en A!
Michael
1

ProxyCommand es una solución limpia para un caso en el que permite el acceso de shell en ambos sistemas. Queríamos dar a los usuarios remotos acceso a una máquina interna (A) a través de un intermediario (B), pero sin permitirle al usuario un acceso de shell a B para mejorar la seguridad. Esto funcionó:

Reemplace el shell de inicio de sesión

Reemplace el shell de inicio de sesión (uso chsh) para extuseren el intermediario con el siguiente script (almacenado en un archivo):

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

Siempre que no se haya configurado un inicio de sesión con contraseña en extuser @ B para el usuario remoto y en internaluser @ A para extuser @ B, la ejecución del siguiente comando llevará directamente al usuario remoto a A

ssh extuser@B

Consejo : Cree la configuración necesaria de inicio de sesión sin contraseña autor_keys en extuser @ B antes de cambiar al shell de inicio de sesión personalizado. Después del cambio, dado que esta cuenta es inaccesible para cualquiera a través de un shell, solo un sudoer @ B puede realizar cambios en el archivo autorizado_claves editándolo directamente.

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

La última línea es suprimir la pantalla de inicio de sesión de B, para que el usuario remoto tenga un acceso transparente a A.

Sunthar
fuente
Enfoque muy interesante. Sin embargo, las principales desventajas de esto son: 1) El uso está limitado al uso estándar de SSH (sin soporte SFTP / SCP). 2) Un usuario no puede seleccionar otro host de destino que no sea el único (porque está codificado en el shell de inicio de sesión) 3) La validación de la clave de host no se puede realizar desde la estación de trabajo hasta el host de destino final (ya que el uso del agente binario SSH) . 4) Las claves privadas para que los usuarios accedan al host objetivo final residen en el intermediario y no en el usuario. Esto permite la suplantación del usuario por un administrador (que normalmente no es posible).
gertvdijk
Todos los puntos son ciertos, gracias por su elaboración. Sin embargo, el objetivo principal es proporcionar un acceso ssh de usuario confiable a A sin iniciar sesión en B. Dado que solo el administrador puede agregar la clave pública del usuario confiable en B (a través de sudo, sin inicio de sesión), esto ya implica que el usuario tiene ( admin) acceso a la clave privada de extuser @ B (no del usuario de confianza externo), y lo ha configurado, en primer lugar.
Sunthar
1

Quieres decir que necesitas varios puentes :)

Recientemente, encontré este problema con jumper1 jumper2 y mi máquina final, en cuanto a mi sol

script local:

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

Luego, en el primer puente (que es mi enrutador), coloqué un script llamado Y00.sh:

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

Puede reemplazarlos con su IP y contraseñas, ¡buena suerte!

Z-Y00
fuente