You might be thinking there is a typo in the rrsync
but it is actually a
legitimate command name. The command name comes from restricted rsync and
is usually distributed alongside rsync
via the package manager. Lets find
out where it is located on Arch Linux:
$ pacman -Fy && pacman -F rrsync
extra/rsync 3.2.3-3 [installed]
usr/lib/rsync/rrsync
It is clear that Arch ships rrsync
as a part of the rsync
package,
although its location is quite of a bummer as /usr/lib/rsync/rrsync
is
not place where one would usually look for executable files and this
location is not usually in a user's $PATH
variable, meaning that to run
it one must provide a full path to it. It is already correctly marked as
executable:
$ ls -l /usr/lib/rsync/rrsync
-rwxr-xr-x 1 root root 7467 Dec 30 2020 /usr/lib/rsync/rrsync
Yes, there is x
at the end of the first column. Alternatively, stat
can
be used as well:
$ stat -c '%A' /usr/lib/rsync/rrsync
-rwxr-xr-x
It's location is not a problem at all however, you won't be running it manually. Trying to do so ends with error:
$ /usr/lib/rsync/rrsync
/usr/lib/rsync/rrsync: No subdirectory specified
Use 'command="/usr/lib/rsync/rrsync [-ro|-wo] SUBDIR"'
in front of lines in /home/user/.ssh/authorized_keys
The error is actually pretty helpful as it hints to exactly what has to be done to make it work.
Generate a public key
On the receiving machine, generate a SSH key pair:
ssh-keygen -f ~/.ssh/rrsync_transfer -C "Transfer files between servers using rrsync"
When prompted for a passphrase, do not insert one. This is crucial for an
automated setup. Now get the public key file located at
~/.ssh/rrsync_transfer.pub
to the sourcing machine. This might be a
little tricky as there most likely isn't a direct connection between these
two servers/machines at this point, but there is usually a intermediate
local computer (the one you are working on right now) that can remotely
connect to both. Transferring the public key could look like this:
scp user@receiving:~/.ssh/rrsync_transfer.pub .
scp rrsync_transfer.pub user@sourcing:~/
There are many other ways to to this, even simple copy-paste from editor to
editor could be sufficient. In the end, the contents of the
rrsync_transfer.pub
should be present at the sourcing machine.
Authorized keys
The next step is to add the rrsync
reference from above to the
authorized_keys
file on the sourcing machine:
echo -n 'command="/usr/lib/rsync/rrsync -ro ~/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ' >> /home/user/.ssh/authorized_keys
If the file does not exist and terminal complains about it, create it first:
touch /home/user/.ssh/authorized_keys
The trailing whitespace is required there. Note that absolute path is used
here just to denote a user
. If already logged in as one, a relative path
can of course be used as well. Proceed by appending the public key just
after this command:
< rrsync_transfer.pub >> /home/user/authorized_keys
For the users unfamiliar with the above syntax, the redirection operator is
used to avoid the so called useless use of cat. Anyway, in the end, the
authorized_keys
file should have one of en the entries on the single line
that contains something like this:
command="/usr/lib/rsync/rrsync -ro ~/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAA...Vc= Transfer files between servers using rrsync
It should now be possible to rsync
files to the receiving machine from
the sourcing one like this:
rsync -e "ssh -i $HOME/.ssh/rrsync_transfer" -av user@sourcing: transferred-files/
Note that this method only works for non-root environments. To get it to work with root, for instance to do a periodic backup of a whole system (the way I usually use it), there are a few more steps required.
Using with root
To be able to access entire filesystem located at /
, first move the above
command="... ssh-rsa AAA...
entry from user's authorized_keys
file to a
one belonging to a root user. Please do not try to move the entire file,
unless you are absolutely sure it contains only the single entry discussed
above, otherwise, depending on the ssh configuration, you might decrease
the security of your system.
Now modify that line you just moved from the
/home/user/.ssh/authorized_keys
to the /root/.ssh/authorized_keys
and
change path from relative ~/
to the absolute /
like this:
command="/usr/lib/rsync/rrsync -ro /",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ssh-rsa AAA...Vc= Transfer files between servers using rrsync
The only difference is the missing ~
there, with /
making whole
filesystem reachable. The final requirement is to modify
/etc/ssh/sshd_config
file. Look for PermitRootLogin
, uncomment it and
change it's value to:
PermitRootLogin forced-commands-only
Here's where rrsync
or restricted rsync shines. Even though it is
accessing root filesystem, it cannot be used to damage the system this way,
as it can only read the files. The command to do the backup of the entire
filesystem could then look like this:
sudo rsync -e "ssh -i $HOME/.ssh/rrsync_transfer" -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} root@sourcing: filesystem-backup/
Make sure to change user@sourcing:
to root@sourcing:
. The above command
could be set up as a cron job, too!