Rendez-vous sur Arrakiss
Le 08/02/2020 à 17:01 dans /Logiciel-libre/OpenBSD/

Sauvegardes avec les outils présents dans la base d’OpenBSD

Sauvegarder : voilà un sujet dont on entend souvent parler. La plupart du temps, ça se finit à coup de rsync, borg ou je ne sais quel autre outil développé spécifiquement.

À l’occasion de la migration de la plateforme obsd4a.net vers openbsd.fr.eu.org, je me suis donné pour défi de réaliser les sauvegardes en n’utilisant que les outils présents de base dans une installation d’OpenBSD. Ainsi, je profite de tous les audits de sécurité réalisés par les développeurs.

Critères

La sauvegarde doit répondre aux critères suivants :

Outils utilisés

Les principaux outils seront tar, sftp (ssh) et les commandes shell comme find, cd, date

Utilisateur dédié

Les sauvegardes appartiendront à un utilisateur que l’on nommera bckpuser. Ce dernier pourra donc accéder aux sauvegardes afin de les copier sur une autre machine.

useradd -s /sbin/nologin -m bckpuser
passwd bckpuser # mot de passe hyper compliqué

Cet utilisateur ne doit rien pouvoir faire d’autre que des transferts via SFTP. On modifiera donc /etc/ssh/sshd_config :

Match User bckpuser
    ForceCommand internal-sftp
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    PasswordAuthentication no

Script de sauvegarde

Quelques explications sur le script de sauvegarde.

Voici le script utilisé pour créer les sauvegardes :

#!/bin/sh

U="bckpuser"
backupdir="/home/$U/"
src=/var/www/htdocs/
DATE=$(date "+%F")


cd "${backupdir}" || exit 1
for d in "${src}"/*; do
	backuptmpdir="${DATE}-$(basename ${d})"
	backupfile="${backuptmpdir}.tar.gz"

	# only backup changed files since 24h and put them in tar
	echo "New files to backup"
	find ${d} -mtime -1 | cpio -pdvu "${backuptmpdir}"

	if [ $? -eq 0 ]; then
		echo "archiving and compressing"
		tar -cvf "${backupfile}" "${backuptmpdir}"
		chown ${U}:${U} "${backupfile}"
	fi
	rm -r "${backuptmpdir}"
done
echo "delete old archives"
find "$backupdir" -iname "*.gz" -mtime +7 -delete

exit 0

Bonus avec MariaDB

Comme il y a une base de données, cette dernière est aussi archivé avec ces lignes :

. /etc/backup.cfg || exit 1

/usr/local/bin/mysqldump \
	--single-transaction \
  --opt \
  --user=${dbuser} \
  --password=${dbpassword} \
	"${dbname}" | gzip -9 > "${backupdir}/${DATE}-${dbname}.sql.gz"

if [ -e "${backupdir}/${DATE}-${dbname}.sql.gz" ]; then
	chown ${U}:${U} "${backupdir}/${DATE}-${dbname}.sql.gz"
fi

Le fichier /etc/backup.cfg contient les identifiants et mots de passes pour accéder à la base :

dbname="lalalala"
dbuser="db_utilisateur"
dbpassword="motdepasse"

Le dump de la base est gzippé pour gagner de la place.

Mais bon là, ce n’est plus tout à fait des outils “de base”…

Récupération des sauvegardes

Je récupère les sauvegardes sur différentes machines, notamment sur mon serveur perso, de façon automatique (toujours grâce à une tâche cron ou bien le fichier /etc/daily.local).

Le transfert se fait à l’aide d’SSH, ou plus précisément SFTP avec identification par jeu de clés, car ce dernier permet de reprendre les transferts incomplets.

On crée un jeu de clés sur la machine qui récupérera les sauvegardes :

ssh-keygen -t ed25519 -f $HOME/.ssh/bckp -a 64

On prend note du contenu du fichier $HOME/.ssh/bckp.pub afin d’en copier le contenu dans le fichier home/bckpuser/.ssh/authorized_keys sur le serveur à sauvegarder :

ssh-ed25519 erqhkrjlgqhlkgjqhklrgjqhklfqhg coco@machine

ATTENTION, ce fichier doit avoir les bonnes permissions :

# chmod 600 .ssh/authorized_keys
# ls -l .ssh/authorized_keys
-rw-------  1   bckpuser  313 Jan 28 18:53 .ssh/authorized_keys

Désormais, on peut créer un petit script pour récupérer les sauvegardes :

#!/bin/sh
mkdir -p /stock/bckp/
cd /stock/bckp/
sftp -b /home/batman/backup.batch \
	-i $HOME/.ssh/bckp \
	backupuser@serveur.tld
find . -mtime +7 -delete

Ce script crée un dossier /stock/bckp et s’y déplace afin d’y déposer les sauvegardes. Ensuite, la commande sftp lit un fichier backup.batch (on en repale juste après), on précise la clé d’identification à utiliser puis le nom d’utilisateur et le domaine du serveur à sauvegarder. Enfin, les vieux fichiers sont supprimés (facultatif).

Le fichier batch backup.batch contient toutes les commandes qui seront exécutées par sftp. Il ressemble à ça :

get -aR *
quit

La commande “get” avec ces options va chercher récursivement les sauvegardes et reprend les transferts précédents là où ils s’étaient arrêtés afin de ne pas retélécharger les anciennes archives. Ceci n’est pas possible avec un simple scp, voilà pourquoi on se sert du protocole SFTP.

Le manuel d’sftp vous donnera davantage d’informations.