52

I am currently away from my LAN and I need to do a backup of my laptop. I have a somewhat recent copy of my laptop on my server and I usually back the laptop up using rsync. Now I wish to do that, but outside of my LAN.

In short I want to send data from A to C via B, where A is my laptop, B my router and C my server.

I found this command: A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination, that works fine for transferring files via scp - but since I already have most of the data on my server I wish to use rsync to only sync the delta.

I have tried: A$ rsync file -e 'ssh B ssh' C, and that works as far as I am prompted to give the password for user:C. However, when I enter the password nothing happens. The router is running Tomato v1.28 and I am unable to set it up to utilize an ssh config file to enable it to log onto C w/o a password.

Any ideas on how to make this work?

GLaDER
  • 761
  • 1
  • 5
  • 8

5 Answers5

87

This question is essentially answered elsewhere, including here for scp and here for rsync. Since the latter includes my answer, but no answer was accepted, I'll repeat it here.

As you noted, you can use rsync's -e | --rsh option, but it's going to be a bit more complicated:

rsync -azv -e 'ssh -o "ProxyCommand ssh -A PROXYHOST -W %h:%p"' foo/ dest:./foo/

Or, if your version of ssh is new enough (OpenSSH >= v7.3), you can use the -J (ProxyJump) option

rsync -azv -e 'ssh -A -J USER@PROXYHOST:PORT' foo/ dest:./foo/

Note that I'm using -A (agent forwarding) but it should also work with password authentication if you don't use keys, and, of course, you can replace proxy with B and dest with C in your example.

If by chance you don't have a new enough ssh version (>= 5.3, IIRC), you can use netcat instead of -W option to ssh:

rsync -azv -e 'ssh -o "ProxyCommand ssh -A PROXYHOST nc %h %p"' foo/ dest:./foo/

Finally, as noted in comments already, you can put the ProxyCommand into your $HOME/.ssh/config file so you don't have to have such a complicated command line. Specifically, add something like this:

Host C
  ProxyCommand ssh -A PROXYHOST -p 22 -W %h:%p

Or, using ProxyJump for OpenSSH >= v 7.3:

Host C
  ProxyJump PROXYHOST

Then you should be able to just do:

rsync -azv foo/ C:./foo/
crimson-egret
  • 3,276
  • 17
  • 20
  • I can ssh from PROXYHOST to dest without a password, but when I use -J (with or without -A) it's prompting me for a password. how do i not get prompted like when i'm directly on PROXYHOST? – Michael Mar 17 '20 at 06:23
  • ProxyJump (or ProxyCommand) directives have no influence over password prompts. In my examples, I assumed an ssh key on your localhost that you use ssh-agent forwarding to avoid password prompts. I DISCOURAGE using passphrase-less ssh keys ANYWHERE, and especially on the PROXYHOST. This is not really an answer to your question, but that's mostly because there are not enough details to be able to answer completely. – crimson-egret Mar 17 '20 at 12:52
  • I tried to figure it out about 8 hours but no luck. I have same public key on both intermediate and destination server and use this commad to comnect destination but it's prompts for password: ssh -i ~/.ssh/id_rsa -J user@intermediate-server user@destination-server – Adnan Jul 22 '21 at 17:06
  • I would suggest trying with just `ssh` and use the `-v*` option to test your ssh connection before putting `rsync` in the mix. I – crimson-egret Jul 26 '21 at 16:30
  • @crimson-egret - I have a similar case, A - Source B - Jumphost - We have dedicated account created and this user doesn't allow for direct SSH C - Destination Currently, we are copying files from source to jumphost (A to B) and again coping files from jumphost to C (B to C). we are using rsync to sync the files. Is it possible to use the above solution in our case ? to directly sync files using rsync from A to C via jumphost B ? – Light Oct 29 '22 at 07:59
  • @Light - yes, though if you have different usernames across the hosts, you might have to add additional arguments to define the username in your config files on a per-host basis. – crimson-egret Nov 03 '22 at 14:10
  • @crimson-egret - Currently direct ssh is not allowed . How can I execute rsync from source to destination via jumphost ? where should I execute rsync in source or jumphost ? – Light Nov 03 '22 at 18:16
  • You always execute `rsync` on one end or the other, not on `jumphost`. I'm not sure I udnerstand what you mean by "direct ssh". If you mean you can't `ssh C` from `A`, then this recipe is exactly what you wanted. – crimson-egret Nov 03 '22 at 18:22
  • @crimson-egret- I mean we can't ssh from A (source) to B (Jumphost). Currently we can only execute rsync in jumphost where we can copy files from A to B and again rsync from B to C from jumphost – Light Nov 03 '22 at 18:48
  • Can you go the other way around? That is, can you **pull** from "A" by executing the `rsync` on "C" and using "B" as the jumphost? If not, then the approch I advocated above is not going to work since it requires connectivity from one side (SRC) to the other (DST), in either direction. – crimson-egret Nov 04 '22 at 19:59
  • @crimson-egret - I tried below cmd in C: sudo -u user rsync -azv --rsync-path="sudo rsync" -e "ssh -A -J JumpHost:22" SourceIP:/home/user1/myfolder /home/user1/myfolder/ Getting this error any help: ssh_exchange_identification: Connection closed by remote host rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: unexplained error (code 255) at io.c(226) [Receiver=3.1.2] – Light Nov 05 '22 at 15:25
  • @crimson-egret - I can do ssh from B (jumphost) to A(source) and B(jumphost) to C. but can't do in either direction – Light Nov 07 '22 at 18:14
  • If you can't get from A to C or C to A (both via "B), then a single `rsync` command as outlined here is of no use to you. The whole point of a jumpshost is provide a server which can do exactly that. You can probably automate via custom script and temporary directory on B, but otherwise I'm not going to be able to help you since your network setup is off-topic. – crimson-egret Nov 07 '22 at 18:21
  • Aside: if you are trying to use `sudo` in the mix as well, that's another complication - unless your system allows passwordless `sudo` (a bad idea, security wise), you'll have to do some other shenaigans with `sudo` tickets, possibly disabling `tty_tickets` in your `sudo` config. That's a whole different can of worms. – crimson-egret Nov 07 '22 at 18:23
  • @light - one more comment to hopefully help you on your way - as I noted earlier to someone else, before trying to use `rsync` with a jumphost, see if you can just `ssh` via a jumphost. You can try the `-v` option as well to get more verbose output. Also suggest you refrain from using `sudo` in the mix until you get the bare-bones connectivity down. Remeber that in using `rsync`, we are piggy-backing on `ssh` and nothing will work if you can't at least do that. – crimson-egret Nov 09 '22 at 13:40
6

Here is how to copy data from local machine to target machine with the bastion machine sitting in between the two (progress bar included):

rsync -r --info=progress2 -e 'ssh -J bastion-user@bastion-host:22' local-file-path target-machine-user@target-machine-host:target-machine-save-location
Stephen Rauch
  • 3,091
  • 10
  • 23
  • 26
0

The first attempt of OP worked fine for me, using public key between all nodes:

A> rsync -avz D:destiny/ ~/origin/ -e "ssh C ssh B ssh"

Download files from D to A, through C and B.

dawid
  • 159
  • 1
  • 7
0

In order not make @crimson-egret's answer any more complex, I'm posting this variant as a new answer.

If your destination host uses a custom port and different username, the syntax is as follows:

rsync -azv -e 'ssh -A -J USER@PROXYHOST:PORT -p dest_port' foo/ dest_user@dest_host:./foo/

dest is your destination machine where

  • dest_port is its SSHD port,
  • dest_user is the username on the destination,
  • dest_host is the IP address (or domain name) of the destination
ceremcem
  • 575
  • 8
  • 22
-1

You will need AllowTcpForwarding no in the sshd config of the host used to hop into the next one.