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
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
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
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.
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
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:
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
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
connections authenticated using this key. In order to do so, we will:
- edit the file
~/.ssh/authorized_keyson 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.pubof host1 we've just generated;
- at the begin of this line, before the public key, add a directive
command=referring to the
rrsynccommand 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" )
- on Debian,
rrsyncis provided as an helper script under the path
/usr/share/rsync/scripts/rrsyncas used above, but you will probably have to adapt this path to the actual path of
rrsyncon your system;
/srv/resultshere 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
rrsyncwill by default reject
rsynccommands using the
--copy-linksoption to avoid copying a linked file that would be outside
/srv/results(as stated in the
SECURITY RESTRICTIONSsection of the
- the option
-rois optional and only allows read accesses to the files of the directory.
-wocan 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.
rrsyncalso provides the options
-no-overwritedescribed in the
rrsyncmanual 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
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
For more information on the options
from= associated to a SSH
key, please see:
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:
rsync here is necessary only to specify the option
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