====== Exemple de système de miroir (rsync+ssh) ======
Cet exemple utilise des fonctions relativement avancées de ''ssh''. Il existe des mécanismes plus simples sur [[doc:formations:hebergement:serveur:sauvegarder|cette page]], mais un peu moins sécurisés qu'ici.
Un considère un serveur source ''srvsrc'' (serveur distant à sauvegarder), et un serveur "local" de backup nommé ''srvbak''.
===== Utilisateur dédié =====
Sur le serveur source, on va créer un utilisateur dédié aux sauvegardes:
useradd backuper
mkdir -p /home/backuper/.ssh
Sur le serveur de backup, on va utiliser ''root'' pour effectuer les opérations de backup, principalement car c'est le seul à pouvoir définir les droits des fichiers qui vont être récupérés de ''srvsrc''.
Pour cela, on copie la clé SSH publique de root dans le ''/home/backuper/.ssh/authorized_keys'' et on finalise:
chown -R backuper:backuper /home/backuper
chmod -R go-rwx /home/backuper
=== sudoer ===
On va permettre à ''backuper'' d'exécuter ''rsync'' en "root", car on va avoir besoin de ces privilèges pour parcourir librement tout ''srvsrc'':
apt install sudo
Utiliser ensuite ''visudo'', ou mieux, créer un fichier spécifique:
echo 'backuper ALL=(ALL) NOPASSWD: /usr/bin/rsync' > /etc/sudoers.d/10-backuper
===== Planification "cron" =====
A ce stade, on peut simplement automatiser une sauvegarde presque complète de ''srvbak'' sur le système ''srvsrc'' ainsi.
* si ce n'est pas fait on ajoute la clé publique de ''root@srvbak'' à ''backuper@srvsrc:.ssh/authorized_keys''
* on crée sur ''srvbak'' le dossier qui sera le miroir: ''mkdir -p /home/srvsrc_miroir''
* on crée sur ''srvbak'' le fichier ''/etc/cron.d/backup_remote'' avec ce contenu:
# Chemins vers les exécutables (car crontab ne le fait pas)
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Lance un miroir à 3h45 tous les jours
45 3 * * * root rsync -a --delete --exclude /proc --exclude /run --exclude /dev backuper@srvsrc:/ /home/srvsrc_miroir > /dev/null
===== Renforcement: SSH utilisateur bridé sur une commande =====
Certes, la configuration sudo ci-dessus ne permet à l'utilisateur de n'éxécuter "en root" que la commande prévue. Ceci étant, il n'est pas souhaitable qu'il puisse se logguer pour faire autre chose que ce pour quoi il a été conçu (que ce soit en root ou non).
On va donc [[doc:formations:hebergement:serveur:ssh#restreindre_les_commandes_appelables|brider]] celles qu'il va pouvoir appeler en ajoutant ceci au début des lignes de ''/home/backuper/.ssh/authorized_keys'' de ''srvsrc'':
command="/home/backuper/backup.sh", ssh-rsa AAAAB3NzaC1yc2EAAA...H1tl root@srvbak
Cela signifie que lors de son appel SSH, l'utilisateur ne peut exécuter que cette commande !
Note: si l'appelant est sur une adresse IP connue on peut même brider la source de l'appel ainsi
from="11.22.33.44", command="/home/backuper/backup.sh", ssh-rsa AAAAB3NzaC1yc2EAAA...H1tl root@srvbak
Et enfin l'on crée ce script ''/home/backuper/backup.sh'' (toujours sur ''srvsrc''):
#!/bin/bash
fail() {
echo 'Rejected'
exit 1
}
# Caractères illégaux
echo "$SSH_ORIGINAL_COMMAND" | grep -q '[&;]' && fail
# On oblige à donner des chemins ancrés sur la racine du site
echo "$SSH_ORIGINAL_COMMAND" | tr "\t" ' ' | grep -q ' /[^ ]*$' || fail
# On injecte la liste des exclusions et on vérifie au passage que c'est bien un rsync
cmd=$(echo "$SSH_ORIGINAL_COMMAND" | sed -n 's|^rsync --server|rsync --server --exclude-from /home/backuper/backup-forbid.txt|p')
[[ -z "$cmd" ]] && fail
# Exécution en root
sudo $cmd
...que on le rend exécutable avec ''chmod +x "/home/backuper/backup.sh''
Enfin, il faut créer le fichier des exclusions ''/home/backuper/backup-forbid.txt'' avec ce contenu, par exemple:
/tmp
/sys
/proc
/run
/dev
cache
*.tgz
*.tar.gz
*.zip
Note: on fait un peu de zèle ici dans ce script, mais qui illustre un moyen de brider les commandes et données gérables par l'appelant, ainsi que l'injection d'arguments dans le ''rsync'' (ici, l'exclusion des dossiers non sauvegardables sur le serveur, ''/sys'', ''/proc'', ''/run'' et ''/dev'' ainsi que divers fichiers et dossiers). Même sans les spécifier lors du rsync, ces options seront utilisées (car "injectées" de force avec le ''sed'' ci-avant).
==== Usage ====
Depuis le serveur de backup ''srvbak'', on exécute un ''rsync'' en root via un simple appel à l'utilisateur dédié sur le serveur source, par exemple:
mkdir backups
rsync -a --progress --delete backuper@srvsrc:/var/www backups/20200225-www
Vu le script d'interception ci-avant, une commande de ce type échouera (source non ancrée à la racine du site):
rsync -a backuper@srvsrc:../ /tmp
Nb: l'option ''-a'' conserve les noms et propriétés des fichiers, l'option ''%%--%%progress'' affiche ce qui se passe, et l'option ''%%--%%delete'' surpprime de la destination les fichiers qui ont disparu de la source. Le résultat est un //miroir// de la source (hormis les fichiers et dossiers ignorés bien entendu).