archivos scp a través de host intermedio

85

Tengo acceso a 3 máquinas, A, B y C. Las únicas conexiones posibles (ssh) son:

A -> B
B <-> C

Necesito obtener archivos de A a C, para poder scp los archivos de A a B, y luego scp de B a C. Sin embargo, B no tiene mucho espacio en disco, por lo que esta no es una opción. ¿Hay alguna manera de scp archivos de A a C a través de B? Tenga en cuenta que no tengo acceso de root en ninguna de las máquinas, así que no piense que puedo configurar túneles persistentes, ¡pero corríjame si me equivoco!

astrofrog
fuente
66
Sé que esto no responde la pregunta, pero para aquellos que no saben acerca de rsync, o no saben cómo usarlo para saltar a través de un host, este podría ser un consejo útil: use la opción '-e' con rsync así:A$ rsync <options> -e 'ssh B ssh' source C:destination
Editado el

Respuestas:

108

ProxyJump

Nuevo en OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(Detrás de escena, esto solo usa ProxyCommand y ssh -W).

ProxyCommand

Actualizado para incluir -W de otras respuestas:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Si A tiene un cliente SSH muy antiguo instalado (sin -Wsoporte), o si B está configurado para no permitir el reenvío TCP (pero aún permite comandos de shell), use alternativas:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

Tubería

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

Por solo un archivo:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

"Túnel" a través de B

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

Cuando haya terminado, no olvide matar el sshproceso iniciado anteriormente (que se ha caído al fondo debido a -f -N).

  • -fSolicita a ssh que vaya al fondo justo antes de la ejecución del comando. Esto es útil si ssh va a pedir contraseñas o frases de contraseña, pero el usuario lo quiere en segundo plano. Esto implica -n.
  • -NNo ejecute un comando remoto. Esto es útil solo para reenviar puertos.

Invierta el "túnel" a través de B a A

Sin embargo, no siempre funciona:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R Especifica que las conexiones al puerto TCP dado o al socket Unix en el host remoto (servidor) se deben reenviar al host y al puerto dados, o al socket Unix, en el lado local.
Gravedad
fuente
Muchas gracias por estos ejemplos @grawity. Una pregunta: ¿es posible invertir `tar c thefile anotherfile | ssh B "ssh C \" cd destination && tar xv \ "" ´ para copiar la descarga de C a A (estar en A)
dmeu
@dmeu: Sí, es posible.
Grawity
¿Cómo "matar" el proceso ssh iniciado anteriormente si digo que estoy usando un MacOS?
Aero Windwalker
Nota: como de costumbre, si desea pasar scp de C, aunque B, a A, puede hacerlo A$ scp -oProxyJump=B C:destination thefile.
jvriesem
@Pablo Mejor use -S, entonces, y -O salga. O ... al menos pkill -f.
Grawity
24

Las versiones de scp de principios de 2011 y posteriores pueden tener una opción "-3":

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

Si tiene esto, simplemente puede ejecutar:

B$ scp -3 A:file C:file
Dan Bloch
fuente
En mi caso, el host A solo era accesible desde B (que estaba VPNed). El host C estaba en la misma LAN que B. Quería obtener un archivo de A a C y scp -3 lo resolvió de manera brillante.
Joe
Tuve problemas con esto cuando ambos hosts solicitaron una contraseña. Parecería pedir ambos a la vez (aparecieron dos mensajes de contraseña en la misma línea) y luego no aceptó mi contraseña. Eventualmente pude hacer que funcionara escribiendo mi contraseña repetidamente (la misma contraseña en ambos hosts), pero fue difícil de entender.
Colin D
8

Casi todo ya se ha dicho, pero aquí está mi último centavo: uso la variante ProxyCommand sin ncni soc. Basado en OpenSSH Proxies y Jumphost Cookbook, diseñé la siguiente configuración:

  1. Entonces tenemos los siguientes jugadores:

    • HOME_HOST: es desde donde copiamos un archivo al host de destino
    • HOP_HOST: copiamos a través de este host (registrado como HOP_USER)
    • TARGET_HOST: es nuestro destino (autenticado como TARGET_USER)
  2. En primer lugar he añadido mi clave pública local desde mi anfitrión casa .ssh/id_dsa.pub a .ssh/authorized_keysen ambos anfitriones hop y de destino. Sí, la misma clave pública del host principal para ambos. Por lo general, esperaría que sea la clave pública HOP la que tiene que agregar a la OBJETIVO.

  3. Luego modifiqué .ssh/configun poco agregando la siguiente entrada:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. Después de que la operación de copia es tan simple como: scp FILE TARGET_HOST:. Muestra pancartas dobles de los nodos de salto y de destino, pero funciona.

Por supuesto que puede usar encima de ssh directamente en el destino: ssh TARGET_HOST. Funciona con scp y ssh.

Otra opción más general podría ser la utilidad sshuttle , que parece ser una especie de proxy transparente (vpn sobre ssh). Entonces, en su caso de A-> B <-> C, permite conectarse a cada nodo en la red de C: A-> B- [CDEFG]. No necesita administrador, pero requiere Python 2.7 (3.5 también está bien), que no siempre es lo que tenemos. Vale la pena intentarlo.

SQ9MCP
fuente
7
ssh -L 4321:hostC:22 youruser@hostB

en otro caparazón:

scp -P 4321 localfile [email protected]

Esto está utilizando el reenvío de puertos. La única limitación aquí es que el host B debe configurarse para permitir el reenvío de puertos. De lo contrario, esto debería funcionar bien.

A modo de explicación, -Ly le -Rpermite reenviar puertos. En -L, el primer puerto dado es el puerto ssh comenzará a escuchar en la máquina de origen (host A), y reenviará todo lo que reciba en ese puerto a través de su conexión SSH al host B, luego se enrutará al host C en el puerto 22.

editar

Me equivoqué un poco la sintaxis. Configura un reenvío en su máquina LOCAL.

Brian Vandenberg
fuente
@astrofrog: si una de nuestras respuestas satisface sus necesidades, probablemente debería aceptar una de ellas.
Brian Vandenberg
2

La respuesta de ProxyCommand de Grawity funcionó para mí, pero como estoy menos familiarizado con SSH, me llevó un poco de experimentación. Pensé que simplemente explicaría la respuesta de Grawity con más detalle para ayudar a cualquier otro novato a SSH como yo. Aquí están las definiciones para una notación más explícita:

Máquina A: la máquina en la que estás

Servidor B: [email protected] (el servidor principal o el servidor intermedio)

Servidor C: [email protected] (el servidor remoto al que desea copiar)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" thefile [email protected]:destination

Ejemplo concreto

Entonces, para un ejemplo concreto, supongamos que tiene acceso a un servidor con IP 0.0.1.2con una cuenta de usuario llamada bar(Servidor C). Pero para llegar a él, primero debe iniciar sesión en un servidor con IP 0.0.1.1con una cuenta de usuario llamada foo(Servidor B). Ahora desea copiar el archivo baz.txtubicado en su equipo actual (la máquina A) al servidor 0.0.1.2's /home/bar/directorio. Para usar el ProxyCommand anterior para este ejemplo, debe ejecutar lo siguiente:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" baz.txt [email protected]:/home/bar/

También puede copiar fácilmente un archivo desde el Servidor C cambiando el orden del archivo y el destino. Entonces, por ejemplo, si baz.txtya estaba en el servidor 0.0.1.2ubicado en, /home/bar/entonces podría copiarlo a su máquina usando:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" [email protected]:/home/bar/baz.txt /destination/path/on/A

Espero que esto ayude a las personas que necesitan explicarse un poco más que otros.

Joseph Carmack
fuente