As you have discovered you cannot use rsync with a remote source and a remote destination. Assuming the two servers can’t talk directly to each other, it is possible to use ssh to tunnel via your local machine.
rsync -vuar host1:/var/www host2:/var/www
you can use this
ssh -R localhost:50000:host2:22 host1 'rsync -e "ssh -p 50000" -vuar /var/www localhost:/var/www'
In case you’re wondering, the
-R option sets up a reverse channel from port 50000 on host1 that maps (via your local machine) to port 22 on host2. There is no direct connection from host1 to host2.
You didn’t say why you didn’t want to log into one host and then copy to the other so I will share one of my reasons and solutions.
I couldn’t log into one machine then rsync to the other because neither host had a SSH key that could log into the other. I solved this by using SSH agent forwarding to allow the first host to use my SSH key while I was logged in.
WARNING: SSH forwarding allows the host to use your SSH key for the duration of your login. While they can’t copy your key they can log into other machines with it. Make sure you understand the risks and don’t use agent forwarding for machines you don’t trust.
The following command will use SSH agent forwarding to open a direct connection from
host2. This has the advantage that the machine running the command isn’t bottlenecking the transfer.
ssh -A host1 rsync -vuar /var/www host2:/var/www
I like roaima’s answer, but the paths are the same in both examples, obscuring which is which. We’ve established that the following doesn’t work:
rsync -vuar host1:/host1/path host2:/host2/path
But this does (I omitted the explicit bind_address of localhost from the
-R option since that’s the default):
ssh -R 50000:host2:22 host1 'rsync -e "ssh -p 50000" -vuar /host1/path localhost:/host2/path'
Note that you’ll have to have ssh keys set up correctly between the two remote hosts, with the private key on host1 and the public key on host2.
To debug the connection, break this into two parts and add verbose status:
localhost$ ssh -v -R 50000:host2:22 host1
If this works, you’ll have a shell on host1. Now try the rsync command from host1. I recommend doing this in a different window so the verbose ssh info doesn’t get mixed together with the rsync status info:
host1$ rsync -e "ssh -p 50000" -vuar /host1/path localhost:/host2/path