Borgbackup und Icinga

„Kein Backup – kein Mitleid“ – dieser weit verbreitete Spruch zeigt deutlich, wie wichtig ein Backup ist. Um Backups meiner Server und VM’s durchzuführen, verwende ich seit einiger Zeit das Tool borgbackup – welches bei vergleichsweise wenig Aufwand viele gute Features (Deduplikation, inkrementelles Backup, Kompression etc.) bietet.

Ein Backup ist aber nur so gut, wie es auch getestet und überwacht wird:

Ein Cronjob, einmal angelegt und dann vergessen, kann man relativ sicher als „kein Backup“ betrachten, genau so wie den MySQL-Dump, der – mangels Kontrolle – plötzlich 0 kB groß ist, wenn man ihn mal braucht. 

Um zumindest einen Teil – das anlegen der Backups – zu überwachen, bietet es sich an, dies mit einem Monitoringtool wie Icinga2 zu automatisieren.

Icinga ist bei mir im Einsatz, um den Status aller wichtiger Dienste zu überprüfen und Benachrichtigungen zu senden. Also auch, ob das letzte durchgeführte, erfolgreiche Backup im Zeitrahmen liegt.

Um das zu erreichen, wird nach jedem erfolgreichen Backup am Host das aktuelle Datum in eine Datei geschrieben: (Ausschnitt aus meinem Backupscript):

borg create -v --stats     			        \
    $REPOSITORY::'{now:%Y-%m-%d_%H:%M}'                 \
    /backupfolder						

if [ $? -eq 0 ]; then
	echo $(date) > /var/borgbackup/last_success
fi

Die /var/borgbackup/last_success sieht nach einem erfolgreichen Backup dann so aus:

Mon Dec 17 13:19:25 CET 2018

Analog passiert nichts, wenn borgbackup mit einem Fehler (Returncode != 0) beendet.

Diese Datei wird jetzt von einem weiteren Script abgefragt, mit der aktuellen Zeit verglichen und entsprechend ausgewertet:

#!/bin/bash
while getopts d:h: opts; do
   case ${opts} in
      d) BASE_DIR=${OPTARG} ;;
      h) HOURS=${OPTARG} ;;
   esac
done

# Read out file with date
file="$BASE_DIR/last_success"
fin=$(cat "$file")
# Calculate timestamp from string
fin_timestamp=`date --date="$fin" +"%s"`
now_timestamp=`date +"%s"`
# Calculate allowed difference in seconds
sec=$(expr $HOURS \* 3600)
# Debug output
echo "Last Backup finished: $fin ($fin_timestamp), now $now_timestamp, max $HOURS h ($sec)"
# Calculate compare timestamp
cmp=$(expr $fin_timestamp + $sec)
# Compare current timestamp with compare timestamp
if [ $cmp -gt $now_timestamp ] 
then
	echo "Backup okay"
	exit 0
fi

echo "Backup to old"
exit 2

Der Ablauf ist simpel: Aus obiger Datei wird der Unix-Timestamp erzeugt, dieser wird mit dem aktuellen Zeitstempel verglichen. Ist der Zeitstempel aus dem Backup länger als $HOURS Stunden her, beenden wir mit einem Fehler, sonst ist alles in Ordnung. Es gibt zwei Argumente: -h gibt die Stunden an, die das letzte Backup her sein darf, -d den Pfad, in dem die Datei gesucht wird.

Und zuletzt zur Host- bzw. Servicekonfiguration in Icinga:

apply Service "Last Borgbackup Check" {
  import "generic-service"

  check_command = "by_ssh"

  vars.backup_check = true
  vars.by_ssh_logname = "root"
  vars.by_ssh_command = "/etc/script/lastbackup"
  vars.by_ssh_arguments = {
    "-d" = host.vars.borgbackup
    "-h" = host.vars.backupint || 24
  }
  assign where host.vars.borgbackup
}

Die Prüfung erfolgt über SSH, wobei sich i.d.R. der User „nagios“ des Monitoring-Servers als root auf dem Zielserver anmeldet. Natürlich müssen entsprechende SSH- und Hostkeys ausgetauscht werden.

In der Hostkonfiguration muss dann noch die Variable „vars.borgbackup“ auf true gesetzt werden, sodass dieser Host für den Service Borgbackup aktiviert wird. Wenn ein anderes Backupintervall geprüft werden soll, kann dies ebenfalls im Host (vars.backupint) angegeben werden.

Ein Sicherheitsaspekt ist noch zu beachten: In dieser Konfiguration erfolgt der Login als Root – was nicht unbedingt sehr sicher ist. Daher sollte man entweder einen anderen Nutzer mit restriktiven Rechten wählen, oder mittels der SSH-Command-Option (command=“/etc/script/lastbackup“ *key*) in der authorized_keys die Rechte einschränken.

Nun hat man den Status seiner Backups durch Icinga überwacht – natürlich nur, ob sie durchgeführt werden. Um den korrekten Inhalt zu überwachen benötigt man noch andere Strategien.