The two methods of rsync remote access and their limitations
When setting up automatic data synchronisations using the well-known file synchronization command rsync between two remote hosts, it is naturally better to restrict rsync accesses to a specific directory, if possible in read-only mode, to limit the number of files that can be read or modified remotely.
rsync allows for a connection to a remote host (where the rsync command is
also installed) either using a remote shell (specified using the -e
/--rsh
option of rsync
, and whose role is to open a communication channel between
the hosts), or using its daemon rsyncd.
The remote shell connection method can use the SSH shell that enables the encryption of data transferred between the hosts. However, only a connection to a rsyncd daemon and its protocol can natively restrict remote rsync accesses to a specific directory (potentially in read-only mode), and this daemon cannot encrypt the data being transferred.
To benefit from the advantages of a SSH connection while still have the
possibility to limit accesses to a directory (in read-only mode if we want it
so), we have the possibility to rely on the helper script rrsync
provided by
the rsync
software.
It is naturally also possible to use a SSH tunnel to the remote host to open
an encrypted connection to a rsync daemon restricted to the local network
interface of the host, but this solution seems rather imperfect in my opinion
and requiring more maintenance than the use of SSH and rrsync
. This will
therefore not be covered here.
If one still wished to use rsyncd, please note that the solution presented
below can be easily adapted to the use a rsyncd daemon (see the manual for
rrsync
), but this aspect
won't be covered here either.
Solution based on SSH and the rrsync
script
The solution detailed here relies on the possibility offered by OpenSSH to force the execution of a command when opening a connection authenticated by a SSH key. The command or script having access to the original command sent by the remote rsync program, it has the ability to control it before deciding upon its execution based on the files that rsync is trying to read or write.
The script
rrsync
is a perl
script provided with the source of the rsync
software. On Debian systems, it
is provided by the rsync package as /usr/share/rsync/scripts/rrsync
, but on
other systems the path can obviously vary. Please adapt the actual path in the
examples below. If your system does not provide this script rrsync
, note that
it is available on the rsync project
forge.
Also note that on older Debian versions, this script was provided in a
compressed form as /usr/share/doc/rsync/scripts/rrsync.gz
. It therefore had
to be uncompressed and installed in another directory.
Generating a dedicated SSH key
In practice, we'll begin by generating a SSH key dedicated to our file synchronisations on the host that initiates the rsync transfer (which we will name host1) and copy it to the host where are located the files we want to copy (we'll name it host2). This key can be generated using a command of the following type:
The command ssh-keygen
above will generate a new SSH key pair whose private
key will be written to ~/.ssh/id_backups
and the public key to
~/.ssh/id_backups.pub
.
Copy the content of the public key file ~/.ssh/id_backups.pub
to your
clipboard, or be ready to transfer it to host2, as it will be used on this
host in the next step.
Force the command executed on the remote host
We now configure host2 to authorize connections using the SSH key we've just
generated on host1 and at the same time force the use of rrsync
in
connections authenticated using this key. In order to do so, we will:
- edit the file
~/.ssh/authorized_keys
on the account we want to use in file synchronizations on host2 and on a new line with the content of the file~/.ssh/id_backups.pub
of host1 we've just generated; - at the begin of this line, before the public key, add a directive
command=
referring to therrsync
command we want to force (separate this directive from the key by a space).
The line to add to the file ~/.ssh/authorized_keys
should look like this:
command="/usr/share/rsync/scripts/rrsync -ro /srv/results" )
Note that:
- on Debian,
rrsync
is provided as an helper script under the path/usr/share/rsync/scripts/rrsync
as used above, but you will probably have to adapt this path to the actual path ofrrsync
on your system; /srv/results
here is the directory that holds the files host1 will have access to (don't forget to adapt it to your own needs). Accesses to any file or directory not under this directory will return an error. (If the provided directory isn't an absolute path, it will be considered relative to the homedir of the account used on host2.)- note that in order to restrict accesses to files under
/srv/results
,rrsync
will by default rejectrsync
commands using the--copy-links
option to avoid copying a linked file that would be outside/srv/results
(as stated in theSECURITY RESTRICTIONS
section of therrsync
manual). - the option
-ro
is optional and only allows read accesses to the files of the directory.-wo
can be used instead to only allow write-only accesses to these files (read accesses would then be denied). If none of these options are specified, both read and write accesses are allowed. rrsync
also provides the options-munge
,-no-del
,-no-lock
and-no-overwrite
described in therrsync
manual but we won't detail them here.
Note that, if the script rrsync
is installed in a directory included in the
PATH
environment variable used by the account (for example /usr/local/bin
),
you won't need to use its absolute path in the directive command=
of the file
~/.ssh/authorized_keys
, and you could simply use command="rrsync -ro /srv/results"
. It is however more cautious to use the full path of the script
to avoid a malicious user installing a script of the same name in a directory
with higher priority in PATH
that would thus replace the executed command.
Should you want to further increase the security of this SSH connection, you
could use the option from=
similarly to command=
to define a list of hosts
allowed to connect to the account using the corresponding SSH key (see the note
below.)
For more information on the options command=
or from=
associated to a SSH
key, please see:
- the article on options associated to SSH keys ;
- the section AUTHORIZED_KEYS FILE FORMAT of the
sshd(8)
manual.
Running the file synchronization
After having generated and authorized the SSH key as described above, the rsync transfer can be run mostly as usual, for example using the command:
The option -e
of rsync
here is necessary only to specify the option -i
to
the ssh
command to specify the (private) key to use (the SSH shell is used
automatically whenever the source or destination of files to synchronise has the form
[user@]host:/path
). This key can naturally also be specified using the user
configuration file for SSH ~/.ssh/config
.