4

I have 3 computers/servers, let's call them as computer A, computer B and computer C.

  • Computer A has access via ssh to computer B.
  • Only computer B has access via ssh to computer C.
  • Computer A doesn't have access to computer C directly.

So, I want to rsync directories from computer A to computer C, using computer B(since only computer B has access via ssh to computer C). I want to use rsync in a simple way, like this:

rsync -options /path_to_local IpComputerC:/path_to_remote

I'm thinking on a ssh tunnel, but I don't know if I have to make a local port forwarding or a remote port forwarding, or if I have to make two tunnels: one from A to B and other from B to C?

Any suggestions?? I'd be really grateful.

**UPDATE: I dit it!! I created an ssh tunnel with local port forwarding, which means that I used a local port from the machine A to connect with a remote port on the machine C through the machine B. The syntax for the command is:

ssh -f -N -L local_port_machineA:ip_machineC:remoteport_machineC user_machineB@ip_machineB

In my case, remoteport_machineC shoul be port 22, because I want to rsync directories through ssh.

After that, we can execute the rsync command from the machine A, in this way:

rsync -avz -e "ssh -p local_port" /source_directory username_machineC@localhost:/target_directory

That's all. Additionally, you can add more options in the part inside the quotes, such as keys or files, etc.**

4 Answers 4

9

Much simpler than other suggestions: use rsync's -e | --rsh option:

rsync -azv -e 'ssh -o "ProxyCommand ssh -A proxy -W %h:%p"' 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 proxy nc %h %p"' foo/ dest:./foo/
3
  • My server "C" is a port on localhost on B (that is, there is a reverse tunnel set up from C to B). How can I rsync from A to C? That is, I need to specify different ports on B and C.
    – CPBL
    Oct 28, 2018 at 3:56
  • Not quite enough information to know exactly how to address your situation. What is being tunneled over ssh (your "reverse tunnel")? Is it ssh? If so, you need only replace the (standard) port with the reverse tunnel endpoint port you specified. Oct 29, 2018 at 14:31
  • Here's my answer to my comment above: rsync -avzhP -e "ssh -A serverB ssh -p 9222" localfilename localhost:remotefilename where the tunnel of serverC ends on port 9222 on serverB
    – CPBL
    Oct 29, 2018 at 18:13
0

One solution would be a crontab on your "jump node" (Computer B in this scenario).

A --> B (manually initiated, or could also be done via crontab on nodeA)

rsync -avzP --progress /path/to/transfer/ user@nodeB:/transfer/share/

B --> C (create a crontab to run every 15 mins)

sudo crontab -e
*/15 * * * * rsync -avzP --progress /transfer/share/ user@nodeC:/destination/share/

You might wish to further secure this by locking down access via a "service account" (AKA: ProdID) with limited access. Alternately you could use a SSH key to get around a password prompt at login.

http://www.rackspace.com/knowledge_center/article/generating-rsa-keys-with-ssh-puttygen

supplemental information

Have you considered a remote NFS share (offered by nodeC, remotely mounted on nodeB, and targeted by the rsync from nodeA)? In this scenario, the remote NFS share (from NodeC) would be mounted on NodeB (and would appear as a standard file-system from the OS perspective). As such, it would be accessible within the connection scenario you describe, without consuming DISK on NodeB. Thus, you would be able to adapt the 'rsync' syntax above to point at the remote NFS share mounted on NodeB to ultimately "pass-thru" onto NodeC. There may also be security concerns you will wish to consider.

2
  • inversecow, thanks for your response. Yes, you're right, but the problem is the storage capacity on server B due to the high amount of information that have to be passed. The idea is that the information pass from A to B and then from B to C, without using storage capacity in server B. For all of this reasons, I think that I should implement a ssh tunnel.
    – ehuarotop
    Aug 28, 2015 at 19:27
  • No need for intermediate storage or the delays of cron. Use rsync --rsh; see other answer. Sep 1, 2015 at 14:10
0

NFS solution

REFERENCE

http://www.tldp.org/HOWTO/NFS-HOWTO/server.html

IMPLEMENTATION

NodeC: enable NFS, create NFS share, set non-root permissions (RHEL 5.x in this example, other distros will be subtly different)

sudo /sbin/chkconfig portmap on
sudo /sbin/chkconfig nfs on
sudo /sbin/service portmap start
sudo /sbin/service nfs start

sudo chown "nobody:users"   /final/destination/share
sudo chmod 775 /final/destination/share

sudo vi /etc/exports
    /final/destination/share    NodeC_IP(rw)    NodeB_IP(rw)    
sudo /usr/sbin/exportfs -ra

NodeB: mount destination share automatically

sudo mkdir -p /transfer/share/name
sudo vi /etc/fstab
    NodeC_IP:/final/destination/share   /transfer/share/name    nfs defaults
sudo mount -a

NodeA: schedule an rsync job (15 min frequency in this example)

# manual method
/usr/bin/rsync -avzP --progress /transfer/share/local/ user@nodeB:/transfer/share/name/

# scheduled method
sudo crontab -e
    */15 * * * * /usr/bin/rsync -avzP --progress /transfer/share/local/ user@nodeB:/transfer/share/name/
1
  • While it may work, it involves a lot of overhead (nfs) and delays (cron). See my one-line answer using --rsh option to rsync. Aug 31, 2015 at 19:29
0

You can either make an explicit tunnel and use the port. But I find it more convenient to work with rsync directly as follows:

rsync -avzhe "ssh -A user@B ssh" ./src user@C:/dst

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .