Back-upstrategie voor rootservers die standhoudt als het erop aankomt
De 3-2-1-regel op één enkele rootserver, restic en Borg met voorbeelden, bewaartermijn en versleuteling. En de stap die bijna iedereen overslaat: het herstel werkelijk testen.
De checklist voor de eerste 30 minuten eindigt met een tar-archief van /etc en met de vaststelling dat dit nog geen back-up is, maar een kopie op dezelfde schijf. Daar begint dit artikel: hoe daar een strategie van wordt die een totaalverlies doorstaat.
De zin waar alles om draait: een back-up waaruit nog nooit iets is teruggehaald, is geen back-up maar hoop. Al het overige dient één doel: daar een gecontroleerde vaststelling van maken.
Alle commando's draaien als root. Werkt u als gewone gebruiker, zet dan voor elk commando een sudo. De referentiesystemen zijn Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS en Ubuntu 22.04 LTS. Waar de vier van elkaar verschillen, staat dat erbij.
Voordat u iets wijzigt: de terugweg
Aan de back-up zelf gaat zelden iets stuk. Gevaarlijk zijn de handelingen eromheen: een herstelactie die over het draaiende systeem heen schrijft, een repository dat de systeemschijf volschrijft, sleutelbestanden die uw eigen toegang vervangen. Vier punten vooraf.
1. Ken de consoletoegang voordat u die nodig hebt
Bij KVM-rootservers en dedicated servers van KernelHost bereikt u de VNC-console in het klantenpaneel. Die hangt niet aan de netwerkstack van het gastsysteem en reageert ook nog wanneer SSH zwijgt. Dat is de vluchtweg wanneer een herstelactie een oude sshd_config of authorized_keys over de actuele heen heeft geschreven. Log daar één keer vooraf op in en controleer of u het rootwachtwoord kent.
2. Zet nooit als eerste poging terug naar /
De eerste herstelactie gaat altijd naar een lege map, bijvoorbeeld /var/tmp/restore-test. Van daaruit vergelijkt u en kopieert u gericht terug. Een herstel rechtstreeks naar / overschrijft ook de bestanden die sinds de back-up met goede reden zijn gewijzigd.
3. Houd een tweede sessie open
Zolang u aan SSH-sleutels of aan de authorized_keys van het doelsysteem werkt, geldt dezelfde regel als bij het opbouwen van een firewall: laat een tweede terminal met een staande verbinding open en sluit die pas wanneer een verse verbinding lukt.
4. Controleer de ruimte voordat het repository groeit
df -h /
df -i /
De tweede regel vergeten de meesten: een bestandssysteem loopt ook vol wanneer er nog gigabytes vrij zijn, namelijk wanneer de inodes op raken. Een lokaal repository dat de systeemschijf volschrijft, is een van de meest voorkomende zelfveroorzaakte storingen. Daarom ligt de bestemming hier vanaf het begin buiten de server.
De 3-2-1-regel, toegepast op één enkele server
- Drie kopieën. De productiegegevens zijn de eerste kopie. Er zijn dus twee back-ups nodig en niet één.
- Twee verschillende opslagplaatsen. Twee mappen op dezelfde schijf zijn één opslagplaats, twee schijven in dezelfde RAID net zo goed: een onbedoelde
rmraakt allebei. RAID beschermt tegen de uitval van één gegevensdrager en tegen verder niets. - Eén kopie buiten de deur. Niet dezelfde server, niet hetzelfde beheeraccount, idealiter niet dezelfde locatie.
Twee aanvullingen zijn nodig. Ten eerste hoort één kopie zo te staan dat de server die zelf niet kan verwijderen, want wie uw server overneemt, vindt daar de inloggegevens voor de bestemming. Ten tweede telt een kopie pas mee wanneer die is gecontroleerd. Een image in hetzelfde klantenpaneel is handig, maar als kopie buiten de deur telt het niet mee.
Leg daarnaast twee getallen vast: hoeveel uur gegevensverlies u kunt accepteren (dat bepaalt de tijd tussen twee draaibeurten), en hoe lang het herstel mag duren (dat beslist over een aanvullend image).
Wat in de back-up hoort, en wat niet
De meest gemaakte fout is niet dat er te weinig wordt geback-upt, maar dat alles wordt meegenomen. Wie / zonder uitsluitingen wegschrijft, neemt pakketcaches, tijdelijke bestanden en swap mee.
| Wat | Typische locatie | Methode | Waarom |
|---|---|---|---|
| Configuratie | /etc | bestandsback-up | Handmatig opnieuw opbouwen kost dagen |
| Pakketselectie | tekstbestand, zie hieronder | bestandsback-up | Maakt de heropbouw reproduceerbaar |
| Gebruikersgegevens | /var/www, /srv, /home | bestandsback-up | Niet opnieuw te verkrijgen |
| Databases | /var/lib/mysql | dump in plaats van bestandskopie | Bestandskopieën tijdens bedrijf zijn inconsistent |
| Certificaten | /etc/letsencrypt | bestandsback-up | Accountsleutel en rate limiting van de certificaatautoriteit |
| Containers | compose-bestanden en volumes | bestandsback-up | Images zijn opnieuw op te halen, volumes niet |
| Niet back-uppen | /proc, /sys, /dev, /run, /tmp | uitsluiten | Kernelinterfaces zonder bestandsinhoud |
| Niet back-uppen | /var/cache, swap | uitsluiten | Altijd opnieuw aan te maken |
apt-mark showmanual > /root/pakketlijst.txt
dpkg --get-selections > /root/pakketselectie.txt
wc -l /root/pakketlijst.txt /root/pakketselectie.txt
apt-mark showmanual toont alleen de uitdrukkelijk geïnstalleerde pakketten, zonder de meegetrokken afhankelijkheden: de korte lijst die u bij een heropbouw nodig hebt.
Bestand, database, image: drie methodes die elkaar niet vervangen
| Methode | Beschermt goed tegen | Beschermt niet tegen | Typische valkuil |
|---|---|---|---|
| Bestandsback-up | Verwijderen, kapotte losse bestanden, verlies van de server | Inconsistentie van geopende databases | Databasebestanden tijdens bedrijf meegekopieerd |
| Databaseback-up (dump) | Inconsistentie, terugkeer naar een schone toestand | Alles buiten de database | Afgebroken dump waarvan het bestand bruikbaar oogt |
| Image van het systeem | Totale uitval, korte hersteltijd | Laat opgemerkt verwijderen, uitval van het account | Weinig versies, allemaal in hetzelfde account |
Daaruit volgt een volgorde, geen keuze. Eerst schrijft de databaseserver een dump, daarna draait de bestandsback-up, en de datamap blijft uitgesloten. Een bestandskopie van /var/lib/mysql tijdens bedrijf legt verschillende tabellen op verschillende momenten vast. Of die zich laat terugzetten, merkt u op het ongunstigste moment.
Toegangsbestand, rechten en struikelblokken van de dump behandelt MySQL- en MariaDB-databases automatisch back-uppen. Belangrijk is het overdrachtspunt: de dumps landen in /var/backups/db, blijven daar één tot twee dagen, en de bewaring neemt het repository over. PostgreSQL back-upt u met pg_dumpall als gebruiker postgres.
restic of Borg
Beide verdelen bestanden in blokken, slaan gelijke blokken maar één keer op, versleutelen en leggen versies vast. Beide zitten op alle vier de distributies in een pakket. Het verschil dat de keuze bepaalt, staat in de laatste regel.
| Kenmerk | restic | Borg |
|---|---|---|
| Pakket | restic | borgbackup, commando borg |
| Versleuteling | altijd actief | instelbaar, zinvol zijn repokey of keyfile |
| Ruimte vrijmaken | forget met --prune | prune, daarna compact |
| Bescherming tegen verwijderen door de server | REST-server of objectopslag met versiebeheer | borg serve --append-only |
| Vereiste op de bestemming | SFTP-toegang volstaat | Borg moet op de bestemming geïnstalleerd zijn |
Op een opslag waarop u niets kunt installeren, valt Borg af. Beschikt u over een tweede Linux-server in eigen beheer, dan pleit de append-only-modus juist voor Borg.
Inrichten met restic
apt update
apt install -y restic
restic version
Controleer de uitvoer voordat u een repository aanmaakt: de vier distributies leveren sterk uiteenlopende versies mee, en een repository van een nieuwere versie laat zich door een oudere niet per se openen.
Toegang tot de bestemming
De bestemming is hier een tweede server via SSH. De sleutel is eigendom van root, want alleen root mag alle te back-uppen bestanden lezen:
ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519_backup -C 'back-up srv01'
ssh-copy-id -i /root/.ssh/id_ed25519_backup.pub backup@203.0.113.50
cat > /root/.ssh/config <<'EOF'
Host backupziel
HostName 203.0.113.50
User backup
IdentityFile /root/.ssh/id_ed25519_backup
BatchMode yes
EOF
chmod 600 /root/.ssh/config
Controle: ssh backupziel true loopt zonder uitvoer en zonder tussenvraag door. De allereerste verbinding vraagt naar de hostsleutel: beantwoord die vraag nu en niet later in een service die op niemand kan wachten.
Wachtwoord en repository
install -d -m 700 /etc/restic
head -c 32 /dev/urandom | base64 | tr -d '\n' > /etc/restic/repo.pass
chmod 600 /etc/restic/repo.pass
cat > /etc/restic/env <<'EOF'
RESTIC_REPOSITORY=sftp:backupziel:/srv/backup/srv01
RESTIC_PASSWORD_FILE=/etc/restic/repo.pass
EOF
chmod 600 /etc/restic/env
Dit bestand is voor de shell en voor systemd even goed bruikbaar. In de shell:
set -a; . /etc/restic/env; set +a
restic init
Controle: restic cat config geeft een korte JSON-structuur met de identificatie van het repository. Verschijnt de tussenvraag Is there a repository at the following location?, dan klopt het pad niet of heeft restic init nooit gedraaid.
De eerste back-up
cat > /etc/restic/excludes.txt <<'EOF'
/proc
/sys
/dev
/run
/tmp
/var/tmp
/var/cache
/var/lib/apt/lists
/var/lib/mysql
/swapfile
EOF
restic backup / --one-file-system --exclude-file=/etc/restic/excludes.txt --exclude-caches --tag system
--one-file-system houdt de back-up op het rootbestandssysteem en neemt aangekoppelde netwerkschijven niet mee. --exclude-caches slaat mappen over die zichzelf als cache hebben gemarkeerd. Het uitsluiten van /var/lib/mysql is de uitwerking van de vorige paragraaf.
Controle: de back-up eindigt met een regel als snapshot 0a1b2c3d saved. Daarna:
restic snapshots
restic stats latest
In de lijst staan het tijdstip, de hostnaam en de paden. Toont restic stats latest een onverwacht kleine omvang, dan grijpt een uitsluiting te ver.
Hetzelfde met Borg
apt install -y borgbackup
borg --version
export BORG_REPO='ssh://backup@203.0.113.50/./srv01'
borg init --encryption=repokey-blake2
borg create --stats --compression zstd ::'system-{now}' /etc /var/www /home /var/backups
borg list
borg info
Alle vier de distributies leveren een versie uit de 1.x-reeks mee. Borg moet aan beide kanten aanwezig zijn, en de versie op de bestemming hoort niet ouder te zijn dan die op de server. Gebruik per server een eigen repository: dat bespaart u het werk om het opruimen tot precies de archieven van deze ene server te beperken, en het maakt gescheiden toegangssleutels mogelijk.
Controle: borg list toont het archief met tijdstempel, borg info de omvang voor en na de deduplicatie.
Bewaartermijn: langer dan de meesten aanhouden
De bewaartermijn hangt niet af van hoe lang u gegevens wilt bewaren, maar van hoe lang het duurt voordat schade opvalt. Een verwijderde map merkt u dezelfde dag, een kapotte tabel vaak pas weken later. Wie zeven dagen bewaart, heeft dan zeven dagen lang de schade mee geback-upt.
| Soort gegevens | Voorstel | Reden |
|---|---|---|
| Databasedumps | 7 dagelijks, 4 wekelijks, 6 maandelijks | Stille beschadigingen vallen laat op |
| Configuratie | 30 dagelijks, 12 maandelijks | Nagaan wanneer er wat is gewijzigd |
| Gebruikersgegevens | 30 dagelijks, 6 maandelijks | Verwijderde bestanden mist u zelden meteen |
| Logbestanden | zo kort als verantwoord is | Groot, zelden nodig bij een herstel |
restic forget --dry-run --keep-daily 7 --keep-weekly 4 --keep-monthly 6
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
De proefdraai laat zien welke versies zouden verdwijnen. Zonder --prune verdwijnen alleen de verwijzingen en blijft de ruimte bezet. Bij Borg gaat dat sinds 1.2 in twee stappen, en het vergeten tweede commando verklaart de meeste repositories die maar niet willen krimpen:
borg prune --list --dry-run --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg prune --list --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg compact
Controle: restic snapshots of borg list toont de verwachte spreiding, en de bezette omvang op de bestemming daalt.
Versleuteling en de sleutel die achteraf niemand meer heeft
Beide gereedschappen versleutelen voordat de gegevens de server verlaten. De bestemming ziet alleen onleesbare blokken, en pas daardoor is opslag bij een externe partij verantwoord. De prijs is duidelijk: zonder wachtwoord of sleutel zijn de gegevens definitief verloren. Er is geen achterdeur.
Daaruit volgen twee regels. Ten eerste hoort het wachtwoord op een tweede plek, gebruikelijk is een wachtwoordkluis. Een wachtwoord dat alleen in /etc/restic/repo.pass staat, is bij verlies van de server ook weg, en daarmee de back-up. Ten tweede exporteert u bij Borg met repokey de sleutel en bewaart u die ergens anders, want daar staat de sleutel in het repository zelf:
borg key export ::
Controle: voer met het wachtwoord uit de wachtwoordkluis op een andere machine restic snapshots uit. Een wachtwoord dat u nog nooit vanaf een andere plek hebt gebruikt, is onbevestigd.
De bestemming beveiligen tegen verwijderen
Een aanvaller met rootrechten heeft ook toegang tot het opgeslagen wachtwoord en tot de sleutel voor de bestemming. Hij kan de back-up dus verwijderen voordat hij de productiegegevens versleutelt. Daarom is er een opslagplaats nodig die nieuwe versies aanneemt, maar geen verwijderen toestaat. Bij Borg regelt u dat in de authorized_keys van de back-upgebruiker op de bestemming:
command="borg serve --append-only --restrict-to-path /srv/backup/srv01",restrict ssh-ed25519 AAAA... back-up srv01
De sleutel neemt daarna alleen nog back-ups aan, en dan uitsluitend in dit pad. Houd er rekening mee dat een prune hier wel doorloopt, maar geen ruimte vrijmaakt, omdat het verwijderen op de bestemming niet wordt uitgevoerd. Het opruimen doet u daar waar de server geen toegang heeft. Bij restic nemen de REST-server in de append-only-modus of een objectopslag met versiebeheer die rol over. Een kale SFTP-toegang doet dat niet.
Automatiseren met een systemd-timer
Een timer verdient de voorkeur boven een cronjob, omdat hij de uitvoer naar het journal schrijft, gemiste beurten inhaalt en het starttijdstip mag spreiden. Over de opbouw van units: Een eigen systemd-service aanmaken.
cat > /etc/systemd/system/sicherung.service <<'EOF'
[Unit]
Description=Dagelijkse back-up met restic
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
Nice=10
IOSchedulingClass=idle
ExecStart=/usr/bin/restic backup / --one-file-system --exclude-file=/etc/restic/excludes.txt --exclude-caches --tag system
ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
EOF
cat > /etc/systemd/system/sicherung.timer <<'EOF'
[Unit]
Description=Start de dagelijkse back-up
[Timer]
OnCalendar=*-*-* 02:30:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now sicherung.timer
systemd-analyze calendar '*-*-* 02:30:00'
Meerdere ExecStart-regels in een oneshot-unit lopen na elkaar, en één mislukking breekt de keten af. Het opruimen draait dus alleen na een geslaagde back-up. Is de bestemming een aangekoppeld bestandssysteem, dan hoort daar een controle voor, anders schrijft de back-up ongemerkt in het lege koppelpunt:
ExecStartPre=/usr/bin/mountpoint -q /mnt/backup
Controle:
systemctl start sicherung.service
systemctl list-timers sicherung.timer
journalctl -u sicherung.service -n 50 --no-pager
systemctl list-timers moet een volgende starttijd tonen. Staat daar niets, dan is de timer niet geactiveerd. Het belangrijkste punt komt tot slot: een back-up die geruisloos ophoudt met draaien, is het normale geval van falen. Controleer systemctl is-failed sicherung.service, of hang als laatste ExecStart-regel een aanroep naar een externe monitoringdienst aan, die alarm slaat wanneer het dagelijkse levensteken uitblijft.
Het herstel testen
De kleine test, maandelijks, vijf minuten
mkdir -p /var/tmp/restore-test
restic restore latest --target /var/tmp/restore-test --include /etc/ssh/sshd_config
diff /etc/ssh/sshd_config /var/tmp/restore-test/etc/ssh/sshd_config && echo "identiek"
Met Borg werkt het net zo, alleen slaat Borg paden zonder voorafgaande schuine streep op:
cd /var/tmp/restore-test
borg extract --list ::system-2026-09-03T02:30:00 etc/ssh/sshd_config
Controleer daarnaast de integriteit van het repository. De tweede regel leest in beide gevallen de gegevens terug en rekent de controlesommen na, bij restic maar voor een deel, zodat de controle geen uren duurt:
restic check
restic check --read-data-subset=1/7
borg check
borg check --verify-data
Controle: restic check eindigt met no errors were found, borg check zonder foutmelding. Een repository dat maar één keer per jaar wordt gecontroleerd, kan elf maanden lang kapot zijn geweest.
De grote test, één keer per jaar
De kleine test bewijst dat bestanden leesbaar zijn. Hij bewijst niet dat u de dienst weer aan de praat krijgt. Daarvoor is de volledige doorloop op een tweede, lege server nodig: basissysteem installeren, pakketlijst inlezen, repository koppelen, gegevens terughalen, dump inlezen, services starten. Klok de tijd. Dat getal is uw werkelijke hersteltijd, ervaringsgewijs een veelvoud van de geschatte.
Noteer wat er ontbrak. Het zijn bijna altijd dezelfde dingen: een bestand buiten de geback-upte paden, een dienst met configuratie onder /opt, een certificaat zonder accountsleutel, een database zonder gebruikers en rechten. Die lijst is de opbrengst van de test.
Veelvoorkomende fouten en oplossingen
Host key verification failed. De service draait als root, en root heeft de hostsleutel van de bestemming nooit bevestigd. Voer één keer handmatig ssh backupziel true uit, of ssh-keyscan -H 203.0.113.50 >> /root/.ssh/known_hosts. Werkt het op de console wel en in de timer niet, dan is dit bijna altijd de oorzaak.
Permission denied (publickey). Verkeerde gebruiker, verkeerde sleutel of verkeerde rechten op de bestemming: .ssh heeft 700 nodig, authorized_keys 600, en beide zijn eigendom van de gebruiker op de bestemming.
Is there a repository at the following location? restic vindt geen repositorystructuur: verkeerd pad, restic init nooit gedraaid, of de bestemming is op dat moment niet bereikbaar.
Fatal: wrong password or no key found Het wachtwoordbestand past niet bij het repository, meestal omdat het achteraf opnieuw is aangemaakt. Controleer met cat -A /etc/restic/repo.pass of er een spatie in is geslopen.
repository is already locked exclusively by Een afgebroken back-up heeft zijn vergrendeling achtergelaten. Controleer eerst dat er niets meer draait, daarna restic unlock. Bij Borg luidt de melding Failed to create/acquire the lock met de toevoeging (timeout) en is het commando borg break-lock. Beide zijn riskant zolang er toch nog een back-up actief is.
Warning: The repository at location ... was previously located at ... Het adres van het repository is gewijzigd en Borg stelt een interactieve vraag. In een unit wacht het commando daarmee op een antwoord dat nooit komt. Nadat u hebt gecontroleerd dat het om hetzelfde repository gaat, zet u BORG_RELOCATED_REPO_ACCESS_IS_OK=yes in het omgevingsbestand.
No space left on device op de bestemming. Ofwel draait het opruimen helemaal niet, ofwel draait het zonder --prune of zonder borg compact. Heeft omgekeerd een dump het rootbestandssysteem volgeschreven, dan helpt Schijf vol onder Linux opruimen verder.
De back-up meldt succes, maar bevat vrijwel niets. Een uitsluiting grijpt te ver, of een pad is verkeerd geschreven. Vergelijk restic stats latest met de waarde van de dag ervoor. Een back-up die ineens ordes van grootte kleiner is, is een alarm en geen succes.
Verschillen tussen de distributies
- Pakketnamen zijn op alle vier de systemen gelijk:
resticenborgbackup. De meegeleverde versies zijn dat niet. - Logging: Debian 13 en veel Debian 12-installaties leveren geen rsyslog mee. De uitvoer van de back-up vindt u daar uitsluitend in het journal, dus via
journalctl -u sicherung.service. Onder Ubuntu 22.04 en 24.04 komt daar de opslag onder/var/logbij. - Back-upversies aankoppelen:
restic mountenborg mounthebbenfuse3nodig. Ontbreekt dat pakket, dan breekt het commando af met een verwijzing naar een ontbrekendefusermount3. De weg zonder FUSE isrestic restoreofborg extract. - Databasegereedschap: Debian levert uitsluitend MariaDB, daar heet het
mariadb-dumpmetmysqldumpals verwijzing daarnaar. Onder Ubuntu kan ook MySQL 8 draaien, daar bestaat alleenmysqldump.
De eindcontrole
De strategie is af wanneer u deze zeven punten met een commando kunt aantonen en niet met een vermoeden:
restic snapshotsofborg listtoont een versie van vannacht.systemctl list-timers sicherung.timertoont een volgende starttijd.restic checkofborg checkmeldt geen fout.- Een enkel bestand liet zich deze maand terughalen en was daarna identiek.
- De spreiding komt overeen met de geplande bewaartermijn, en het repository groeit niet onbeperkt.
- Het wachtwoord staat op een tweede plek, en u hebt het van daaruit al een keer gebruikt.
- Minstens één opslagplaats neemt back-ups aan zonder dat de server ze kan verwijderen.
Ontbreekt punt vier, dan hebt u een vermoeden. Ontbreekt punt zes, dan hebt u versleuteld afval. Ontbreekt punt zeven, dan hebt u een back-up die precies die ene aanval niet doorstaat waartegen zij het hardst nodig is.
Veelgestelde vragen
Wat betekent de 3-2-1-regel op één enkele rootserver?
Is een RAID of een image van het systeem al een back-up?
restic of Borg: wat past wanneer?
Waarom wordt mijn repository niet kleiner terwijl ik oude versies verwijder?
Kan ik een draaiende database gewoon als bestand meekopiëren?
Wat gebeurt er als ik het wachtwoord van het repository kwijtraak?
Hoe vaak moet ik het herstel testen?
Waarom draait mijn back-up handmatig wel, maar niet in de systemd-timer?
2026 KernelHost GmbH. Alle rechten voorbehouden. Deze handleiding is auteursrechtelijk beschermd. Publicatie op andere websites, geheel, gedeeltelijk of in bewerkte vorm, is zonder onze schriftelijke toestemming niet toegestaan. Citeren met bronvermelding en link is uitdrukkelijk welkom.

