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 -
Using SSH
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 -
Using SCP
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.