has_many :codes

Transfer files through an intermediate server

Published  

Sometimes I need to copy files from a remote server, but I can only access it through an intermediate server due to some restrictions, so here’s a couple of ways to transfer files through an intermediate server. 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 [email protected]

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 [email protected]:/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:

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.

© Vito Botta