¿Cómo hago transferencias de Multihop SCP?

85

Quiero copiar un archivo de mi máquina A al servidor C, pero solo tengo acceso al servidor C a través del servidor B.

En lugar de transferir primero al servidor B, inicie sesión y luego transfiera al servidor C, ¿es posible transferir el archivo directamente con SCP o programas similares?

(El modo vagabundo de Emacs tiene esta función para editar archivos de forma remota).

sverrejoh
fuente

Respuestas:

48

Puede agregar -oopciones a en scplugar de .ssh/config.

scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path

$jump_host es su "servidor B" en este caso.

John Tantalo
fuente
Esta es mi forma preferida de hacer esto. Desordenar .ssh / config para compras múltiples no es la mejor solución si accede al mismo host desde una puerta de enlace y directamente.
GabrieleV
¿Cómo sería esto con nombres de usuario y puertos diferentes / personalizados?
Pablo A
Intento esto y debo ingresar la contraseña. Cómo puedo arreglar esto. Gracias.
hqt
44

Asumiendo OpenSSH, agregue a su configuración SSH en .ssh / config

Host distant
ProxyCommand ssh near nc distant 22

Esto hará que SSH pueda conectarse "directamente" a la máquina llamada distante mediante proxy a través de la máquina nombrada cerca. Luego puede usar aplicaciones como scp y sftp para la máquina distante.

Para que esto funcione, necesita 'nc', también conocido como netcat, instalado en la máquina llamada near. Pero muchos sistemas modernos ya lo tendrán.

La solución de alquitrán de towo es más efectiva para problemas de un solo disparo, suponiendo que haya memorizado la sintaxis y las reglas de operación de alquitrán.

tialaramex
fuente
Este es el mismo método que uso ... En este ejemplo, 'distante' sería el servidor C y 'cercano' sería el servidor B para aclarar ...
Jeremy Bouse
Muchas máquinas modernas no tienen 'nc': normalmente está disponible solo para máquinas Linux y solo a pedido (no forma parte de la instalación estándar).
Mei
1
ssh tiene ahora la opción -W, que hace esto automáticamente sin 'nc', pero me pregunto por qué no hay scp -W
kubanczyk
3
En caso de que no sea el único, esto no era obvio: si el nombre de usuario activado neares diferente del nombre de usuario activado distant, el usuario cercano ingresa ProxyCommand ssh nearuser@near...y el usuario distante entra en una User distantuserlínea separada .
Mu Mind
Simplemente escriba ssh multi hope y presione Google Me siento afortunado
chandank
19

Con versiones más recientes de ssh en el servidor cerca de la máquina (B), lo siguiente funcionará sin netcat:

Host distant
    ProxyCommand ssh near -W distant:22

Sin embargo, requerirá AllowTcpForwarding para que sea sí (el valor predeterminado) en la máquina cercana (B)

editar: requiere OpenSSH 5.4+ en B

danblack
fuente
funciona como un encanto :)
gongzhitaao
1
Y a partir de OpenSSH 7.4p1 como mínimo, hay un comando "ProxyJump" en el que solo hay que enumerar cada usuario @ host: puerto separado con comas. ¡Agradable!
hmijail
ProxyJump es bueno, pero no tomó el User and IdentityFile del archivo de configuración. ProxyCommand -W hace esto y también funciona con scp.
rickfoosusa
18

Puede enviar ssh al servidor B usando algo como

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>

Entonces puede enviar ssh al servidor C usando

ssh -p 5022 <user_serverC>@localhost 

Del mismo modo, scp funcionaría usando

scp -P 5022 foo.txt <user_serverc>@localhost:

Recuerde usar el caso correcto de p con scp y ssh

Saurabh Barjatiya
fuente
5

Es posible y relativamente fácil, incluso cuando necesita usar certificados para autenticación (típico en entornos de AWS).

El siguiente comando copiará los archivos de un remotePathen server2directamente a su máquina en localPath. Internamente, la solicitud scp se procesa mediante server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Al revés también funciona (subir archivo):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>

Si utiliza la autenticación de contraseña en su lugar, intente con

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Si usa las mismas credenciales de usuario en ambos servidores:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
donhector
fuente
3

Si quieres ser realmente malvado, puedes encadenar ssh y alquitrán, algo así tar c mydir | ssh server "ssh otherserver | tar x", pero esto puede toparse con todos los problemas.

La forma más fácil sería simplemente configurar un túnel SSH con los métodos integrados de SSH; mira el -Dconmutador en la página de manual y simplemente reenvía algún puerto al puerto ssh del otro servidor.

towo
fuente
2

También puede hacer esto a la inversa y tal vez sea más fácil.

Supongamos que tiene una sesión ssh abierta con la máquina a la que desea enviar el archivo. Esta PC de salto más lejano, la llamaremos hop2. Su host "proxy" será hop1. La PC que es de origen de archivo, llamaremos a ese origen.

origin:~/asdf.txt  --> hop1 --> hop2:~/asdf.txt

Puede construir túneles haciendo que un puerto local esté disponible en una PC remota. De este modo, estamos definiendo un puerto para abrir en la PC remota, que será una redirección al puerto que detuvo con usted cuando construyó el túnel.

En hop2:

ssh -R 5555:127.0.0.1:22 <hop1_user>@<hop1_IP>
#this has the effect of building a tunnel from hop2 to hop1, making hop2's port 22 available on hop1 as port 5555

Ahora en esa sesión de túnel abierta, puede hacer lo mismo desde hop1 hasta file_origin.

En hop1:

ssh -R 6666:127.0.0.1:5555 <origin_user>@<origin_IP>
#this has the effect of building a tunnel from hop1 to origin while also pulling the active tunnel with it, making hop1's port 5555 (hop2's port 22) available on origin as port 6666.

Ahora está canalizado de hop2 a hop1 al origen. Casualmente, ahora tanto el puerto 5555 como el 6666 están abiertos en origen, que son redireccionamientos al puerto 22 de hop2. Dentro de esta sesión, las dos siguientes son rutas scp válidas para hop2:

En origen:

scp -P 6666 ~/asdf.txt <hop2_user>@<127.0.0.1>:~/asdf.txt

De esta manera, puede tener un número arbitrario de saltos en el medio, y es más fácil trabajar en términos de encadenar más de dos saltos.

SYANiDE
fuente
1

Pruebe adapring en el siguiente ejemplo openssh config para una configuración que se puede usar para varios hosts:

Host uat-*
     ProxyCommand ssh bastion-uat nc %h %p

Esto supone un conjunto de servidores que comienzan con "uat-" a los que solo se puede acceder a través del servidor jumpbox / gateway "bastion-uat". Probablemente también desee agregar ForwardAgent yessi está usando una clave para iniciar sesión.

Benjamin Goodacre
fuente
No lo uses ForwardAgent yespara esto. El reenvío de agentes no es necesario en este caso porque no se ejecutará ningún cliente ssh en el bastión, y reenviar un agente cuando no sea necesario solo reducirá la seguridad. Y creo que sshfalta tu comando. Si sshse está utilizando una versión reciente que no necesita nc, puede escribir en su ssh -W %h:%p bastion-uatlugar.
kasperd
@kasperd Editado para incluir ssh. Re ForwardAgent; se ejecutará un cliente ssh para ejecutar el comando nc. Tal vez te refieres a la cáscara?
Benjamin Goodacre
1

Esto no es scp (que OP solicitó), pero me pareció muy simple de usar rsyncpara copiar de local a remoto en un solo salto con:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination

Fuente: http://mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

Había intentado la sugerencia -o ProxyPass anterior y no quería cambiar la configuración para mis necesidades cambiantes. Como dice el autor en el enlace anterior, el archivo de destino que precede a los dos puntos (:) es importante para indicar que la ruta especificada está en el servidor de destino. Además, con rsync, tiene las opciones de comparación de fechas, sincronización de carpetas, etc. ¡Espero que esto ayude a alguien!

texas-bronius
fuente
-2

scp -o 'ProxyJump jumpboxname' somefilename.txt finaldestinationhost: / tmp /.

Yo y
fuente
3
No descargues un poco de código inexplicable aquí. Hay muchas buenas respuestas a esta pregunta y necesita agregar valor a las existentes, esto no es así.
Sven