In dieser Anleitung zeige ich, wem auch immer, wie man mit BorgBackup und dem BorgBackup-Wrapper Borgmatic, einen Ubuntu Webserver auf einen Backup-Server verschlüsselt backupt und wie das erstellte Backup auch fein wiederhergestellt werden kann. Dieser Backup-Stack funktioniert zum Beispiel auch sehr gut mit einer Storage-Box von Hetzner oder mit den hier vorgestellten Storage-Systemen. Selbstverständlich ist die Anleitung auch für andere Betriebtssysteme anwendbar.
Warum BorgBackup
Weil BorgBackup ein vom Betriebssystem unabhängiges, Open-Source (BSD) Backup-System ist, welches sehr effizient, verschlüsselt und performant, deduplizierende Backups erstellen kann. Nebenher gibt es noch unzählige Einstellungsoptionen, Borg wird kräftig weiterentwickelt und die Dokumentation ist aller erste Sahne.
Warum Borgmatic
Weil man hiermit BorgBackup um einiges leichter, schicker und schneller steuern kann. Es ist auch möglich geschwind verschiedene Backup-Profile anzulegen, die dann nur bestimmte Applikationen wie z. B. den Webserver oder die Datenbank absichern.
Ausgangsszenario
Für dieses derbe Unterfangen nehme ich einen bei Netcup schuftenden Ubuntu Webserver (RS 4000 G9) und peitsche das Backup über eine freshe SSH-Verbindung direkt auf meinen Hetzner Backup-Server (AX51).
Vorgaben
# Achtung Ficktive Daten :) # Backup-Programme: BorgBackup und Borgmatic # Backup-Patient: Ubuntu-20.04 Webserver (IP: 91.200.90.200 | hostname: betzi.true-og.de) # Backup-Server: Ubuntu-20.04 Fileserver (IP: 95.100.70.100 | hostname: fillissima.true-og.de) # Backup-Patient Ordnerstruktur: - /root/server-scripts/borg/ # Mysql Backupskript - /data/backups/db/ # Mysql Backupverzeichnis - /var/log/borg/ # BorgBackup/Mysql Logfileverzeichnis - /data/backups/borg/restore/$(hostname -f) # Ordner für den Backup-Restore - /mnt/backups/borg/$(hostname -f) # Ordner für den Mount eines Backups # Backup-Server Ordnerstruktur: - /data/backups/borg/$(hostname -f) # BorgBackup Silo
Installation und Konfiguration
Installation BorgBackup
# Auf Webserver und Backupserver ausführen apt install software-properties-common zstd add-apt-repository ppa:costamagnagianfranco/borgbackup aptitude update && aptitude install borgbackup liblz4-tool
Installation Borgmatic
# Borgmatic über Python Pip (da aktueller). Nur auf dem Webserver installieren! apt install python3-pip python3-setuptools pip3 install --upgrade pip pip3 install --upgrade borgmatic
Ordnerstruktur auf dem Webserver anlegen
# Ordner für die Borgbackup-Skripte erstellen mkdir -p /root/server-scripts/borg # Ordner für die Datenbank Backups erstellen mkdir -p /data/backups/db # BorgBackup Logfile-Ordner erstellen mkdir -p /var/log/borg # BorgBackup Restore-Ordner erstellen mkdir -p /data/backups/borg/restore # Berechtigung setzen find /root -type d | xargs -I {} chmod -v 700 {} && find /root/ -type f | xargs -I {} chmod -v 600 {} find /data/backups -maxdepth 1 -type d | xargs -I {} chmod -v 700 {}
Ordnerstruktur auf dem Backupserver anlegen
# Ordner für die Borgbackups erstellen mkdir -p /data/backups/borg/betzi.true-og.de # Berechtigung setzen find /data/backups -type d | xargs -I {} chmod -v 700 {}
SSH-Key auf dem Webserver erstellen
# Superstabilen SSH-Key mit elliptischen Kurven für die Übertragung auf dem Backupserver erstellen ssh-keygen -t ed25519 -o -a 100 -C "$(whoami)@$(hostname)-borg-$(date -I)" -f ~/.ssh/borg_id_ed25519 # Den superstabilen SSH-Key auf den Backupserver (fillissima.true-og.de) übertragen ssh-copy-id -i ~/.ssh/borg_id_ed25519.pub root@fillissima.true-og.de:33220
SSH-Berechtigung auf dem Backupserver anpassen
Damit man mit dem erstellten SSH-Key des Webservers keinen Schabernack auf dem Backupserver treiben kann, wird auf dem Backupserver die authorized_keys so angepasst, dass nur das Borgbackup-Kommando zum Managen der Backups erlaubt ist und das dafür vorgesehene Backupverzeichnis.
# /root/.ssh/authorized_keys command="borg serve --restrict-to-path /data/backups/borg/betzi.true-og.de" ssh-ed25519 AAAAC3Nz@C3lZDI1NTVE5ABLAIT.LWNcF3A77CrjdJY/oPpEd2IpZKmP7s5mQ7zrlTgmxT5 root@betzi.true-og.de-borg-2020-12-30
Borgmatic konfigurieren
In der Borgmatic-Konfiguration config.yaml, sollte man zumindest bei „repositories“ die IP-Adresse des Backupservers, die zu sichernden „source_directories„-Ordner, die zu exkludierenden Verzeichnisse (exclude_patterns), die Hooks und unter „storage“ den „encryption_passphrase“ anpassen.
Borgmatic-Konfiguration generieren:
generate-borgmatic-config
Inhalt Borgmatic-Konfiguration:
# Borgmatic config.yaml location: # Repository Pfad repositories: - root@95.100.70.100:/data/backups/borg/{fqdn} - root@99.100.70.100:/data/backups/borg/{fqdn} # Zusätzlicher Backup-Server wenn vorhanden # Backup Sources source_directories: - /etc - /usr - /opt - /srv - /var - /root - /home # Exclude Sources exclude_patterns: - /run - /sys - /dev - /tmp - /mnt - /proc - /var/run - /lost+found - /var/lib/lxcfs - /var/spool/dma - /data/backups/borg exclude_caches: true # Repository-Optionen storage: compression: auto,zstd # lz4 wenn zstd nicht vorhanden ssh_command: ssh -i /root/.ssh/borg_id_ed25519 -p 33220 relocated_repo_access_is_ok: true archive_name_format: '{fqdn}-{now:%Y-%m-%d_%H-%M}' encryption_passphrase: "zum-g0ld3nen.Spu<kn@pF!_" # Aufbewahrungszeitraum retention: keep_daily: 7 keep_weekly: 4 keep_monthly: 6 prefix: '{fqdn}-' # Backup-Validierung consistency: checks: - repository - archives check_last: 1 prefix: '{fqdn}-' # Farblicher Terminal output output: color: true # Aktionen hooks: before_backup: - echo "Das geile Borgmatic-Backup ist soeben gestartet:" - ping -q -c 1 95.100.70.100 > /dev/null || exit 75 - /root/server-scripts/borg/borgbackup_db.sh before_prune: - echo "Starting pruning: Mama wäre stolz auf dich." before_check: - echo "Starting Backup checks:" after_backup: - echo "Das sagenumwobene Borgmatic-Backup haben fertig. Fetter Respect dude!." after_prune: - echo "Finished pruning. Sauwa." after_check: - echo "Finished checks du krasser Checker." on_error: - echo "Irgendetwas ist derbe abgekackt ;(" # Berechtigung umask: 0077
Borgmatic Konfiguration validieren und Backupverzeichnis initialisieren
Die Validierung checkt die Borgmatic-Konfiguration auf Syntaxfehler durch und bei dem „borgmatic ini“-Befehl müsst ihr dann für das Backup-Repository (hier betzi.true-og.de) das hoffentlich ultrafiese Passwort aus der Borgmatic- Konfiguration (hier encryption_passphrase: „zum-g0ld3nen.Spu<kn@pF!_„) eingeben.
validate-borgmatic-config borgmatic init --encryption repokey-blake2
Mysql Datenbank Backupskript
Mit diesem duften Mysql Backupskript werden die Datenbanken einmal in separaten SQL-Files gespeichert und danach noch mal alle Datenbanken in ein einzelnes SQL-File geballert, damit man bei einem Datenmalheur je nach Situation trotzdem schön geschmeidig bleiben kann. PS: Das Mysql-Backupskript kann man auch sehr schön von BorgBackup enkoppelt als Standalone-Backupskript benutzen.
#========================================================== #!/usr/bin/env bash # Autor: Hackspoiler # Version: 0.9 # Shellcheck: True # Datum: 29.01.2020 # Modifizierung: 17.02.2024 # URL: https://hackspoiler.de # Skriptname: borgbackup_db.sh # Skriptpfad: /root/server-scripts/borg # Beschreibung: DBs werden in separate SQL-Files eingetütet plus alles zusammen in ein SQL-File. DB-Passwort wird aus .mylogin.cnf gezogen #========================================================== # Check for root permissions if [[ "$(id -u)" -ne 0 ]]; then echo "Requires root permissions" > /dev/stderr exit 1 fi # Set Bash-Defaults set -o nounset # Beenden, falls ein ungesetzter Variablenname verwendet wird set -o pipefail # Beenden, falls eine Pipeline fehlschlägt # Set Variables USER="root" RM="$(which rm)" TEE="$(which tee)" GREP="$(which grep)" FIND="$(which find)" XARGS="$(which xargs)" MKDIR="$(which mkdir)" MYSQL="$(which mysql)" MYSQLDUMP="$(which mysqldump)" COMPRESSION="gzip" #(bzip2|lz4|pigz|zstd) COMPRESSION_TYPE="gz" #(bz2|lz4|zst) LOG_DIRECTORY="/var/log/borg" LOG_FILE="${LOGDIRECTORY}/mysql_db_dump.log" TIMESTAMP=$(date +'%F-%H-%M-%S') BACKUP_DIR="/var/backups/db" ## Logging starten exec > >(tee --ignore-interrupts "${LOG_FILE}") 2>&1 # BACKUP_DIR + LOG_DIRECTORY erstellen "${MKDIR}" --parents "${LOG_DIRECTORY}" "${BACKUP_DIR}/${TIMESTAMP}" # Datenbanken älter als eine Stunde rasieren "${FIND}" "${BACKUP_DIR}"/ -mindepth 1 -type d -mmin +60 -print0 | "${XARGS}" -0 -I {} "${RM}" -rf {} # Datenbank-Backup starten DATABASES=$("$MYSQL" --user="$USER" --batch --skip-column-names -e "SHOW DATABASES;" | "$GREP" -E -v '^mysql$|^sys$|*_schema$') for DATABASE in ${DATABASES[@]}; do "${MYSQLDUMP}" \ --user="${USER}" \ --force \ --quote-names --dump-date \ --opt --single-transaction \ --events --routines --triggers \ --databases "${DATABASE}" \ --result-file="${BACKUP_DIR}/${TIMESTAMP}/${DATABASE}.sql" echo "Backup ${DATABASE} am ${TIMESTAMP} erstellt" done # Logging [[ ${STATUS} == 0 ]] && printf "Task am %s erfolgreich in %s erstellt\n" "$(date +'%F-%H-%M-%S')" "${BACKUP_DIR}" || printf "Task am %s gefailed\n" "$(date +'%F-%H-%M-%S')" # Backup der Datenbanken in ein ganzes, komprimiertes SQL-File echo "Drop Full DB Backup" "${MYSQLDUMP}" --user="${USER}" --all-databases --events --quick --routines --single-transaction --triggers | "${COMPRESSION}" > "${BACKUP_DIR}/${TIMESTAMP}/full_db.sql.${COMPRESSION_TYPE}"
Erstes Initiales Backup erstellen
borgmatic --verbosity 2 --log-file /var/log/borg/borgmatic.log
Backup verifizieren
borgmatic list borgmatic info
Cronjob einrichten
# vim /etc/cron.d/borgmatic # Jeden Tag um 01:00 Hur Nachts 0 1 * * * root /usr/local/bin/borgmatic --log-file /var/log/borg/borgmatic.log --syslog-verbosity 2
Logrotate einrichten
# Borgmatic Logrotate-Files (/etc/logrotate.d/borgmatic) /var/log/borg/*.log { rotate 4 weekly missingok notifempty compress delaycompress sharedscripts postrotate invoke-rc.d rsyslog rotate >/dev/null 2>&1 || true endscript }
Hier endet nun die komplette Installation und Konfiguration von BorgBackup und Borgmatic. Doch seid nicht traurig, im nächsten Abschnitt gibt es noch etwas zu den Themen „Backups wiederherstellen“ und „Backups manuell entfernen“.
Borgmatic Befehle
Backups wiederherstellen – Mount Version
# Alle vorhandenen Archive anzeigen borgmatic list # Zuletzt erstelles Backup-Archiv unter /mnt/backups/borg/$(hostname -f) mounten borgmatic mount --archive latest --mount-point /mnt/backups/borg/$(hostname -f) # Mount des angegebenen, kompletten Backups unter /mnt/backups/borg/$(hostname -f) borgmatic mount --archive $ARCHIVE_NAME --mount-point /mnt/backups/borg/$(hostname -f) # Nur einen speziellen Pfad des zuletzt erstellten Backups mounten borgmatic mount --archive latest --mount-point /mnt/backups/borg/$(hostname -f) --path etc/apache2/ # Backup-Mounts wieder entmounten borgmatic umount --mount-point /mnt/backups/borg/$(hostname -f)
Backups wiederherstellen – Extract Version
# Erstellen des Restore-Ordners mkdir -p /data/backups/borg/restore/$(hostname -f) # Vorhandene Backup-Archive anzeigen borgmatic list # Restore des aktuellsten kompletten Backups in das angegeben Restore-Verzeichnis borgmatic extract --archive latest --destination /data/backups/borg/restore/$(hostname -f) # Restore des angegebenen kompletten Backups in das Restore-Verzeichnis borgmatic extract --archive $ARCHIVE_NAME --destination /data/backups/borg/restore/$(hostname -f) # Restore der angegebenen Pfade (/etc und /usr) in das Restore-Verzeichnis borgmatic extract --archive $ARCHIVE_NAME --destination /data/backups/borg/restore/$(hostname -f) --restore-path /etc/ /usr/
Backups entfernen
# Repository-Pfad setzen REPOSITORY="root@95.100.70.100:/data/backups/borg/betzi.true-og.de" # Alle vorhandenen Backups auflisten borgmatic list # Beispiel-Archiv betzi.true-og.de-2021-01-21_22-55 Sun, 2021-02-21 22:55:15 # Gewünschtes Backup löschen borg delete ${REPOSITORY}::'betzi.true-og.de-2021-01-21_22-55' # Will man das ganze Repository endgültig entfernen (bei der Bestätigung "YES" groß schreiben!) borg delete ${REPOSITORY}
Repository Passwort ändern
# Repository Pfad setzen REPOSITORY="root@95.100.70.100:/data/backups/borg/betzi.true-og.de" # Repository-Passwort ändern borg key change-passphrase -v root@95.100.70.100:/data/backups/borg/betzi.true-og.de
Falls jemand Fragen, Anregungen oder Verbesserungsvorschläge hat, schreibt mir einfach auf Mastodon.