Fluxul unui backup criptat cu restic de pe un VPS Linux catre stocare la distanta
Linux

Tutorial backup restic: backup-uri criptate si automate

Orice om care administreaza un server ajunge, mai devreme sau mai tarziu, la o poveste cu backup-uri, iar cele urate incep toate la fel: “Eram sigur ca avem backup.” Un disc cedeaza, cineva ruleaza rm -rf in directorul gresit, un update de plugin strica baza de date sau un ransomware cripteaza tot ce prinde. Daca totul se termina cu o dupa-amiaza proasta sau cu o afacere pierduta depinde de doua intrebari: exista o copie recenta si intacta a datelor in alta parte, si ai restaurat vreodata efectiv din ea? In acest tutorial backup restic construim exact asta pe un VPS Linux proaspat. Configuram backup-uri criptate si deduplicate pentru fisiere si dump-uri de baze de date, le trimitem in fiecare noapte catre o stocare la distanta cu un timer systemd, le curatam cu reguli de retentie si le verificam cu un test real de restaurare.

Restic este un program de backup gratuit si open source, scris in Go, publicat pe restic.net , cu codul sursa pe github.com/restic/restic , sub licenta BSD 2-Clause. Vine ca un singur binar, fara daemon si fara nimic de instalat pe partea de stocare. Citeste fisierele, le cripteaza chiar pe serverul tau si le scrie pe aproape orice stocare ii indici. E simplu de rulat si sigur din start, de aceea a ajuns unul dintre cele mai folosite unelte de backup pentru servere Linux.

De ce restic se potriveste pe un VPS

Inainte sa instalam ceva, sa ne punem de acord ce inseamna backup. Un backup e o copie a datelor aflata pe alt hardware, ideal in alta locatie, din care poti restaura chiar daca serverul original a disparut complet. Un RAID nu e backup, pentru ca iti copiaza instant si greselile. O copie in /root/backup pe acelasi disc nu e nici ea backup. Regula clasica este 3-2-1: trei copii ale datelor, pe doua tipuri diferite de stocare, dintre care una in alta locatie. Restic rezolva partea cu “alta locatie” cu foarte putin efort.

Cinci notiuni pe care trebuie sa le stii

  • Repository: locul in care restic isi pastreaza backup-urile. Poate fi un folder pe alt server accesat prin SFTP, un bucket pe o stocare de obiecte compatibila S3, un server REST restic si cateva alte variante. Aceste tipuri de stocare se numesc backend-uri. Un repository poate tine backup-uri de la un singur server sau de la mai multe.
  • Snapshot: rezultatul unei rulari de backup. La fiecare rulare, restic inregistreaza un snapshot cu fisierele exact asa cum erau in acel moment. Poti lista snapshot-urile, le poti rasfoi si poti restaura din oricare.
  • Deduplicare: restic taie fisierele in bucati (chunk-uri) de dimensiune variabila, recunoaste bucatile pe care le are deja si le urca doar pe cele noi. Daca un folder de 2 GB se schimba cu 20 MB, urmatorul backup trimite cam 20 MB, dar tot obtii un snapshot complet.
  • Compresie: formatul de repository versiunea 2, pe care versiunile actuale de restic il creeaza implicit, comprima bucatile cu zstd inainte de upload. Fisierele de configurare si dump-urile SQL se micsoreaza mult.
  • Criptare: datele sunt criptate pe serverul tau, inainte sa plece, cu AES-256, si autentificate cu Poly1305. Furnizorul de stocare vede doar blocuri opace. Cheia e protejata de o parola, pe care nu ai voie sa o pierzi: fara parola, nimeni nu mai poate decripta backup-ul, nici macar tu.
Drumul unui backup facut cu resticVPS-ul tauFisiere si configurariDump-uri baze de dateTimer systemd, noaptearesticimparte + deduplicacomprima (zstd)cripteaza (AES-256)urca doar ce e nouRepository la distantaBucket S3 sau SFTPDoar blocuri criptateSnapshot-uri + retentieHTTPS/SSHRestaurare: descarca, decripteaza si aduce inapoi doar ce iti trebuie
Restic face toata munca pe VPS-ul tau: furnizorul de stocare primeste doar bucati criptate si nu vede niciodata parola.

Cum se compara cu alternativele obisnuite

Majoritatea oamenilor incep cu una din trei metode. Un rsync catre alta masina e rapid, dar ai o singura oglinda. Daca un fisier se corupe luni, sincronizarea de marti copiaza fidel si coruptia, si nimic nu e criptat. O arhiva tar.gz in fiecare noapte iti da istoric, dar fiecare noapte inseamna o copie completa, deci platesti iar si iar pentru aceleasi date. Snapshot-urile de hypervisor oferite de furnizorul de hosting sunt un strat suplimentar foarte bun, dar stau pe aceeasi infrastructura ca serverul si nu ar trebui sa fie singura ta linie de aparare. Restic iti da in acelasi timp istoric, criptare si upload-uri incrementale mici, de aceea diferenta de spatiu e atat de mare:

Spatiu ocupat dupa 30 de backup-uri zilnice (aproximativ)Server exemplu: ~10 GB de date, ~1% din ele se schimba zilnicCopie completa zilnictar.gz zilnicrestic (dedup)~300 GB~150 GB~8 GB0100200300Dimensiune repository in GB (aproximativ)Metoda de backupValori ilustrative: cifrele reale depind de cat de compresibile si cat de volatile sunt datele.
Deduplicarea si compresia fac ca o luna de snapshot-uri zilnice restic sa ocupe mai putin decat o singura copie necomprimata a serverului.

De ce ai nevoie

  • Un VPS cu Debian 13 sau Ubuntu 24.04 si un utilizator care poate rula sudo. Totul merge si intr-un container LXC. Iti semnalam singura functie care de obicei nu merge acolo.
  • O stocare la distanta care nu e acelasi server. Poate fi un bucket compatibil S3 de la orice furnizor de object storage, sau alt server accesibil prin SSH, de exemplu un al doilea VPS sau un server de stocare. Ideal, se afla in alt data center decat serverul pe care il protejezi.
  • Un manager de parole, sau alt loc sigur in afara serverului, pentru parola repository-ului.
  • Cam 30 de minute, plus cat dureaza primul upload.

Iata toata procedura dintr-o privire. Numerele corespund titlurilor de pasi de mai jos.

Cei 7 pasi din acest tutorial backup restic1234567InstalareresticPregatirestocareInitializarerepositoryPrimulbackupReguli deretentieTimersystemdTest derestaurareConfigurare unicaRutina de noapteVerificarePasii 1-3 se fac o data, pasii 4-6 se repeta in fiecare noapte, pasul 7 il repeti periodic
Pasii 1-3 pregatesc repository-ul, pasii 4-6 devin jobul automat de noapte, iar pasul 7 demonstreaza ca backup-urile chiar pot fi restaurate.

Pasul 1: Instalarea restic

Atat Debian, cat si Ubuntu au restic in depozitele oficiale, asa ca instalarea e o singura comanda:

sudo apt update
sudo apt install -y restic
restic version

Ultima comanda afiseaza versiunea instalata. In momentul scrierii, Debian 13 vine cu 0.18.x, iar Ubuntu 24.04 vine cu 0.16.x. Ambele stiu compresie, si toate comenzile din acest tutorial merg pe amandoua.

Daca vrei cea mai noua versiune (versiunile recente restaureaza mai repede si adauga cateva optiuni), poti instala in schimb binarul oficial. Il punem in /usr/local/bin, care apare inaintea lui /usr/bin in PATH, deci are prioritate fata de pachetul distributiei:

RESTIC_VERSION=0.18.0   # verifica github.com/restic/restic/releases pentru ultima versiune
ARCH=$(dpkg --print-architecture)   # amd64 sau arm64
sudo apt install -y curl bzip2
cd /tmp
curl -fLO "https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_${ARCH}.bz2"
bunzip2 "restic_${RESTIC_VERSION}_linux_${ARCH}.bz2"
sudo install -m 0755 "restic_${RESTIC_VERSION}_linux_${ARCH}" /usr/local/bin/restic
hash -r
restic version

O diferenta practica: binarul oficial se poate actualiza singur mai tarziu cu sudo restic self-update. Pachetele Debian si Ubuntu au aceasta functie dezactivata si se actualizeaza prin apt, ca orice alt pachet.

Pasul 2: Pregatirea stocarii la distanta si a credentialelor

La fiecare rulare, restic trebuie sa stie trei lucruri: unde e repository-ul, care e parola si cum se autentifica la stocare. Le tinem pe toate intr-un singur director, /etc/restic, pe care il poate citi doar root, ca utilizatorii obisnuiti de pe server sa nu le vada.

Mai intai, cream directorul si generam o parola aleatoare puternica:

sudo mkdir -p /etc/restic
sudo chmod 700 /etc/restic
sudo sh -c 'umask 077; head -c 32 /dev/urandom | base64 > /etc/restic/password'
sudo cat /etc/restic/password

Partea cu umask 077 face ca fisierul nou sa poata fi citit doar de root. Ultima comanda iti afiseaza parola, un sir de 44 de caractere. Copiaz-o acum in managerul de parole. Daca serverul moare, fisierul moare odata cu el, iar fara el backup-ul nu mai foloseste la nimic.

Acum alegi varianta de stocare.

Varianta A: un bucket compatibil S3

Creeaza un bucket la furnizorul tau de object storage, plus o cheie de acces care are drepturi doar pe acel bucket. Apoi scrie fisierul de mediu, inlocuind endpoint-ul, numele bucket-ului si cheile cu ale tale:

sudo tee /etc/restic/restic.env > /dev/null << 'EOF'
RESTIC_REPOSITORY=s3:https://s3.example-provider.com/company-backups/web01
RESTIC_PASSWORD_FILE=/etc/restic/password
RESTIC_CACHE_DIR=/var/cache/restic
AWS_ACCESS_KEY_ID=CHEIA_TA_DE_ACCES
AWS_SECRET_ACCESS_KEY=CHEIA_TA_SECRETA
# Doar daca furnizorul cere o regiune:
# AWS_DEFAULT_REGION=eu-central-1
EOF
sudo chmod 600 /etc/restic/restic.env

Adresa repository-ului are forma s3:https://ENDPOINT/BUCKET/PREFIX. Prefixul (aici web01) permite mai multor servere sa foloseasca acelasi bucket, fiecare cu repository-ul lui. Variabilele pastreaza numele AWS_ chiar daca furnizorul tau nu e Amazon, pentru ca asa se asteapta bibliotecile client S3. RESTIC_CACHE_DIR muta cache-ul local de metadate al lui restic intr-un loc fix, ca rularile manuale si cele programate sa foloseasca acelasi cache.

Varianta B: un server SFTP controlat de tine

Daca ai o a doua masina (un VPS de stocare, un server dedicat, un calculator la birou), restic poate folosi SSH simplu. Pe acea masina, creeaza un utilizator (noi il numim backup) si un director detinut de el, de exemplu /srv/restic. Apoi, pe serverul de salvat, creeaza o cheie SSH pentru root, pentru ca backup-ul va rula ca root:

sudo install -d -m 700 /root/.ssh
sudo ssh-keygen -t ed25519 -f /root/.ssh/restic_backup -N "" -C "restic@$(hostname)"
sudo ssh-copy-id -i /root/.ssh/restic_backup.pub backup@backup.example.com

ssh-copy-id iti cere o singura data sa confirmi amprenta serverului si sa introduci parola utilizatorului backup. Apoi dai conexiunii un nume scurt in configurarea SSH a lui root:

sudo tee -a /root/.ssh/config > /dev/null << 'EOF'
Host restic-target
    HostName backup.example.com
    User backup
    IdentityFile /root/.ssh/restic_backup
    ServerAliveInterval 60
    ServerAliveCountMax 240
EOF
sudo chmod 600 /root/.ssh/config
sudo ssh restic-target exit && echo "SSH OK"

Daca vezi SSH OK fara sa ti se ceara parola, scrie fisierul de mediu:

sudo tee /etc/restic/restic.env > /dev/null << 'EOF'
RESTIC_REPOSITORY=sftp:restic-target:/srv/restic/web01
RESTIC_PASSWORD_FILE=/etc/restic/password
RESTIC_CACHE_DIR=/var/cache/restic
EOF
sudo chmod 600 /etc/restic/restic.env

Un mic wrapper ca sa ramana comenzile scurte

Sa incarci de mana mediul la fiecare comanda devine repede obositor. Facem un mic ajutor care citeste /etc/restic/restic.env si ii paseaza restul direct lui restic:

sudo tee /usr/local/sbin/restic-run > /dev/null << 'EOF'
#!/bin/sh
# Ruleaza restic cu setarile de repository ale acestui server
set -a
. /etc/restic/restic.env
set +a
exec restic "$@"
EOF
sudo chmod 700 /usr/local/sbin/restic-run

set -a exporta toate variabilele citite din fisier, ca restic sa le vada. De acum, sudo restic-run snapshots ruleaza restic cu toate setarile la locul lor. Atat pe Debian, cat si pe Ubuntu, /usr/local/sbin e in calea de cautare a lui sudo, deci numele scurt functioneaza.

Pasul 3: Initializarea repository-ului criptat

Initializarea creeaza structura repository-ului pe stocare si scrie acolo cheia principala, criptata cu parola ta:

sudo restic-run init

Rezultat asteptat:

created restic repository 5b7d8e9f01 at s3:https://s3.example-provider.com/company-backups/web01

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.

Ia avertismentul in sens propriu. Apoi ruleaza sudo restic-run snapshots. Ar trebui sa se conecteze si sa afiseze o lista goala, ceea ce dovedeste ca adresa, credentialele si parola functioneaza. Daca primesti o eroare, treci prin sectiunea de probleme frecvente inainte sa mergi mai departe.

Pasul 4: Primul backup pentru fisiere si dump-uri de baze de date

Ce merita salvat

Nu ai nevoie de backup la tot discul. Sistemul de operare il reinstalezi in cateva minute. Ce nu poti inlocui sunt datele si configurarile tale. Pe un VPS obisnuit, asta inseamna:

  • /etc: configurarea sistemului si a serviciilor (server web, firewall, cron, SSH).
  • /home si /root: fisierele utilizatorilor, scripturi si chei SSH.
  • /var/www, /srv, /opt: site-uri si aplicatii, in functie de unde le-ai instalat.
  • Dump-urile bazelor de date, pe care le cream imediat.

Daca folosesti Docker, adauga folderele cu fisierele compose si cu datele montate, de exemplu /opt/stacks (acoperit deja de /opt).

Sari peste cache-uri, foldere node_modules si fisiere temporare trecandu-le intr-un fisier de excluderi:

sudo tee /etc/restic/excludes > /dev/null << 'EOF'
/root/.cache
/home/*/.cache
**/node_modules
**/*.tmp
EOF

De ce dump-uri si nu fisierele brute ale bazei de date

Un server de baze de date tine date in memorie si le scrie pe disc pe bucati. Daca copiezi fisierele din /var/lib/mysql sau /var/lib/postgresql cat timp serverul ruleaza, poti prinde o stare scrisa pe jumatate, care nu mai porneste dupa restaurare. Metoda sigura este sa ceri bazei de date un export consistent, numit dump, si sa salvezi acel fisier. mariadb-dump si mysqldump cu --single-transaction produc o copie consistenta a tabelelor InnoDB fara sa blocheze site-ul, iar pg_dumpall face acelasi lucru pentru PostgreSQL.

Un detaliu conteaza pentru restic: nu comprima dump-urile cu gzip. Compresia schimba toti octetii fisierului chiar daca s-a modificat un singur rand, si asta strica deduplicarea. Un fisier .sql simplu se deduplica bine de la o noapte la alta, iar restic il comprima oricum.

Aici Debian si Ubuntu difera. Pe Debian, serverul implicit compatibil MySQL este MariaDB (serviciul mariadb, unealta de dump mariadb-dump). Pe Ubuntu poti avea fie MariaDB, fie MySQL 8 de la Oracle (serviciul mysql, unealta mysqldump). Scriptul de mai jos le trateaza pe amandoua. In configurarea implicita de pe ambele sisteme, contul root al bazei de date se autentifica prin socket-ul Unix, deci un script rulat ca root nu are nevoie de parola de baza de date.

Scriptul de backup

Scriptul face intai dump-urile, apoi salveaza folderele din lista care exista pe server:

sudo tee /usr/local/sbin/restic-backup.sh > /dev/null << 'EOF'
#!/bin/bash
# Backup restic de noapte: intai dump-urile, apoi fisierele
set -euo pipefail
cd /

# Incarca adresa repository-ului, fisierul cu parola si credentialele
set -a
. /etc/restic/restic.env
set +a

DUMP_DIR=/var/backups/db
mkdir -p "$DUMP_DIR"
chmod 700 "$DUMP_DIR"

# MariaDB sau MySQL, doar daca ruleaza un server
if systemctl is-active --quiet mariadb || systemctl is-active --quiet mysql; then
    if command -v mariadb-dump > /dev/null 2>&1; then
        DUMP_BIN=mariadb-dump
    else
        DUMP_BIN=mysqldump
    fi
    "$DUMP_BIN" --all-databases --single-transaction --quick \
        --routines --events > "$DUMP_DIR/mysql-all.sql.tmp"
    mv "$DUMP_DIR/mysql-all.sql.tmp" "$DUMP_DIR/mysql-all.sql"
fi

# PostgreSQL, doar daca ruleaza
if systemctl is-active --quiet postgresql; then
    runuser -u postgres -- pg_dumpall > "$DUMP_DIR/postgres-all.sql.tmp"
    mv "$DUMP_DIR/postgres-all.sql.tmp" "$DUMP_DIR/postgres-all.sql"
fi

# Salveaza doar folderele care exista pe acest server
SOURCES=(/etc /home /root /var/www /srv /opt "$DUMP_DIR")
EXISTING=()
for p in "${SOURCES[@]}"; do
    if [ -e "$p" ]; then EXISTING+=("$p"); fi
done

restic backup \
    --exclude-file /etc/restic/excludes \
    --exclude-caches \
    --tag scheduled \
    "${EXISTING[@]}"
EOF
sudo chmod 700 /usr/local/sbin/restic-backup.sh

Iata ce fac partile importante:

  • set -euo pipefail opreste scriptul la prima eroare. Daca un dump esueaza, toata rularea esueaza vizibil si nu ajungi sa salvezi in liniste dump-ul de saptamana trecuta.
  • Fiecare dump se scrie intr-un fisier .tmp si se redenumeste doar cand e complet, ca o cadere sa nu lase niciodata un fisier pe jumatate sub numele real.
  • --tag scheduled eticheteaza snapshot-urile automate. Conteaza pentru regulile de retentie din Pasul 5.
  • --exclude-caches sare peste orice folder care contine un fisier standard CACHEDIR.TAG, pe care multe unelte il pun in cache-urile lor.

Daca baza de date ruleaza intr-un container Docker, inlocuieste sectiunea de dump cu o comanda de tipul docker exec my-postgres pg_dumpall -U postgres > "$DUMP_DIR/postgres-all.sql.tmp". Cu restic 0.17 sau mai nou (pachetul din Debian 13 sau binarul oficial) poti trimite un dump direct in repository cu restic backup --stdin-from-command. Pachetul din Ubuntu 24.04 e prea vechi pentru aceasta optiune, de aceea folosim aici fisiere de dump: merg peste tot.

Rularea manuala

sudo /usr/local/sbin/restic-backup.sh

Prima rulare urca tot, deci dureaza cel mai mult. Finalul afisajului arata cam asa (cifrele tale vor fi altele):

repository 5b7d8e9f opened (version 2, compression level auto)
created new cache in /var/cache/restic
no parent snapshot found, will read all files

Files:       18734 new,     0 changed,     0 unmodified
Dirs:         2311 new,     0 changed,     0 unmodified
Added to the repository: 1.912 GiB (812.304 MiB stored)

processed 18734 files, 2.104 GiB in 1:47
snapshot 7c1e4d2a saved

Uita-te la randul “Added to the repository”. Primul numar e cantitatea de date noi, iar cel din paranteza e ce s-a stocat efectiv dupa compresie. Ruleaza scriptul a doua oara si verifica acelasi rand. Ar trebui sa vezi cel mult cativa megabytes, pentru ca se urca doar bucatile schimbate. Asta e deduplicarea la lucru.

Pasul 5: Reguli de retentie cu forget si prune

Fara curatenie, un repository creste la nesfarsit. Restic imparte curatenia in doua actiuni:

  • forget scoate snapshot-uri din lista, dupa reguli stabilite de tine. Datele folosite de ele raman inca in repository.
  • prune sterge datele de care nu mai are nevoie niciun snapshot ramas, si asta elibereaza efectiv spatiu.

O politica rezonabila pentru un server mic: un snapshot pe zi pentru ultimele 7 zile, unul pe saptamana pentru 4 saptamani si unul pe luna pentru 6 luni. Asta inseamna cel mult 17 puncte de restaurare, pe o perioada de aproximativ jumatate de an. Verifica intotdeauna intai cu --dry-run:

sudo restic-run forget --tag scheduled --group-by host,tags \
    --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run

Rezultatul arata ce snapshot-uri ar fi pastrate si ce ar fi sterse, cu motivul pentru fiecare snapshot pastrat. Doua optiuni merita explicate:

  • --tag scheduled aplica regulile doar snapshot-urilor automate. Un snapshot manual facut inainte de un upgrade riscant nu va fi sters niciodata de jobul de noapte.
  • --group-by host,tags aplica politica pe fiecare server si pe fiecare eticheta. Implicit, restic grupeaza si dupa lista de cai salvate. Cu setarea implicita, daca adaugi mai tarziu un folder nou, de exemplu /srv, ar porni un grup separat, iar grupul vechi nu ar mai fi curatat corect.

Cand esti multumit de previzualizare, adauga la finalul scriptului retentia si o verificare saptamanala de integritate:

sudo tee -a /usr/local/sbin/restic-backup.sh > /dev/null << 'EOF'

# Retentie: 7 zilnice, 4 saptamanale, 6 lunare
restic forget --tag scheduled --group-by host,tags \
    --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Duminica verifica structura si reciteste 5% din datele stocate
if [ "$(date +%u)" = "7" ]; then
    restic check --read-data-subset=5%
fi
EOF

--prune ruleaza prune imediat dupa forget. Prune rescrie stocarea doar cand poate recupera suficient spatiu (implicit tolereaza pana la 5% date nefolosite), deci rularea lui in fiecare noapte pe un server mic e in regula. restic check --read-data-subset=5% descarca si verifica in fiecare saptamana 5% din date, alese aleatoriu, si prinde coruptiile tacute de pe partea de stocare fara sa descarce tot repository-ul.

Pasul 6: Backup automat cu un timer systemd

Un timer systemd este inlocuitorul modern al unei intrari in cron. Porneste un serviciu dupa un program, scrie totul in jurnalul sistemului, recupereaza rularile ratate cat timp serverul a fost oprit si face erorile usor de vazut cu systemctl. Avem nevoie de doua fisiere: un serviciu care spune ce se ruleaza si un timer care spune cand.

sudo tee /etc/systemd/system/restic-backup.service > /dev/null << 'EOF'
[Unit]
Description=Restic backup to remote repository
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
Environment=HOME=/root
ExecStart=/usr/local/sbin/restic-backup.sh
Nice=10
IOSchedulingClass=idle
TimeoutStartSec=6h
# Optional: trimite un ping catre un monitor push doar daca backup-ul a reusit
# ExecStartPost=-/usr/bin/curl -fsS -m 10 --retry 3 https://status.example.com/api/push/TOKENUL_TAU
EOF

sudo tee /etc/systemd/system/restic-backup.timer > /dev/null << 'EOF'
[Unit]
Description=Nightly restic backup

[Timer]
OnCalendar=*-*-* 03:15:00
RandomizedDelaySec=20min
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer

Ce face fiecare setare:

  • Type=oneshot ii spune lui systemd ca jobul ruleaza pana la capat si apoi se termina, spre deosebire de un daemon care ruleaza continuu.
  • Environment=HOME=/root ajuta uneltele care isi cauta configurarea in folderul home, pentru ca systemd nu seteaza implicit HOME pentru serviciile de sistem.
  • Nice=10 si IOSchedulingClass=idle scad prioritatea backup-ului pe procesor si pe disc, ca site-ul sa raspunda normal cat timp ruleaza.
  • TimeoutStartSec=6h opreste o rulare blocata, de exemplu pe o conexiune de retea moarta, ca sa nu o blocheze pe urmatoarea.
  • OnCalendar stabileste ora, RandomizedDelaySec adauga pana la 20 de minute aleatorii (util cand mai multe servere fac backup pe aceeasi stocare), iar Persistent=true ruleaza imediat dupa pornire un backup ratat, daca serverul era oprit la 03:15.
  • Linia comentata ExecStartPost e un “dead man’s switch”: trimite un ping catre un monitor de tip push (de exemplu in Uptime Kuma) doar daca backup-ul a reusit. Daca ping-ul nu mai vine, monitorul te alerteaza. Semnul - din fata inseamna ca un ping esuat nu marcheaza backup-ul ca esuat. Pe Debian, instaleaza intai curl cu sudo apt install -y curl daca lipseste.

OnCalendar foloseste fusul orar local al serverului, iar multe imagini de VPS vin implicit pe UTC. Verifica cu timedatectl si schimba-l daca vrei, de exemplu cu sudo timedatectl set-timezone Europe/Bucharest.

Confirma ca timer-ul e programat:

systemctl list-timers restic-backup.timer
NEXT                         LEFT      LAST PASSED UNIT                ACTIVATES
Wed 2026-11-11 03:24:51 EET  15h left  -    -      restic-backup.timer restic-backup.service

Apoi porneste serviciul o data acum, ca sa stii ca varianta programata merge exact ca cea manuala:

sudo systemctl start restic-backup.service
systemctl status restic-backup.service --no-pager
sudo journalctl -u restic-backup.service -n 30 --no-pager

Pentru un serviciu oneshot, systemctl start asteapta pana se termina backup-ul. Statusul ar trebui apoi sa arate inactive (dead) cu status=0/SUCCESS, iar jurnalul contine tot afisajul lui restic. Folosim sudo pentru journalctl pentru ca primul utilizator de pe Ubuntu e in grupul adm si poate citi logurile de sistem, dar pe Debian de obicei nu e. Timer-ele functioneaza la fel pe VPS-urile KVM si LXC.

Pasul 7: Testul de restaurare

Un backup din care n-ai restaurat niciodata e o speranta, nu un backup. Fa testul acum si apoi repeta-l o data la una sau doua luni. Pune-ti un memento in calendar.

Restaurarea unui singur fisier

Listeaza snapshot-urile, uita-te in cel mai recent si restaureaza un fisier intr-un folder temporar:

sudo restic-run snapshots
sudo restic-run ls latest /etc/ssh
sudo restic-run restore latest --target /tmp/restore-test --include /etc/ssh/sshd_config
sudo diff /etc/ssh/sshd_config /tmp/restore-test/etc/ssh/sshd_config && echo "identical"

Restic recreeaza toata calea sub folderul tinta, deci fisierul ajunge in /tmp/restore-test/etc/ssh/sshd_config. Daca diff nu afiseaza nimic si vezi identical, restaurarea functioneaza cap-coada: descarcare, decriptare si reasamblare. Faci curat cu sudo rm -rf /tmp/restore-test.

Verificarea dump-urilor de baze de date

restic dump afiseaza un fisier dintr-un snapshot direct in terminal, deci poti verifica un dump fara sa-l restaurezi pe disc:

sudo restic-run dump latest /var/backups/db/mysql-all.sql | tail -n 1
sudo restic-run dump latest /var/backups/db/postgres-all.sql | tail -n 3

Un dump complet MariaDB sau MySQL se termina cu un rand de tipul -- Dump completed on 2026-11-10 3:15:42, iar un dump complet PostgreSQL cu -- PostgreSQL database cluster dump complete. Daca ultimul rand lipseste, dump-ul a fost taiat. Testul cel mai bun merge un pas mai departe: incarci dump-ul pe un server de baze de date de test (un al doilea VPS mic e perfect) si deschizi aplicatia pe el.

Ca sa te uiti comod prin backup-uri, poti monta repository-ul ca folder doar pentru citire:

sudo apt install -y fuse3
sudo mkdir -p /mnt/restic
sudo restic-run mount /mnt/restic

Comanda ramane activa in prim-plan. Intr-o a doua sesiune SSH, navighezi cu sudo ls /mnt/restic/snapshots/latest/etc, apoi apesi Ctrl+C in prima sesiune ca sa demontezi. Montarea foloseste FUSE si de obicei nu merge intr-un container LXC neprivilegiat, pentru ca /dev/fuse nu e disponibil acolo decat daca il activeaza host-ul. Restul tutorialului merge fara probleme in LXC, iar restore si dump acopera aceleasi nevoi.

Recuperare completa pe un server nou

Daca serverul a disparut, drumul de recuperare arata asa:

  1. Instalezi un VPS nou cu aceeasi distributie si instalezi restic.
  2. Recreezi /etc/restic/password (din managerul de parole), /etc/restic/restic.env si wrapper-ul restic-run, exact ca la Pasul 2.
  3. Restaurezi ultimul snapshot intr-un folder intermediar: sudo restic-run restore latest --target /srv/restore. Daca mai multe servere folosesc acelasi repository, adaugi --host web01.
  4. Reinstalezi pachetele, apoi copiezi la locul lor configurarile si fisierele site-urilor din /srv/restore.
  5. Importi bazele de date: sudo cat /srv/restore/var/backups/db/mysql-all.sql | sudo mariadb (sau sudo mysql pe MySQL) si sudo cat /srv/restore/var/backups/db/postgres-all.sql | sudo -u postgres psql.

Restauram intentionat intr-un folder intermediar, nu direct peste /. O restaurare peste /etc-ul unui sistem nou ar suprascrie fisiere care apartin noii masini, cum ar fi configurarea de retea.

Verificarea integritatii repository-ului

La final, poti verifica oricand structura repository-ului:

sudo restic-run check

Comanda ar trebui sa se termine cu no errors were found. Verificarea partiala saptamanala a datelor, din Pasul 5, adauga peste asta un test mai profund.

Probleme frecvente si greseli comune

  • Access Denied sau bucket does not exist la init: cheile, numele bucket-ului, URL-ul endpoint-ului sau regiunea sunt gresite. Verifica din nou /etc/restic/restic.env si seteaza AWS_DEFAULT_REGION daca furnizorul o cere.
  • wrong password or no key found: fisierul cu parola nu se potriveste cu repository-ul. L-ai regenerat cumva dupa init? Pune la loc parola originala din managerul de parole.
  • repository is already locked: ruleaza alt proces restic, sau o rulare a fost oprita brusc si a lasat o blocare veche. Verifica systemctl status restic-backup.service. Daca nu ruleaza nimic, scoti blocarea cu sudo restic-run unlock.
  • Backup-ul se termina cu codul de iesire 3: snapshot-ul s-a salvat, dar unele fisiere nu au putut fi citite (de obicei permisiuni sau fisiere sterse in timpul rularii). Jurnalul le listeaza. Din cauza lui set -e, scriptul se opreste acolo si rularea apare ca esuata, exact ce vrei sa observi.
  • Access denied for user 'root'@'localhost' la dump: root-ul bazei de date are parola in loc de autentificare prin socket. Creeaza /etc/restic/my.cnf cu o sectiune [client] care contine user si password, ruleaza chmod 600 pe el si adauga --defaults-extra-file=/etc/restic/my.cnf ca prima optiune a comenzii de dump.
  • Timer-ul nu ruleaza niciodata: probabil ai activat .service in loc de .timer. systemctl list-timers trebuie sa afiseze restic-backup.timer.
  • Memorie insuficienta pe un VPS mic: consumul de RAM al lui restic creste cu numarul de fisiere. Adauga GOGC=20 in restic.env ca sa folosesti mai putina memorie in schimbul unui pic mai mult procesor.
  • Se umple discul local: cache-ul din /var/cache/restic si dump-urile din /var/backups/db ocupa spatiu pe server. sudo restic-run cache --cleanup sterge cache-urile vechi, iar dump-urile ocupa cam cat bazele de date.

Note de securitate

  • Parola este backup-ul. Tine-o intr-un manager de parole, in afara serverului. Cu sudo restic-run key add poti adauga o a doua parola, de exemplu una pastrata de un coleg, iar key list le arata pe toate.
  • Restrictioneaza fisierele. /etc/restic trebuie sa aiba 700, iar fisierele din el 600, toate detinute de root. Dump-urile din /var/backups/db contin toata baza de date, asa ca si acel folder ramane pe 700.
  • Porneste de la ideea ca serverul poate fi compromis. Credentialele de pe server pot si sterge backup-uri, deci un atacator cu acces root ti-ar putea goli repository-ul. Protejeaza macar o copie impotriva acestui scenariu: activeaza object lock sau versionarea pe bucket, daca furnizorul le ofera, foloseste un server REST restic pornit cu --append-only, sau ruleaza prune de pe o masina separata de incredere si da serverului doar acces de scriere.
  • Stii ce anume e criptat. Continutul, numele fisierelor si structura folderelor sunt criptate. Furnizorul de stocare poate vedea totusi cate date tii si cand faci upload.
  • Tine backup-urile in alta parte. Un repository in acelasi data center cu serverul te apara de greseli, dar nu si de pierderea intregii locatii. Daca VPS-ul tau ruleaza la noi, in Romania, tine repository-ul la alt furnizor sau macar pe hardware separat.
  • Tine restic la zi, cu apt sau restic self-update, ca pe orice alt software care se ocupa de datele tale.

Deci, serverul tau chiar are backup?

Daca ai parcurs toti cei sapte pasi, da. In fiecare noapte, serverul isi face dump-urile de baze de date, trimite doar bucatile schimbate catre o stocare la distanta, criptate cu o cheie pe care o ai doar tu, si curata singur snapshot-urile vechi. Mai important, ai demonstrat deja ca iti poti recupera datele. Ce ramane e disciplina: verifica in continuare ca timer-ul reuseste (un monitor de tip push face asta automat) si repeta din cand in cand testul de restaurare.

Daca ai nevoie de un loc unde sa rulezi toate acestea, un VPS din data center-ul nostru e gata in cateva minute, iar restic merge confortabil chiar si pe cele mai mici planuri. Daca preferi ca altcineva sa stabileasca politica de backup, sa configureze stocarea externa si sa faca testele de restaurare in locul tau, echipa noastra de administrare servere se ocupa exact de asta.

Intrebari frecvente

Cat spatiu de stocare are nevoie restic?

Socoteste aproximativ dimensiunea datelor dupa compresie, plus schimbarile zilnice pastrate de politica de retentie. Pentru un server web obisnuit cu 10 GB de date si schimbari zilnice moderate, o luna de snapshot-uri zilnice incape adesea in 8-15 GB. Ruleaza sudo restic-run stats --mode raw-data ca sa vezi cifra reala pentru repository-ul tau.

E restic mai bun decat rsync sau BorgBackup?

Pentru backup, restic bate rsync, pentru ca pastreaza istoric si cripteaza datele. BorgBackup e o alternativa excelenta, cu deduplicare asemanatoare. Avantajul lui restic este suportul nativ pentru stocare compatibila S3 si pentru multe alte backend-uri, fara nimic instalat pe partea de destinatie.

Ce se intampla daca un backup e intrerupt?

Nu se strica nimic. Restic inregistreaza un snapshot doar dupa ce toate datele lui au fost urcate, asa ca o rulare intrerupta lasa doar cateva bucati nefolosite, pe care le curata un prune ulterior. Daca ramane o blocare veche, restic unlock o elimina, iar urmatoarea rulare continua normal.

Pot face backup la volume Docker cu restic?

Da. Folderele montate prin bind mount le salvezi ca pe orice alt director, iar pentru containerele de baze de date folosesti dump-uri (prin docker exec), nu copii ale fisierelor de date active. Volumele cu nume se afla in /var/lib/docker/volumes, iar calea poate fi adaugata in lista, ideal pentru volumele care nu contin baze de date pornite.

Avem Incredere & Suntem Membri

Suntem membri ai principalelor organizatii de infrastructura internet.

RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX RIPE NCC MANRS PeeringDB RoTLD DSIX SBIX 4IXP LOCIX Euro-IX