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/$(hostname -f)
# BorgBackup Mount-Ordner erstellen
mkdir -p /mnt/backups/borg/$(hostname -f)
# 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.


