Skip to main content

Vaultwarden Backup / Restore Scripts

Das Backup-Script kann per Crontab täglich ausgeführt werden: 

0 0 * * * /scripts/vaultwarden-daily-backup-encrypt.sh

Verwendet wird Docker und einer SQLite DB. Alle Dateien liegen im Vaultwarden Ordner.

#####---#####

Verschlüsseltes Backup erstellen

Anpassung bitte vornehmen: CONTAINER, CONTAINER_DATA_DIR, SQLITE_DB, PASSPHRASE_FILE

die PASSPHRASE Datei vorher anlegen und das Kennwort hinterlegen im Pfad /root/.xy/passphrase (Klartext)

vaultwarden-daily-backup-encrypt.sh

#!/bin/bash

# Set the script to exit immediately if any command fails
set -e

DATE=$(date +%d-%m-%Y)
BACKUP_DIR=/mnt/xyz
BACKUP_FILE=vaultwarden-$DATE.tar.gz
ENCRYPTED_BACKUP_FILE=vaultwarden-$DATE.tar.gz.gpg
CONTAINER=vaultwarden
CONTAINER_DATA_DIR=/vaultwarden-datafolder
SQLITE_DB=/vaultwarden-datafolder/db.sqlite3
PASSPHRASE_FILE=/root/.xy/passphrase

# create backups directory if it does not exist
mkdir -p $BACKUP_DIR
#mkdir -p $SQLITE_BACKUP_DIR

# Stop the container
/usr/bin/docker stop $CONTAINER

# Backup the vaultwarden data directory to the backup directory
tar -czf "$BACKUP_DIR/$BACKUP_FILE" -C "$CONTAINER_DATA_DIR" .

# Encrypt the backup file with gpg using the passphrase from the file
gpg --batch --passphrase-file "$PASSPHRASE_FILE" --symmetric --cipher-algo AES256 -o "$BACKUP_DIR/$ENCRYPTED_BACKUP_FILE" "$BACKUP_DIR/$BACKUP_FILE"

# Optionally, remove the unencrypted backup file
rm "$BACKUP_DIR/$BACKUP_FILE"

# backup sqLite Datenbank
#sqlite3  "$SQLITE_DB" "VACUUM INTO '$SQLITE_BACKUP_DIR/$SQLITE_BACKUP_FILE'"
#sqlite3 "$SQLITE_DB" .dump > "$SQLITE_BACKUP_DIR/$SQLITE_BACKUP_FILE"

# Restart the container
/usr/bin/docker start $CONTAINER

# To delete files older than 30 days
find $BACKUP_DIR/* -mtime +30 -exec rm {} \;

#####---#####

Verschlüsseltes Backup wiederherstellen

vaultwarden-restore-backup.sh

Anpassungen bei folgenden Variablen vornehmen: CONTAINER, CONTAINER_DATA_DIR, SQLITE_DB, PASSPHRASE_FILE

Das Script fragt den Passphrase ab, wenn dieser nicht im Ordner verfügbar ist

#!/bin/bash

# Set colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Set the script to exit immediately if any command fails
set -e

SOURCE_DIR="/mnt/backupfolder"
PASSPHRASE_FILE="/root/.xy/passphrase1"
DEST_DIR="/vaultwarden-data"

# Ensure the destination directory exists
mkdir -p "$DEST_DIR"

echo -e
echo -e
echo -e 
echo -e "${RED}!!! WARNUNG: UNBEDINGT DIE PFADE IM SCRIPT ANPASSEN; SOURCE_DIR & DEST_DIR !!!.${NC}"
echo -e
echo -e
echo -e

# Function to prompt for passphrase with asterisks
prompt_passphrase() {
    echo -e "${YELLOW}Bitte geben Sie die Passphrase für die Entschlüsselung ein:${NC}"
    echo -n "Passphrase: "
    stty -echo  # Turn off echoing
    read PASSPHRASE  # Read input silently
    stty echo  # Turn on echoing
    echo  # Move to a new line after the password input
}

# Check if the passphrase file exists and is readable
if [ -f "$PASSPHRASE_FILE" ] && [ -r "$PASSPHRASE_FILE" ]; then
    PASSPHRASE_OPTION="--passphrase-file $PASSPHRASE_FILE"
else
    echo -e "${RED}Warnung: Die Passphrase-Datei $PASSPHRASE_FILE ist nicht vorhanden oder nicht lesbar.${NC}"
    prompt_passphrase
    PASSPHRASE_OPTION="--passphrase '$PASSPHRASE'"
fi

# Print header for the date selection
echo -e "\n${GREEN}Wählen Sie ein Datum für das zu entpackende Archiv:${NC}\n"

# Generate numbered list of dates
DATES=($(ls "$SOURCE_DIR" | grep -oP '\d{2}-\d{2}-\d{4}' | sort | uniq))
for ((i=0; i<${#DATES[@]}; i++)); do
    echo -e "[${YELLOW}$((i+1))${NC}] ${DATES[i]}"
done

# Prompt user to select a date
while true; do
    read -p "Geben Sie die Nummer des gewünschten Datums ein: " CHOICE
    if [[ ! $CHOICE =~ ^[0-9]+$ ]]; then
        echo -e "${RED}Fehler: Bitte geben Sie eine gültige Nummer ein.${NC}"
    elif (( CHOICE < 1 || CHOICE > ${#DATES[@]} )); then
        echo -e "${RED}Fehler: Ungültige Auswahl. Bitte geben Sie eine Nummer innerhalb des angegebenen Bereichs ein.${NC}"
    else
        DATE="${DATES[CHOICE-1]}"
        echo -e "Gewähltes Datum: ${GREEN}$DATE${NC}"
        break
    fi
done

ENCRYPTED_BACKUP_FILE="vaultwarden-$DATE.tar.gz.gpg"
DECRYPTED_BACKUP_FILE="vaultwarden-$DATE.tar.gz"

# Check if the encrypted backup file exists
if [ ! -f "$SOURCE_DIR/$ENCRYPTED_BACKUP_FILE" ]; then
    echo -e "${RED}Fehler: Die verschlüsselte Datei $SOURCE_DIR/$ENCRYPTED_BACKUP_FILE existiert nicht.${NC}"
    exit 1
fi

# Decrypt the backup file
gpg --batch $PASSPHRASE_OPTION -o "$SOURCE_DIR/$DECRYPTED_BACKUP_FILE" -d "$SOURCE_DIR/$ENCRYPTED_BACKUP_FILE"
if [ $? -ne 0 ]; then
    echo -e "${RED}Fehler: Entschlüsselung der Datei $SOURCE_DIR/$ENCRYPTED_BACKUP_FILE fehlgeschlagen.${NC}"
    exit 1
fi

# Extract the decrypted tar.gz file
tar -xzf "$SOURCE_DIR/$DECRYPTED_BACKUP_FILE" -C "$DEST_DIR"
if [ $? -ne 0 ]; then
    echo -e "${RED}Fehler: Entpacken der Datei $SOURCE_DIR/$DECRYPTED_BACKUP_FILE fehlgeschlagen.${NC}"
    exit 1
fi

# Optionally, remove the decrypted tar.gz file after extraction
rm "$SOURCE_DIR/$DECRYPTED_BACKUP_FILE"

echo -e "${GREEN}Entschlüsselung und Entpacken abgeschlossen. Dateien befinden sich in $DEST_DIR.${NC}"