Transfer files between two hosts via an intermediate host
written on Thursday, June 30, 2016
Once in a while I need to transfer files from host A to host C without having a direct connection between them. However, host B can connect to both of them:
A <----> B <----> C
A typical use case is to copy files from a server to an isolated virtual machine.
Using traditional netcat
The following commands work with the traditional netcat (netcat-traditional on Debian Jessie). In order to automatically close the connection one needs to specify the -q parameter with an appropriate timeout on host A. Otherwise the connection is kept open until it is closed manually (CTRL-C).
- Host A: $ tar -cJf - directory | nc -q 0 B 8000
- Host B: $ nc -l -p 8000 | nc C 9000
- Host C: $ nc -l -p 9000 | tar -xJf -
Using OpenBSD netcat
In case the OpenBSD version of netcat is available (netcat-openbsd on Debian Jessie) one might use the following commands instead.
- Host A: $ tar -cJf - directory | nc B 8000
- Host B: $ nc -l 8000 | nc C 9000
- Host C: $ nc -l 9000 | tar -xJf -
One can also establish SSH port forwarding to secure the transfer between host A and host C:
- Host A: $ tar -cJf - directory | nc localhost 10000
- Host B (1): $ ssh -N -R 10000:localhost:10000 user@A
- Host B (2): $ ssh -N -L 10000:localhost:10000 user@C
- Host C: $ nc -l 10000 | tar -vxJf -
If the relevant files are accessible from the user that is used to establish the SSH connection you might also use scp with the -3 option. On host B: $ scp -r -3 user@A:/path/to/directory user@C:/path/to/destination.
There are more ways to transfer files using an intermediate. Drop me a line, if you know about a particular neat one.