nblock's ~

Transfer files between two hosts via an intermediate host

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.


tagged nc, scp and ssh