How do I do Multihop SCP transfers between machines?

83,068

Solution 1

You can add -o options to scp instead of .ssh/config.

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

$jump_host is your "server B" in this case.

Solution 2

Assuming OpenSSH, add to your SSH configuration in .ssh/config

Host distant
ProxyCommand ssh near nc distant 22

This will cause SSH to be able to connect "directly" to the machine named distant by proxying through the machine named near. It can then use applications like scp and sftp to the distant machine.

For this to work you need 'nc' aka netcat installed on the machine named near. But a lot of modern systems will have it already.

towo's tar solution is more effective for one-shot problems, assuming you've memorised tar's syntax and rules of operation.

Solution 3

With more recent versions of ssh on the server near (B) machine the following will work without netcat:

Host distant
    ProxyCommand ssh near -W distant:22

It will however require AllowTcpForwarding to be yes (the default) on the near (B) machine

edit: requires OpenSSH 5.4+ on B

Solution 4

You can ssh to server B using something like

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

Then you can ssh to server C using

ssh -p 5022 <user_serverC>@localhost 

Similarly scp would work using

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

Remember to use correct case of p with scp and ssh

Solution 5

It's possible and relatively easy, even when you need to use certificates for authentication (typical in AWS environments).

The command below will copy files from a remotePath on server2 directly into your machine at localPath. Internally the scp request is proxied via server1.

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

The other way around also works (upload file):

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

If you use password authentication instead, try with

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

If you use the same user credentials in both servers:

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

The -W option is built into new(er) versions of OpenSSH, so this will only work on machines that have the minimum version (5.4, unless your distro back-ported any features; e.g., RHEL6 OpenSSH 5.3p1 includes this feature). Per the release notes: http://www.openssh.com/txt/release-5.4

Added a 'netcat mode' to ssh(1): "ssh -W host:port ..." This connects stdio on the client to a single port forward on the server. This allows, for example, using ssh as a ProxyCommand to route connections via intermediate servers.

%h and %p are placeholders for the host and port.

Share:
83,068

Related videos on Youtube

maslovalex
Author by

maslovalex

Developer living and working in Chandigarh, India.

Updated on September 17, 2022

Comments

  • maslovalex
    maslovalex almost 2 years

    I want to copy a file from my machine A to server C, but only have access to server C through server B.

    Instead of first transferring to server B, log in and then transfer to server C, Is is possible to transfer the file directly with SCP or similar programs?

    (Emacs tramp-mode has this feature for editing files remotely).

  • Jeremy Bouse
    Jeremy Bouse almost 15 years
    This is the same method I use ... In this example 'distant' would be server C and 'near' would be server B for clarification...
  • Mei
    Mei almost 15 years
    A lot of modern machines don't have 'nc': it's normally available only to Linux machines and only by request (not part of the standard install).
  • GabrieleV
    GabrieleV almost 13 years
    Thi si my preferred way to do this. Messing up .ssh/config for multihopping is not the best solution if you access the same host either from a gateway and directly.
  • Naveed Abbas
    Naveed Abbas over 12 years
    ssh has now -W option, that does this automatically without 'nc', but I wonder why there isn't scp -W
  • Mu Mind
    Mu Mind over 12 years
    In case I'm not the only one this wasn't obvious to: if the username on near is different from the username on distant, the near user goes into ProxyCommand ssh nearuser@near..., and the distant user goes into a separate User distantuser line.
  • chandank
    chandank over 11 years
    Just type ssh multi hope and press Google I am feeling lucky
  • gatoatigrado
    gatoatigrado over 11 years
    Do you know how to make it work with globbing? Like, if I have a cluster with machines node1, node2, node3 -- in SSH config, I can usually write "Host node*", but this seems to require the exact names hardcoded?
  • hdave
    hdave about 11 years
    Current versions of ssh have nc built-in so now you only need to use the -W command line option: ProxyCommand ssh near -W distant:22
  • gongzhitaao
    gongzhitaao almost 11 years
    works like a charm :)
  • Benjamin Goodacre
    Benjamin Goodacre about 10 years
    @kasperd Edited to include ssh . Re ForwardAgent; a ssh client will run in order to run the nc command itself. Perhaps you are referring to the shell?
  • Jeff Ward
    Jeff Ward over 8 years
    Thanks! BTW, my near server uses a non-standard SSH port (123) and username, e.g. ProxyCommand ssh nearusername@near -p 123 nc distant 22
  • hmijail mourns resignees
    hmijail mourns resignees almost 7 years
    And as of OpenSSH 7.4p1 at the very least, there is a "ProxyJump" command in which one only has to list each user@host:port separated with commas. Nice!
  • rickfoosusa
    rickfoosusa about 6 years
    ProxyJump is nice, but it didn't take the User and IdentityFile from the config file. ProxyCommand -W does this and also works with scp.
  • Pablo A
    Pablo A almost 6 years
    How this would be with different/custom usernames and ports?
  • FooBee
    FooBee over 5 years
    Don't just dump a bit of unexplained code here. There are plenty of good answers to this question and you need to add value to the existing ones - this doesn't.
  • hqt
    hqt almost 5 years
    I try this and must input password. How can I fix this. Thanks.
  • Askar Kalykov
    Askar Kalykov almost 4 years
    In my case, with help of this info stackoverflow.com/questions/22635613/…, another option worked: scp -o ProxyCommand="ssh $jump_host -W $host:22" $local_path $host:$destination_path
  • AATHITH RAJENDRAN
    AATHITH RAJENDRAN over 3 years
    explanation added to for -W, %h:%p will make this post more useful for first-timers like me. @donhector
  • openCivilisation
    openCivilisation over 3 years
    If the user on server2 has passwordless sudo to retrieve the file, how can sudo be used to avoid permission denied errors?
  • JS.
    JS. over 3 years
    You're right. It is easier to just use rsync rather than deal with scp's oddities.
  • Ben
    Ben almost 3 years
    What if I need one more hop? Is there any chainable syntax/solution?
  • user1079505
    user1079505 over 2 years
    I understand by local_path you mean source_path?
  • Admin
    Admin about 2 years
    How to save ssh keys with ssh-copy-id?