ArraKISS
μ | 📰 | | 📧 |

    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 openbsd.fr.eu.org 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.