Outils pour utilisateurs

Outils du site


doc:formations:hebergement:serveur:sauvegarder

Sauvegarder son serveur

Via scaleway

Manuellement

On peut créer des sauvegardes à tout moment. Le nombre est illimité, mais on paye au stockage par minute, donc plus vous en aurez, plus cela deviendra significatif.

:!: les "bare metal" doivent être physiquement arrêtés pour pouvoir être backupés! Cela peut prendre 10-15 minutes à arrêter et le mmême temps pour être relancé (30 minutes de "down time" de votre serveur, pas forcément négligeable!)

Enfin, une image est une copie complète du disque. Elle est constituée de "snapshots" qui sont des copies des disques du serveur. Une image peut servir à recréer un serveur, et donc le migrer vers une offre "compute" plus puissante, de façon assez triviale!

On ne peut pas supprimer un "snapshot" si une image en dépend, il faudra d'abord effacer l'image (pensez à effacer les snapshots correspondants pour ne pas être facturé si elles n'ont plus de raison d'être).

Script d'automatisation pour scaleway

Ce script linux (à faire tourner sur un linux, ex. un serveur secondaire) peut vous permettre d'automatiser la création d'une image de sauvegarde d'un site scaleway.

script d'automatisation de sauvegarde chez scaleway, pour linux

Usage: ./scaleway_remote_backup.sh options…

Options

  • --token <API_TOKEN>: votre clé d'API ou un fichier qui la contient
  • --server <SERVER_NAME>: le nom du serveur scaleway à sauvegarder
  • --keyword <KEYWORD>: un mot clé qui identifie la sauvegarde

:!: une fois le backup créé, le script supprime tous les précédents backups qui ont le KEYWORD dans leur nom. Cela évite d'accumuler des images et snapshots indéfiniment.

Clé d'API "APITOKEN"

Le script a besoin d'une clé d'API, qu'il vous faudra générer sur le site de scaleway: User Account / Credentials / API Tokens.

:!: Cette clé donnera au script tout pouvoir de gestion de vos hébergement scaleway. La machine qui provoque la sauvegarde doit donc être particulièrement bien protégée, car si elle se fait pirater, le hacker pourra gérer tout votre compte scaleway, détruire des serveurs et créer 100 serveurs pour envoyer du spam (autant dire un gros carnage).

De ce point de vue je conseille deux options:

  • dédiez une instance scaleway minimale à 3$/mois pour ces taches administratives, et dont vous briderez l'accès sévèrement (ex. sur la console scaleway, via le pare-feu, ou vous pouvez même lui déconnecter l'IP externe quand vous n'avez pas de raison de vous y connecter!). Le serveur restera fonctionnel dans le "réseau local" de scaleway (IP locale en 10.x.y.z, pas publique).
  • utilisez un linux chez vous, qui lancera le travail! Un simple raspberry pi ou orangepi zero à 15€ suffit tout à fait. Ainsi votre clé reste chez vous, sur une machine sans accès externe.

Automatisation

Via une crontab sous linux, par exemple /etc/cron.d/scaleway_backups, le script étant sauvé sous /sbin/scaleway_remote_backup.sh:

PATH=/usr/sbin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin
# m  h     dom mon dow  user command
0    1      *   *   *   root scaleway_remote_backup.sh --token /etc/scw_api_key --server monserveur --keyword daily
0    2  1-31/14 *   *   root scaleway_remote_backup.sh --token /etc/scw_api_key --server monserveur --keyword weekA
0    2  7-31/14 *   *   root scaleway_remote_backup.sh --token /etc/scw_api_key --server monserveur --keyword weekB

Le fichier /etc/scw_api_key contient votre clé d'API scaleway (ex. d185cfa0-8d41-474c-fa21-2ff992d375a9). Pensez à lui faire un sudo chmod go-rwx /etc/scw_api_key afin de le rendre illisible pour tout autre utilisateur que root.

La première ligne sauve un backup du serveur monserveur qui sera nommé monserveur-daily tous les jours à 1h du matin (et élimine le précédent).

Les deux autres sauvent un backup toutes les deux semaines, et chacun valables deux semaines. Mais monserveur-weekA sera fait le 1er et le 14 du moins alors que monserveur-weekB se fera le 7 et le 21 du mois. Ainsi vous aurez la garantie d'avoir toujours un backup daté d'une semaine au moins (et deux semaines au plus). C'est important si jamais votre serveur est corrompu ou suite à une erreur de manipulation dont vous vous rendriez compte apres le backup journalier! Ce dernier est davantage utile si jamais le serveur "tombe" et ne répond plus (l'image peut servir à recréer un autre serveur).

Archivage et récupération distants via ssh

:!: ce sont ici des opérations manuelles, plus complexes qu'une image globale du serveur. Il y a deux intérêts particuliers:

  • garder un contrôle de la granularité (ex. sauvegarder des dumps de base de données, plus facile à manipuler)
  • pouvoir synchroniser/sauvegarder en dehors de scaleway (ex. sur une machine indépendante chez soi).

Ici, on travaille directement sur le serveur qui va recevoir les données (cible). Voyez la page SSH si vous ne l'avez pas encore fait!

Partie commune à la suite

On identifie la source distante ainsi que la date du moment:

source="root@source.com"         # identification de l'utilisateur et du serveur
now="$(date '+%Y%m%d-%H%M%S')"   # la variable $now contiendra la date du jour au format 20200307-140906
mkdir ~/backups/                 # on crée localement un dossier backups
cd ~/backups/

Pour vérifier que l'utilisateur local peut faire un "ssh" vers root@source.com, la commande:

ssh $source whoami

doit répondre ici root. Bien sûr on peut faire des variantes. Mais si on se loggue sur un utilisateur autre que root, ce qui est bien en terme de sécurité, alors il faudra que celui-ci aie des droit adéquats.

Si votre port SSH n'est pas le standard 22, vous pouvez spécifier ssh -p 21234 root@source.com. Si vous utilisez scp le paramètre est donné ainsi scp -P 21234 root@source.com:nomdufichier dest. Mais voyez plutôt comment simplifier cela avec un fichier .ssh/config.

Archive de dossiers

On peut créer une archive compressée du contenu d'un dossier de cette façon:

ssh $source "tar cvz /le/dossier/distant/"> "dossier-distant.tgz"

Plus utile, on peut automatiser les noms des dossiers à backuper ainsi (les / seront remplacé par un _):

src="/var/www"     # dossier *distant* qu'il faut archiver
ssh $source "tar cvz - -C "$src" ."> "dossier-$(echo $src|tr / _)-$now.tgz"

Note: l'option -C /var/www de tar retire la composante de base /var/www des fichiers et dossiers de l'archive: c'est généralement plus pratique que l'inverse, mais il faudra se souvenir de se mettre là ou vous voudrez que le contenu soit décompressé, par exemple cd /var/www; tar xvzf /chemin/vers/la/sauvegarde.tgz

:!: l'utilisateur utilisé sur le serveur distant (ici root!) doit avoir les droits nécessaires pour lire tous les dossiers et fichiers de $src. Si le contenu est détenu par divers utilisateurs et/ou avec divers droits, il reste bien utile d'utiliser un compte root.

Archive d'une base MySQL / MariaDB

On crée un fichier d'identification localement, par exemple mysql_remote.cnf et qui va contenir une identification admistrateur de la base distante (astuce: on peut recycler le login qui se trouve dans /etc/mysql/debian.cnf). Et on y met ce contenu:

[client]
user = debian-sys-maint
password = HtfLFDt43glqZuF3

Pensez à faire un chmod go-rwx mysql_remote.cnf afin de réduire la visibilité de ce fichier sensible!

Maintenant, pour "dumper" toutes les tables de la base de données distante (notez bien que le login se trouve sur la machine locale ici, transmis par ssh pour l'éxécution de la commande ssh sur le serveur à sauvegarder):

cat mysql_remote.cnf | ssh $source "mysqldump --defaults-extra-file=/dev/stdin --all-databases --single-transaction --quick --lock-tables=false | gzip"> "mysql-$now.sql.gz"

Si vous voulez ensuite "écraser" une base MySQL locale avec ce backup afin d'en faire un miroir, le mot de passe vous sera demandé dans le shell avec cette commande:

zcat dump.sql.gz | mysql -u root -p

Archive d'une base postgresql

Exemple:

db_name="inra_bdd"
ssh $source "cd /tmp; sudo -u postgres pg_dump '$db_name' | gzip"> "$db_name-$now.pgdump.gz"

Tout-en-un

On crée un script localement nommé /root/backup_de_distant.sh (avec un chmod +x /root/backup_de_distant.sh) et qui contient:

  #!/bin/bash
  echo "Backup entamé le $(date)"
 
  source="root@distant.com"
  now="$(date ' %Y%m%d-%H%M%S')"
  mkdir /home/backup_de_distant/
  cd /home/backup_de_distant/
 
  # Backup de certains dossiers (trois ici)
  for src in "/var/www" "/home" "/etc"; do
    ssh $source "tar cvz - -C "$src" ." > "dossier-$(echo $src|tr / _)-$now.tgz"
  done
 
  # Backup mysql (complet)
  ssh $source "cat /etc/mysql/debian.cnf | mysqldump --defaults-extra-file=/dev/stdin --all-databases --single-transaction --quick --lock-tables=false | gzip" > "mysql-$now.sql.gz"
 
  # Backup de bases postgresql explicites
  for db_name in "inra_bdd" "utilistateurs" "autre_bdd"; do
    ssh $source "cd /tmp; sudo -u postgres pg_dump "$db_name" | gzip" > "$db_name-$now.pgdump.gz"
  done
 
  # Enfin, on élimine les backups de plus de 15 jours:
  find /home/backup_de_distant/ -type f -name "*gz" -mtime 15 -print0 | xargs -r0 rm --
 
  echo -n "Backup terminé le $(date)"
  echo

Ce script doit etre rendu exécutable avec chmod x /root/backup_de_distant.sh, à modifier en fonction de vos besoins (quels dossiers, quelles bases…), et qui peut finalement être mis dans un "cron" afin de planifier des sauvegardes régulières (voyez ci-dessous comment faire)

PS: on a utilisé les identifiants de /etc/mysql/debian.cnf pour la connexion à SQL distant comme mentionné avant, et afin d'éviter de rapatrier le login MySQL distant sur le serveur local.

Miroir rsync

Contrairement aux archives que l'on a fait jusqu'ici, rsync est un outil de copie de fichiers qui est beaucoup plus rapide lorsqu'il y a de nombreux fichiers (ex. arborescence complète), car il ne copie que les changements détéctés sur les fichiers. On peut donc le faire tourner régulièrement pour "entretenir" une copie, sans que cela ne charge ni les serveurs ni la bande passante… excepté bien sûr la toute première fois où il fera une copie complète.

En effet, la copie de fichiers par scp ou sftp copient les fichiers même s'ils sont identiques: c'est inutile s'ils n'ont pas changé, ou si le changement ne nécessite pas une recopie complète (ex. changement de droit, ou de date d'accès au fichier…). Enfin non seulement rsync ne copie que ce qu'il faut, mais il peut aussi détruire sur la destination les fichiers qui ont été supprimés sur la source (avec l'option --delete): cela garantit un _miroir_ de l'arborescence distante et n'accumule pas des fichiers inutiles sur la cible.

A noter: ce n'est pas un bon moyen pour dupliquer une base de donnée, ou tout système qui repose sur des fichiers dynamiques et interdépendants. Dans ces cas-là il est préférable d'utiliser un "dump", comme nous l'avons fait ci-avant. Cela reste faisable si et seulement si l'on peut arrêter temporairementn ces services avant la copie (ex. service postgresql stop; rsync…; service postgresql start).

En bref: si le root local peut accéder au root distant, alors il maintiendra un miroir du /home distant dans un dossier local (y compris les droits) de cette façon:

rsync -a --delete root@distant:/home /home/miroir_du_home_de_distant

On peut aussi indiquer des fichiers ou dossiers à ignorer, voyez l'aide de rsync:

rsync -a --delete --exclude '/home/mysql'' root@distant:/home /home/miroir_du_home_de_distant

Note: rsync s'appuie sur le service SSH. Si le port utilisé n'est pas le 22 par défaut, il faudra lui indiquer de façon un peu compliquée, avec le paramètre -e "ssh -p 22123" par exemple. A la place, je vous conseille fort de configuer votre $HOME/.ssh/config pour lui donner les bonnnes valeurs par défaut (voyez le chapitre dédié à SSH).

Note: vous pouvez aussi passer par un utilisateur distant pour sécuriser davantage rsync, qui ne pourra pas directement faire n'importe quoi sur le serveur.

Note: sous windows, il existe un outil opensource et compatible avec rsync nommé DeltaCopy.

Note: ''trickle'' est un tout petit utilitaire intéressant pour limiter la bande passante utilisée par une commande, par exemple ainsi: trickle -s -u 5 -d 15 rsync … (limite les transferts montants à 5Ko/s et descendants à 15Ko/s).

rdiff: backup et miroir incrémental

On parle de backup incrémental lorsque l'on conserve plusieurs versions historiques des fichiers, tout en évitant de les dupilquer (cf "time capsule" sur MacOS). C'est généralement essentiel car les simples copies ne suffisent pas, puisqu'une erreur de manipulation à la source sera tot ou tard propagée vers ces miroirs.

On veut donc avoir plusieurs sauvegardes d'une source mais à des dates différentes.

L'approche naive consisterait bien sur à dupliquer l'ensemble des données sources et à les faire tourner, mais il est possible de faire bien plus efficacement. On effectue un premier backup complet, que l'on complète par des copies partielles et de plus en plus vieilles … mais qui ne contiennent que les différences avec le précédent backup. C'est donc beaucoup plus économe en espace disque (et en vitesse disque/réseau) que des sauvegardes complètes.

Le bel outil rsync couplé avec l'usage intelligent des liens matériels (hardlinks) permet déjà de créer manuellement des backups incrémentaux, comme ici.

Ces backups se trouvent chacun dans leur dossiers respectifs, et ils restent accessibles exactement comme le dossier maître. C'est parfois très intéressant pour en donner l'accès direct aux utilisateurs à travers un réseau, un NAS ou un point de montage en lecture seule par exemple.

rsnapshot

rsnapshot est un script perl intéressant, qui se base lui-même sur rsync afin de simplifier son usage en tant que moyen de faire des backups incrémentaux.

rdff-backup

Mais on va parler ici de rdiff-backup. Il dffère de l'approche rsync+hardlinks par le fait que ces données sont stockées dans un format interne, qui n'est donc pas accessible directement. L'intérêt reste notable puisque la place exigée par les backups incrémentaux est souvent bien moins grande (rdiff-backup ne stocke que les différence entre les fichiers, pas l'ensemble des fichiers qui diffèrent).

On peut créer un script comme ci-dessous, puis l'appeler depuis une crontab (ci-après):

rdiff-backup -v1 --print-statistics --max-file-size 10000000 /home/jeremie/ rdiff@serveur_de_backup.com:/home/rdiff/backup_rdiff
rdiff-backup -v1 --force --remove-older-than 4W rdiff@serveur_de_backup.com:/home/rdiff/backup_rdiff

Bien sur, l'idée est de placer ces deux lignes dans un crontab par exemple pour qu'il soit éxécuté à intervalles réguliers.

L'avantage de rdiff-backup est que rdiff-web vous permettra d'offir une interface web sur les sauvegardes incrémentales. Il devient très simple d'accéder simplement aux versions précedents de vos fichiers.

Nb: pensez à créer un utilisateur dédié aux seules opérations de copie (ci-dessus c'est rdiff@serveur_de_backup.com), et à le brider sur les opérations qu'il peut faire. On peut aussi passer par un utilisateur sudoer qui ne pourra lancer qu'un script dédié à la sauvegarde (exemple de script complet). Enfin, il peut etre aussi intéressant de mettre en place un tunnel SSH inverse, etc.

Automatisation via cron

Pour automatiser une tâche, on peut créer un "cron" localement, sous la forme d'un fichier /etc/cron.d/miroir_de_distant et appeler une fonction ou un script:

# 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 root@distant:/home /home/miroir_du_home_de_distant> /dev/null

# Lance un backup tous les 3 jours à minuit, et conserve un historique dans /var/log/backups.log
0   0 */3 * * root  /root/backup_de_distant.sh>> /var/log/backups.log

Voyez cette page pour plus d'information sur les cron.

doc/formations/hebergement/serveur/sauvegarder.txt · Dernière modification : 2023/11/23 20:31 de jeremie