has_many :codes

Vito Botta's journal with tips and walkthroughs on web technologies and digital life

Copy files via an intermediate server with SSH/SCP

Sometimes I need to copy files from a remote server, but I can only access it through an intermediate server due to some restrictions.

I can’t remember always how to do it so I thought I’d add some notes here which may hopefully save time to others; I bet there are many ways of doing this, but here’s a couple. The first one is with SCP, using an SSH tunnel. First, start the tunnel with:

ssh -L <local-port>:<gateway-address>:<ssh-port-target-server> <target-user>@<target-server>  

So, for example, given

  • I can SSH into the intermediate server 1.2.3.4 (with settings stored in ~/.ssh/config for example)
  • from the intermediate server, I can SSH into the target server 5.6.7.8 with the user vito and SSH listening on the port 9876

I would start the tunnel with the command:

ssh -L 5000:1.2.3.4:9876 vito@5.6.7.8  

where 5000 is just a random port I choose. Once the tunnel is started, to copy files from the remote server, through the tunnel, you can run:

scp -P 5000 vito@127.0.0.1:/path/to/file /local/destination/folder/

That’s it. SCP should copy files just as it would do if there were a direct SSH connection with the target server. Unfortunately, it is not always possible to copy files this way because SSH forwarding may have been disabled on the intermediate server for security reasons; in this case, using an SSH tunnel won’t work and you’ll see errors like:

channel 3: open failed: administratively prohibited: open failed

There is another trick though we could use in this case to copy files, using SSH directly and without a forwarding tunnel. An example:

bash ssh 1.2.3.4 "ssh 5.6.7.8 \"cat /path/to/file\"" | pv > /local/destination/folder/
477MiB 0:05:05 [1.81MiB/s] [ <=> ]
```

I like this trick because it doesn’t require any particular configuration on either the intermediate server or the target server, and it uses a tool like cat which I believe is available on all distros; pv is optional, but quite handy since it shows how much has been copied and the transfer speed, in realtime. In the example above pv won’t show the % of the file which has already been copied, but it’s easy to fix that by passing the -s SIZE argument (you need to know the size of the file in advance for the progress bar to be accurate).

I would be curious to know if there are other tricks to copy files via an intermediate server, so please leave a comment if you are aware of any others. :)

Author image
About Vito Botta
Espoo, Finland Website
I am a passionate developer based in Espoo, Finland, where I work as Lead Software Engineer for OnApp. My roles as architect, coder and technology enthusiast overlap each other here on this web log.