'How to bind rsync to a specific interface?

I have a lot of interfaces configured in my server, each of which connect to a specific nic card and have a separate routing table. These interfaces can be identified by "netstat -a" command.

Now, I want to execute the rsync command connecting only to specific interface. I have this requirement because each of the interfaces will go through a separate tunnel/path and I want a particular rsync command to sync files through a specified tunnel.

Specifically, I want a way to specify the interface name.

Thanks, Mohan.



Solution 1:[1]

You can specify the address of the interface using --address=x.x.x.x on the command-line.

I don't think there is any way to specify the interface directly, but the ip command can tell you the address for an interface, so you could use something like this:

IP=$(ip -4 -br addr show eth0 | awk '{split($3,a,"/"); print a[1]}')
rsyncd ... --address=$IP

Edit For systems with the "real" iproute2 (anything not busybox-based, essentially), ip can produce JSON output which can be parsed a bit more sanely:

IP=$(ip -j -4 addr show wlo1 | jq .[0].addr_info[0].local)
rsyncd ... --address=$IP

Solution 2:[2]

I've written this little perl script to turn interface names to addresses, save it as iftoip (or similar)

#!/usr/bin/perl

use strict;
use warnings;
use IO::Interface::Simple;
use feature qw(say);

my $iface = shift;

my $if = IO::Interface::Simple->new($iface) or die "$!: $iface";
say $if->address;
exit 0;

You can do something similar with bash:

iftoip() {
  ip addr show $1 | grep inet | awk '{print $2}' | cut -d'/' -f1
}

just add the above 3 lines to ~/.bashrc and start a new shell or source ~/.bashrc

Running it produces:

v@juno:~$ iftoip ens33
10.251.17.94
v@juno:~$ iftoip ens34
192.168.78.128
v@juno:~$ echo "IP=$(iftoip ens33)"
IP=10.251.17.94
v@juno:~$ iftoip ens35 #perl
No such device: ens35 at /home/v/bin/iftoip line 10.

or

v@juno:~$ iftoip ens35 #bash
Device "ens35" does not exist.    

Solution 3:[3]

This has been tried using 2 interfaces, with different subnets and worked.

rsync -avzP -e 'ssh -b 10.100.16.X' /var/tmp/ent1 10.100.16.X:/var/tmp/;

rsync -avzP -e 'ssh -b 10.100.20.X' /var/tmp/ent2 10.100.20.X:/var/tmp/ ;

Solution 4:[4]

From client to server, over ssh use:

 rsync -avP -e 'ssh -b x.x.x.x' tmp/ server:tmp/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 cloned
Solution 4 Alberto