blog_hero_Een Zabbix backup nemen

Een Zabbix backup nemen

Aug 30 2023

Wat kunnen we allemaal updaten?

Zabbix bestaat uit verschillende onderdelen. Sommigen belangrijker dan anderen maar steeds de moeite waard om een backup te nemen. Hier gaan we even uit van de meest simpele opstelling; één Zabbix server met een database en webserver geïnstalleerd. In feite kan dit scenario ook uiteengetrokken worden in de vorm van een HA-cluster op de verschillende niveau's. De essentie zal steeds dezelfde blijven

De belangrijke onderdelen die we willen veilig stellen zijn:

  • Zabbix server configuratie
  • Zabbix Frontend data
  • Zabbix database
  • Webserver configuratie

We behandelen ze één voor één; opbouwend naar complexiteit

Zabbix server configuratie

Dit bestand bevindt zich steeds in /etc/zabbix/zabbix-server.conf. Deze configuratie bevat voor velen niet gek veel aanpassingen. Iedere aanpassing kan het resultaat geweest zijn van uren zoeken naar een probleem of een broodnodige tweak. Dit is dan ook het eerste bestand dat we gaan veiligstellen.

#!/bin/bash
# Zabbix BackupScript

# Eerst maken we een map aan om alle data vast te houden.
datum=$(date +'%F')
backupFolder=/opt/backup/zabbix/$datum
mkdir -p $backupFolder

# Eerst de Zabbix configuratie en scripts veiligstellen met de juiste rechten
cp -dR --preserve=all /etc/zabbix/ $backupFolder/configuratie
cp -dR --preserve=all /usr/lib/zabbix $backupFolder/scripts

Frontend

We kunnen ook gegevens uit de frontend halen door middel van de Zabbix API. Hiervoor kunnen we gebruik maken van bijvoorbeeld curl om die data uit te lezen. De belangrijke vereiste is dat je een gebruiker hebt die API-toegang heeft. Met sterke voorkeur is dat geen gebruiker die frontend toegang heeft tot Zabbix.

Vooraleer we informatie uit Zabbix mogen halen, moeten we authenticeren met onze API-gebruiker. Dat kunnen we ook met Curl doen:

Spring heel voorzichtig om met wachtwoorden in een script. Die zijn clear text en iedereen die aan het bestand kan, kan dat lezen. Beter gebruik je een soort wachtwoord manager of wachtwoord kluis om dit net op tijd door te geven aan het script.

response=$(curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"jsonrpc": "2.0","method": "user.login", "params": {"user": "<API-gebruiker>", "password": "<wachtwoord>"},"id": 1 }' \
  https://zabbix.url/api_jsonrpc.php)

Daar zouden we een JSON antwoord van moeten terugkrijgen met een authenticatie token. Deze token moeten we nu bij iedere verzoek meegeven om te bewijzen dat we correct aangemeld zijn. zo kunnen we de data bekijken en exporteren. Deze token uit het JSON object krijgen lijkt moeilijk maar is goed haalbaar met jq, awk of grep. Hier gebruik ik grep met PCRE-regex om een opeenvolging van 32 karakters te vinden.

authcode=$(echo $response | grep -oP '[a-z0-9]{32}')

Nu we dat hebben, kunnen we effectief de data opvragen en veilig opslaan in onze backup map.

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"jsonrpc": "2.0","method": "hostgroup.get", "params": {"output": "extend", "sortfield": "name"},"id": 1, "auth":"'$authcode'" }' \
  https://zabbix.url/api_jsonrpc.php >> $backupFolder/groups.json

Haal zo verschillende zaken uit Zabbix om je backup nog vollediger te maken. Naast Host groups, zijn de Hosts en Templates ook waardevol om op te nemen in je backup. Controleer zeker de [Documentatie]{https://www.zabbix.com/documentation/current/en/manual/api} om inspiratie op te doen van wat jij wilt opslaan.

Webserver Configuratie

Zabbix ondersteunt momenteel Apache en Nginx als webserver. Alhoewel jij jouw voorkeur naar de ene of de andere hebt, moet dat niet relevant zijn voor jouw Zabbix backup. Iedereen moet namelijk een goede backup kunnen maken. Hieronder controleer ik dan welke geïnstalleerd is. Er zijn verschillende manieren om dat aan te pakken: controleer op de processen die lopende zijn, controleer het netverkeer van een bepaalde gebruiker. Omdat ik ervan uitga dat je Systemd gebruikt, kan het ook als volgt.

# We kijken welke service automatisch opstart
if [[ $(systemctl is-enabled httpd 2> /dev/null) = "enabled" ]]; then
    service="httpd"
elif [[ $(systemctl is-enabled nginx 2> /dev/null) = "enabled" ]]; then
    service="nginx"
fi

cp -dR --preserve=all /etc/$service $backupFolder

Database backup

Hier begint het wat moeilijker te worden. Je kan namelijk niet gewoon database bestanden verplaatsen. Zabbix ondersteunt voor de server namelijk enkel MySQL/MariaDB en PostgreSQL. Beide zijn relationele SQL database systemen en hebben hun eigen manier om een database dump te maken.

Opnieuw moeten we hier een wachtwoord in clear text ingeven. Probeer dat met sterke voorkeur te vemijden in voorkeu van een wachtwoordmanager of kluis

# Afhankelijk van welke database service, kunnen we het ene of het andere commando uitvoeren.
if [[ $(systemctl is-enabled mysqld 2> /dev/null) = "enabled" ]]; then
    $(which mysqldump) --single-transaction -p --tab $backupFolder -uzabbix -p <password> zabbix
else
    $(which pg_dump) zabbix > $backupFolder\zabbix_db
fi

Comprimeren

Een goede backup is achteraf ook mooi opgeruimd en neemt niet meer ruimte in dan nodig. We kunnen daarom onze backup in een tarbal steken en die dan ook comprimeren.

#Ga naar een bovenliggende map
cd $backupFolder/..
tar -czf zabbix_$datum.tar.gz $datum/

Nu allemaal samen

Alhoewel ik het sterk afraad dit script in productie te gebruiken, kan dit wel een goed startpunt zijn om een goede backupstrategie uit te bouwen. Je merkt hierboven dat op verschillende momenten authenticatie nodig is. Dit kan je wegwerken door gebruik te maken van een wachtwoord vault en dan die wachtwoorden Just in time te laten invullen. Alhoewel zeker interessant, valt dat een beetje buiten de scope van deze handleiding. Hieronder heb ik nog enkele extra stappen toegevoegd zoals de backup van eventuele rebranding als je dat ook gedaan hebt.

#!/bin/bash
# Zabbix BackupScript

# Eerst maken we een map aan om alle data vast te houden.
datum=$(date +'%F')
backupFolder=/opt/backup/zabbix/$datum
mkdir -p $backupFolder

# We kijken welke webservice automatisch opstart
if [[ $(systemctl is-enabled httpd 2> /dev/null) = "enabled" ]]; then
    service="httpd"
elif [[ $(systemctl is-enabled nginx 2> /dev/null) = "enabled" ]]; then
    service="nginx"
fi

# Info uit Zabbix frontend
response=$(curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"jsonrpc": "2.0","method": "user.login", "params": {"user": "<API-gebruiker>", "password": "<wachtwoord>"},"id": 1 }' \
  https://zabbix.url/api_jsonrpc.php)

authcode=$(echo $response | grep -oP '[a-z0-9]{32}')

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"jsonrpc": "2.0","method": "hostgroup.get", "params": {"output": "extend", "sortfield": "name"},"id": 1, "auth":"'$authcode'" }' \
  https://zabbix.url/api_jsonrpc.php >> $backupFolder/groups.json

#### Andere exports toe te voegen ###

# Zabbix + Webservice configuratie
cp -dR --preserve=all /etc/zabbix/ $backupFolder/configuratie
cp -dR --preserve=all /usr/lib/zabbix $backupFolder/scripts
cp -dR --preserve=all /etc/$service $backupFolder

# Zabbix rebranding
cp -dR --preserve=all /usr/share/zabbix/my_images $backupFolder/logos
cp -dR --preserve=all /usr/share/zabbix/local/conf/brand.conf.php $backupFolder
cp -dR --preserve=all /usr/share/zabbix/assets/styles $backupFolder

# Database backup
if [[ $(systemctl is-enabled mysqld 2> /dev/null) = "enabled" ]]; then
    $(which mysqldump) --single-transaction -p --tab $backupFolder -uzabbix -p <password> zabbix
else
    $(which pg_dump) zabbix > $backupFolder\zabbix_db
fi

cd $backupFolder/..
tar -czf zabbix_$datum.tar.gz $datum/