NAS mit ODROID-HC4 - Teil 2: Borg
Mit dieser Artikelserie soll das Einrichten eines kleinen, günstigen NAS erläutert werden. Linux basierte Clients im Haushalt sollen darauf ihre Backups ablegen. Damit eine defekte NAS-Festplatte keinen Daten-GAU verursacht, werden die Daten per RAID1 gespiegelt. Der generische Ansatz (kein Fertigsystem) soll uns dabei helfen, auch andere Wünsche an das NAS zu erfüllen, wie z. B. ein Calibre Server.
Es sind folgende Teile geplant:
- Hardware und Betriebssystem
- Backups mit Borg
- Calibre Server
- Samba Server
Subvolume @backup
Um das RAID auch für andere Datenhaltungsaufgaben zu verwenden und diese sauber voneinander zu trennen, erstellen wir ein Subvolume, dediziert für unsere Backups:
# mount /dev/sda /mnt
# btrfs subvolume create /mnt/@backup
# umount /mnt
Damit das Subvolume automatisch eingehängt wird, erstellen wir noch das Verzeichnis /srv/backup und fügen folgenden Eintrag in /etc/fstab
hinzu:
[…]
/dev/sda1 /srv/backup btrfs defaults,nofail,noatime,compress=zstd,subvol=@backup 0 0
Die Optionen können natürlich nach Belieben modifiziert werden. Ich habe mich für eine Kompression mittels des zstd-Algorithmus entschieden. nofail
bewirkt, dass das System auch startet, wenn es beim Einhängen Probleme gibt.
Wenn man sich einen Reboot ersparen will, mountet man das Subvolume nun einfach einmalig mit mount /srv/backup
(als root).
Borg Backup
Nach Installation des Pakets borgbackup erstellen wir einen User borg, dem die Backupdaten auf dem NAS gehören und gegen den sich die Borg-Clients authentifizieren.
# useradd -m borg
Natürlich wollen wir, dass borg der Owner für die Backups ist:
# chown borg:borg /srv/backup
Falls noch nicht geschehen, erstellen wir jetzt auf den Clients, von denen wir Backups erstellen möchten, SSH-Schlüssel für root (ssh-keygen
). Für root deshalb, weil je nach Backupzweck Zugriff auf Systemdaten oder die Daten anderer Benutzer notwendig ist. Die public keys speichern wir alle in der Datei ~/.ssh/authorized_keys von borg.
Um den Schaden zu begrenzen, falls Clients kompromittiert werden, kann man die erlaubten Kommandos für borg einschränken. Hierzu ist für jeden SSH-Key in authorized_keys z. B. folgendes voranzustellen:
command="borg serve --restrict-to-path /path/to/repo",restrict ssh-rsa AAAAB3[...]
Von den Clients aus können wir nun je ein borg-Repository erstellen, in dem dann die Backups landen:
# borg init -e repokey borg@droidnas:/srv/backup/`hostname`
Nun ist alles bereit für das Erstellen von Backups. Die Borg-Dokumentation erläutert hierzu mannigfaltige Möglichkeiten. Ich möchte hier kurz mein Backup-Skript vorstellen, das es erlaubt, Backups von /home
und vom System (ohne home) zu machen. Die Systeme sind bei mir so eingerichtet, dass sie auch Btrfs als Dateisystem verwenden und separate Subvolumes für /
und für /home
verwenden. Mittels Snapshots wird vermieden, dass Änderungen von Dateien während des Backups zu inkonsistenten Zuständen führen. Darauf kann man natürlich auch verzichten, und muss bei den Backups eben entsprechend umsichtig vorgehen. Hier jedenfalls mein derzeitiges Backup-Skript:
#!/bin/bash
export BORG_REPO=ssh://borg@droidnas:22/srv/backup/`hostname`
export DATETIME=`date +%Y%m%d-%H%M%S`
export BORG_PASSPHRASE='HierMeinKomplexesPasswort'
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
backup_home() {
export SNAPSHOT_PATH=/home/.snapshots/home-$DATETIME
BACKUP_PATH=/mnt/backup-home
info "Starting backup of home dirs"
btrfs subvolume snapshot -r /home $SNAPSHOT_PATH
sync
mount --bind $SNAPSHOT_PATH $BACKUP_PATH
cd $BACKUP_PATH
# Backup the home directories
borg create \
--progress \
--stats \
--compression zstd \
--exclude-caches \
--exclude '*/.cache/*' \
\
::"home-$DATETIME" \
* \
cd /tmp
#echo "Deleting snapshot"
umount $BACKUP_PATH
btrfs subvolume delete $SNAPSHOT_PATH
info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS home backup. The 'home-' prefix is very important to
# limit prune's operation to these archives and not apply to
# other archives also:
borg prune \
--list \
--prefix 'home-' \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
}
backup_system() {
export SNAPSHOT_PATH=/.snapshots/system-$DATETIME
BACKUP_PATH=/mnt/backup-system
info "Starting backup of system dirs"
btrfs subvolume snapshot -r / $SNAPSHOT_PATH
sync
mount --bind $SNAPSHOT_PATH $BACKUP_PATH
cd $BACKUP_PATH
# Backup the system directories
borg create \
--progress \
--stats \
--one-file-system \
--compression zstd \
--exclude-caches \
--exclude 'root/.cache' \
--exclude 'dev' \
--exclude 'proc' \
--exclude 'sys' \
--exclude 'var/run' \
--exclude 'lost+found' \
\
::"system-$DATETIME" \
. /boot \
cd /tmp
#info "Deleting snapshot"
umount $BACKUP_PATH
btrfs subvolume delete $SNAPSHOT_PATH
info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS system backup. The 'system-' prefix is very important
# to limit prune's operation to these archives and not apply to
# other archives also:
borg prune \
--list \
--prefix 'system-' \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6
}
usage() {
echo "usage: backup_borg.sh [-t [home | system]] | [-h]"
}
## MAIN
bkuptape=""
while [ "$1" != "" ]; do
case $1 in
-t | --type ) shift
bkuptype=$1
;;
-h | --help ) usage
exit
;;
* ) usage
exit 1
esac
shift
done
if [ "$bkuptype" == "home" ]; then
backup_home
elif [ "$bkuptype" == "system" ]; then
backup_system
else
usage
fi
Mittels backup_borg.sh -t system
oder backup_borg.sh -t home
(mit root-Rechten) können nun Backups vom System- oder vom Home-Subvolume gemacht werden. Das Skript kann beliebig angepasst oder erweitert werden, etwa wenn vorab noch Datenbanksysteme gestoppt werden sollen o. ä.
Teil 3 der Artikelserie ist etwas spezieller und richtet sich an die E-Book Leser. Das NAS soll dann den Nutzern des Heimnetzes die geballte E-Book-Sammlung präsentieren. Somit können direkt über den Browser der E-Reader die Bücher auf die Geräte geladen werden, ohne ein USB-Kabel in die Hand zu nehmen.