Les deux méthodes d'accès distant de rsync et leurs limitations
Lors de la mise en place de synchronisations automatisées de données à l'aide de la célèbre commande de synchronisation incrémentale de fichiers rsync entre deux machines, il est bien entendu préférable de limiter ses accès à un répertoire particulier, si possible en lecture seule, pour limiter le nombre de fichiers pouvant être lues ou modifiés à distance.
rsync permet une connexion vers une machine distante (disposant également de
la commande rsync) soit à l'aide d'un shell distant (précisé par l'option
-e
/--rsh
de rsync
, et dont le rôle est d'ouvrir un canal de communication
entre les machines), soit en utilisant son daemon rsyncd.
La connexion utilisant un shell distant peut utiliser le shell SSH, qui permet le chiffrement des données transférées entre les machines. Cependant, seule la connexion via le daemon rsyncd permet nativement de limiter les accès distants aux fichiers d'un répertoire particulier (potentiellement en lecture seule), et ce daemon ne permet pas de chiffrer les données transférées.
Pour bénéficier des avantages de la connexion par SSH tout en ayant la
possibilité de limiter les accès à un répertoire (en lecture seule si on le
souhaite), il est possible de s'appuyer sur le script rrsync
fourni avec
rsync.
Il serait bien sûr également possible d'utiliser un tunnel SSH jusqu'à la machine
distante pour ouvrir une connexion chiffrée à un daemon rsyncd limité à
l'interface réseau locale de la machine, mais cette solution me semble
imparfaite et demander plus de maintenance que l'utilisation de rrsync
avec
SSH. Elle ne sera donc pas abordée ici.
Si l'on souhaite malgré tout utiliser rsyncd, la solution décrite ci-dessous
peut toutefois être facilement adaptée à l'utilisation d'un daemon rsyncd
(voir le manuel de rrsync
),
mais cet aspect n'est pas abordé ici.
Solution basée sur SSH et le script rrsync
La solution détaillée ici s'appuie sur la possibilité qu'offre OpenSSH de forcer l'exécution d'une commande, lors d'une connexion authentifiée à l'aide d'une clef SSH. Cette commande ou script ayant accès à la commande originale envoyée par le programme rsync distant, il peut la contrôler avant de l'exécuter ou non selon les fichiers que rsync tente de lire ou écrire.
Le script
rrsync
est un
script perl fourni avec les sources de rsync
. Sous les systèmes Debian, il
est fourni avec le paquet rsync sous le chemin
/usr/share/rsync/scripts/rrsync
, mais ce chemin peut bien entendu varier
selon votre système. Adaptez-le dans les instructions ci-dessous. Si votre
système ne fournissait pas ce script rrsync
, il est disponible sur la forge
du projet.
Notez que sous des versions de Debian plus anciennes, ce script était fourni
sous forme compressée sous le nom /usr/share/doc/rsync/scripts/rrsync.gz
. Il
était alors nécessaire de le décompresser et de l'installer dans un autre
répertoire.
Génération d'une clef SSH dédiée
En pratique, on commencera par générer une clef SSH dédiée à nos synchronisations de données sur la machine qui initie le transfert rsync (qu'on appellera machine1) et la copier sur la machine où se trouvent les données qu'on souhaite copier (on l'appellera machine2). On pourra générer cette clef avec une commande du type :
La commande ssh-keygen
ci-dessus va générer une nouvelle paire de clefs SSH
dont la partie privée sera écrite dans ~/.ssh/id_sauvegardes
et la partie
publique dans ~/.ssh/id_sauvegardes.pub
.
Copiez le contenu de ce fichier ~/.ssh/id_sauvegardes.pub
dans votre
presse-papiers ou soyez prêt à le transférer sur machine2, car il devra être
utilisé sur cette autre machine dans l'étape qui suit.
Forcer la commande exécutée sur la machine distante
On configure ensuite machine2 pour autoriser les connexions à l'aide de la
clef SSH qu'on vient de générer sur machine1, et en même temps forcer
l'utilisation de rrsync
lors des connexions authentifiées grâce à cette clef.
Pour cela, on va :
- éditer le fichier
~/.ssh/authorized_keys
du compte qu'on souhaite utiliser pour les synchronisations de fichiers sur machine2 pour ajouter sur une nouvelle ligne le contenu du fichier~/.ssh/id_sauvegardes.pub
de machine1 qu'on vient de générer ; - ajouter, au début de la même ligne que cette clef, une directive
command=
référençant la commanderrsync
qu'on souhaite forcer (séparer cette directive de la clef par une espace).
La ligne finale devrait ressembler à ceci :
command="/usr/share/rsync/scripts/rrsync -ro /srv/results" )
Notez que :
- sous Debian,
rrsync
est fourni comme script annexe sous le nom/usr/share/rsync/scripts/rrsync
utilisé ci-dessus, mais vous devrez probablement adapter ce chemin à celui utilisé sur votre système ; /srv/results
est ici le répertoire contenant les données auxquelles machine1 aura accès (adaptez-le bien entendu à vos besoins). L'accès à tout répertoire qui n'est pas descendant de celui-ci provoquera une erreur. (Si le répertoire fourni n'est pas un chemin absolu, il sera considéré comme relatif au répertoire personnel du compte utilisé) ;- notez que pour restreindre strictement l'accès aux fichiers sous
/srv/results
,rrsync
rejette par défaut les commandesrsync
utilisant l'option--copy-links
pour interdire la copie ou l'écriture de fichiers qui ne seraient sous/srv/results
(comme décrit dans la sectionSECURITY RESTRICTIONS
du manuel derrsync
manual (en anglais)). - l'option
-ro
est facultative et n'autorisera que les accès en lecture aux données de ce répertoire. On peut aussi la remplacer par l'option-wo
pour n'autoriser que les accès en modification (la lecture des fichiers sera alors interdite). Si aucune de ces options n'est présente, à fois la lecture et la modification des fichiers sera autorisée. rrsync
propose également les options-munge
,-no-del
,-no-lock
et-no-overwrite
décrites dans le manuel derrsync
(en anglais) qu'on ne détaillera pas ici.
Notez que, si le script rrsync
est installé dans un répertoire présent dans
la variable d'environnement PATH
utilisée par ce compte (par exemple
/usr/local/bin
), vous n'avez pas besoin de fournir son chemin complet dans la
directive command=
du fichier ~/.ssh/authorized_keys
, et vous pouvez
simplement utiliser command="rrsync -ro /srv/results"
. Il est toutefois plus
prudent d'utiliser le chemin complet pour éviter qu'un utilisateur malveillant
n'installe un script du même nom dans un répertoire plus prioritaire du PATH
et remplace ainsi la commande exécutée.
Si vous souhaitez renforcer la sécurité de cette connexion, vous pouvez
également utiliser l'option from=
de manière similaire à command=
pour
désigner une liste de machines depuis lesquelles la connexion utilisant cette
clef sera autorisée.
Pour plus de renseignements sur les options command=
ou from=
associés à
une clef SSH, reportez-vous à :
- l'article sur les options associées à une clef ssh ;
- à la section AUTHORIZED_KEYS FILE FORMAT du manuel
sshd(8)
(en anglais).
Lancement d'une synchronisation de fichier par rsync
Après avoir généré et autorisé la clef SSH comme décrit ci-dessus, le lancement du transfert rsync se fait quasiment comme d'habitude sur machine1, par exemple avec la commande :
L'option -e
de rsync
n'est ici utile que pour fournir l'option -i
à la
commande ssh
pour indiquer la clef (privée) à utiliser (le shell SSH est
utilisé automatiquement lorsque la source ou la destination des fichiers à
synchroniser est de la forme [utilisateur@]machine:/path
). Cette clef peut
bien sûr également être précisée à l'aide du fichier ~/.ssh/config
.