diff --git a/backup_vaultwarden/.env.exemple b/backup_vaultwarden/.env.exemple new file mode 100644 index 0000000..8a1e463 --- /dev/null +++ b/backup_vaultwarden/.env.exemple @@ -0,0 +1,6 @@ +DATA_DIR= +LOCAL_BACKUP= +REMOTE_USER= +REMOTE_HOST= +REMOTE_DIR= +SSH_KEY= diff --git a/backup_vaultwarden/.gitignore b/backup_vaultwarden/.gitignore new file mode 100644 index 0000000..8814d50 --- /dev/null +++ b/backup_vaultwarden/.gitignore @@ -0,0 +1,3 @@ +.env + +backup.log diff --git a/backup_vaultwarden/README.md b/backup_vaultwarden/README.md new file mode 100644 index 0000000..f5795e1 --- /dev/null +++ b/backup_vaultwarden/README.md @@ -0,0 +1,116 @@ +# FONCTIONNEMENT DU SCRIPT VAULTWARDEN +Le script de backup de vaultwarden permet une sauvegard périodique des mots de passe et utilisateurs de celui-ci. + +## INITIALISATION DES VARIABLES DE MANIÈRE SÉCURISÉ + +1. Les informations sensibles ne sont pas stockées directement dans le script. Elles sont placées dans un fichier .env + +```bash +WEBHOOK_URL=... +REMOTE_USER=... +REMOTE_HOST=... +SSH_KEY=... +DATA_DIR=... +``` + +2. on recupere les varibales dans le script +```bash +REMOTE_USER=$(grep -E '^REMOTE_USER=' .env | cut -d '=' -f2-) +``` + +Explication: + +- grep recherche la variable dans le fichier .env +- cut récupère uniquement la valeur après = +- REMOTE_USER="user" Le script récupère >> "user" + +Cela permet: + +- d’améliorer la sécurité +- d’éviter de modifier le script si un paramètre change + +## RÉCUPÉRATION DES DONNÉES + +1. Le dossier data de Vaultwarden est dupliqué puis compressé afin de créer une archive : +```bash +tar -czf "$LOCAL_BACKUP" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" +``` + +2. Transfer vers le serveur de backup +```bash +scp "${SSH_OPTS[@]}" "$LOCAL_BACKUP" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" +``` +La sauvegarde est envoyée vers une machine dédiée grâce à SCP. Pour éviter de saisir un mot de passe à chaque fois, une clé SSH est utilisée. + +Cette clé SSH est générée sur la machine de backup et autorisée sur la machine Vaultwarden. + +## NOTIFICATION DISCORD + +Le script envoie une notification sur un salon Discord pour informer de l’état de la sauvegarde. Cela se fait grâce à un webhook Discord. + +1. on défini le message +```bash +local msg="**@here Backup Vaultwarden $color**\n" +msg+="Backup: ${BACKUP_NAME}\n" +msg+="Data transfer: $dumps_display\n" +[[ -n "$details" ]] && msg+="Details: $details" +``` + +2. on envoie le message sur discord avec le message et le webhook +```bash +curl -fsS -H "Content-Type: application/json" \ +-d "{\"content\":\"$msg\"}" \ +"$DISCORD_WEBHOOK_URL" +``` +Le message indique: + +- si la sauvegarde a réussi 🟢 +- si elle a échoué 🔴 +- le nom du backup +- les détails de l’erreur si nécessaire + +## PLANIFICATION AVEC CRON + +Le script est exécuté automatiquement chaque jour grâce à cron. + +1. Ouvrez le crontab pour l'édition : + ```bash + crontab -e + ``` +2. Ajoutez la ligne suivante pour exécuter le script tous les jours à 19h : +```bash + 0 19 * * * /chemin/vers/le/script/check_storage.sh +``` + +Signification: + +- 0 minute 0 +- 19 19h +- * tous les jours du mois +- * tous les mois +- * tous les jours de la semaine + +Tous les jours à 19h, le script est exécuté et les logs sont enregistrés dans backup.log ce qui permet d’analyser les erreurs si un problème survient. + +## NETTOYAGE + +Une fois la sauvegarde envoyée sur la machine distante, le fichier temporaire est supprimé : + +```bash +rm -f "$LOCAL_BACKUP" +``` + +Cela permet de garder le serveur propre et éviter de remplir le disque. + +## RÉSUMÉ + +Le script automatise complètement les sauvegardes Vaultwarden : + +- sauvegarde du dossier data +- compression et datation +- transfert sécurisé via SSH +- notification Discord +- exécution automatique avec cron +- sécurisation des paramètres via .env + +Cela permet d’avoir une sauvegarde quotidienne fiable et surveillée. diff --git a/backup_vaultwarden/backup-vaultwarden.sh b/backup_vaultwarden/backup-vaultwarden.sh new file mode 100755 index 0000000..5f92a05 --- /dev/null +++ b/backup_vaultwarden/backup-vaultwarden.sh @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +set -euo pipefail + +####################################### +# Chemins fixes du script +####################################### +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="/home/matt/vaultwarden/scripts/Scripts-Serveur/backup_vaultwarden/.env" +LOG_FILE="/var/log/vaultwarden_backup.log" + +mkdir -p "$(dirname "$LOG_FILE")" +touch "$LOG_FILE" + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" +} + +####################################### +# Vérification fichier .env +####################################### +[[ -f "$ENV_FILE" ]] || { + echo "ERROR: Fichier .env introuvable : $ENV_FILE" >&2 + exit 1 +} + +####################################### +# Chargement du .env +####################################### +set -a +source "$ENV_FILE" +set +a + +####################################### +# Variables obligatoires +####################################### +: "${WEBHOOK_URL:=}" +: "${DATA_DIR:?Variable DATA_DIR manquante dans .env}" +: "${LOCAL_BACKUP:?Variable LOCAL_BACKUP manquante dans .env}" +: "${REMOTE_USER:?Variable REMOTE_USER manquante dans .env}" +: "${REMOTE_HOST:?Variable REMOTE_HOST manquante dans .env}" +: "${REMOTE_DIR:?Variable REMOTE_DIR manquante dans .env}" +: "${SSH_KEY:?Variable SSH_KEY manquante dans .env}" + +####################################### +# Variables backup +####################################### +DATE="$(date +'%Y-%m-%d_%H-%M-%S')" +BACKUP_NAME="vaultwarden-backup-${DATE}.tar.gz" +LOCAL_BACKUP_DIR="$LOCAL_BACKUP" +LOCAL_BACKUP_FILE="${LOCAL_BACKUP_DIR}/${BACKUP_NAME}" + +SSH_OPTS=(-i "$SSH_KEY" -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout=10) + +mkdir -p "$LOCAL_BACKUP_DIR" + +####################################### +# Notification Discord +####################################### +discord_ping() { + local success="$1" + local details="${2:-}" + + [[ -z "$WEBHOOK_URL" ]] && return 0 + + local icon status_line + if [[ "$success" == "true" ]]; then + icon="🟢" + status_line="✅" + else + icon="🔴" + status_line="❌" + fi + + local msg + msg="**@here ${icon} Backup Vaultwarden**\n" + msg+="Backup: ${BACKUP_NAME}\n" + msg+="Data transfer: ${status_line}\n" + [[ -n "$details" ]] && msg+="Détails: ${details}" + + python3 - </dev/null || true +import json +print(json.dumps({"content": """$msg"""})) +PY +} + +####################################### +# Fonction erreur +####################################### +fail() { + local detail="$1" + log "ERROR: $detail" + discord_ping "false" "$detail" + exit 1 +} + +####################################### +# Vérifications préalables +####################################### +[[ -d "$DATA_DIR" ]] || fail "Le dossier source n'existe pas : $DATA_DIR" +[[ -f "$SSH_KEY" ]] || fail "La clé SSH est introuvable : $SSH_KEY" + +log "Début du backup Vaultwarden" +log "Source : $DATA_DIR" +log "Archive locale : $LOCAL_BACKUP_FILE" +log "Destination distante : ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}" + +####################################### +# Création du backup +####################################### +tar -czf "$LOCAL_BACKUP_FILE" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" \ + || fail "Erreur lors de la compression du dossier $DATA_DIR" + +####################################### +# Création dossier distant +####################################### +ssh "${SSH_OPTS[@]}" "$REMOTE_USER@$REMOTE_HOST" "mkdir -p '$REMOTE_DIR'" \ + || fail "Impossible de créer le dossier distant $REMOTE_DIR" + +####################################### +# Envoi du backup +####################################### +scp "${SSH_OPTS[@]}" "$LOCAL_BACKUP_FILE" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" \ + || fail "Erreur lors de l'envoi du backup vers $REMOTE_HOST" + +####################################### +# Nettoyage local +####################################### +rm -f "$LOCAL_BACKUP_FILE" || fail "Impossible de supprimer le backup local $LOCAL_BACKUP_FILE" + +####################################### +# Fin +####################################### +log "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR" +discord_ping "true" "Backup envoyé avec succès vers $REMOTE_HOST" +echo "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR"