Come configurare backup Restic su VPS con Ubuntu 24.04
Proteggi i dati del tuo VPS con Restic. Questa guida spiega come automatizzare backup crittografati e deduplicati verso storage esterni usando systemd e SFTP.
Perché un backup sullo stesso server non è un backup
Restic è uno strumento di backup gratuito e open source che invia snapshot crittografici e deduplicati dei file a un repository esterno: un secondo VPS, una macchina di casa oppure uno storage a oggetti compatibile con S3. Questa guida illustra la configurazione su Ubuntu 24.04, dall'installazione alla creazione di un repository tramite SFTP, dal primo backup a un timer systemd eseguito ogni notte, fino alla definizione di una policy di conservazione e alla procedura di ripristino che verifica il corretto funzionamento dell'intero sistema. La destinazione deve essere un'altra macchina, perché una copia che risiede sullo stesso server viene persa insieme al server.
Una directory backup/ sulla macchina di cui esegui il backup protegge da un solo problema: l'eliminazione accidentale di un file. Non sopravvive al guasto del disco, perché si trova sullo stesso disco. Non sopravvive a un attaccante con accesso root, perché le copie vengono eliminate per prime. Non sopravvive a un errore dell'account che rimuove il VPS stesso. Il datacenter meno efficiente del mondo scherza su un archivio tar denominato backup_final_v2_REAL che si trova sullo stesso array dei dati. La battuta funziona perché molti di noi hanno eseguito esattamente questa procedura. La regola è mantenere la copia fuori dalla macchina, e restic è il modo meno problematico per rispettarla.
Restic in quattro concetti
Repository. È la destinazione in cui restic scrive i dati. È una directory nel formato proprietario di restic, piena di blob crittografati, che soltanto restic può leggere. Non modificarla mai manualmente: accedici tramite i comandi restic e l'indirizzo -r.
Snapshot. È la fotografia dei file sottoposti a backup in un preciso momento. Ogni esecuzione del backup crea uno snapshot. Ogni snapshot può essere ripristinato autonomamente e si comporta come una copia completa dei dati in quell'istante.
Deduplicazione. Restic divide i file in chunk definiti dal contenuto e carica soltanto quelli che il repository non contiene già. Il primo backup carica tutto. Le esecuzioni successive caricano all'incirca solo ciò che è cambiato. Uno snapshot notturno di 20 GB con 50 MB modificati occupa circa 50 MB. Per questo è economico conservare decine di snapshot.
Crittografia predefinita. Un repository restic è sempre crittografato (AES-256). Restic rifiuta di creare o aprire un repository con una password vuota, a meno che non venga passato --insecure-no-password (restic 0.17.0 e versioni successive). Un repository configurato come descritto in questa guida richiede quindi la password per ogni comando. L'host che esegue il backup o il provider di storage vede soltanto blob crittografati. La conseguenza è definitiva: se perdi la password, i dati sono persi per sempre, per progettazione. Conserva una copia della password in un luogo diverso da questo server. È un aspetto così importante che verrà richiamato altre due volte più avanti.
Installare restic su Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionSu Ubuntu 24.04 questo comando installa restic 0.16.4, mentre la versione upstream attuale è 0.19.1. La differenza esiste perché una versione LTS (long term support) blocca le versioni dei pacchetti. In questo caso non è un problema: 0.16.4 include tutte le funzionalità necessarie per questa guida. Se vuoi usare la versione più recente per beneficiare dei miglioramenti in termini di velocità, scarica il build ufficiale a binario singolo dalla pagina delle release di restic su GitHub, decomprimilo con bunzip2 e installalo in /usr/local/bin/restic. Per installare restic non serve altro.
Creazione del repository su un altro server via SFTP
È necessaria una macchina di destinazione: una seconda piccola VPS è la soluzione standard, e qualsiasi server con un demone SSH e spazio disco disponibile è idoneo. Restic utilizza il protocollo SFTP (file transfer over SSH), pertanto l'host di backup non richiede l'installazione di alcun software aggiuntivo. In questa guida l'host di backup è 10.0.0.12 con un utente denominato restic. Non assegnare a tale utente il nome backup: Ubuntu e Debian includono un account di sistema riservato chiamato backup (uid 34, shell di login non disponibile) in ogni installazione, pertanto adduser backup fallisce e la sessione SSH dell'utente ssh backup@... termina nella shell nologin.
Il job notturno verrà eseguito come root sul server di cui si effettua il backup, quindi l'utente root necessita dell'accesso tramite chiave SSH verso l'host di backup. Crea una chiave dedicata senza passphrase, poiché non è presente alcun operatore alle 3 del mattino per digitarla, e copiala sul server remoto:
sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login worksSe non hai familiarità con le chiavi SSH, le basi della gestione delle chiavi SSH spiegano il modello, i permessi e come revocare una chiave in futuro.
Successivamente, occorre definire la password del repository. Generane una robusta all'interno di un file accessibile solo da root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordCopia ora questa password nel tuo gestore di password prima di procedere. Se questa VPS dovesse guastarsi, il repository insieme a questa password permetterà di ripristinare tutto; il repository senza la password non consente alcun recupero.
Inizializza il repository:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1La destinazione alternativa è lo storage a oggetti compatibile con S3, che rappresenta la scelta corretta quando non si desidera gestire una seconda macchina. Qualsiasi bucket compatibile con S3 funziona allo stesso modo; cambiano solo l'indirizzo e due variabili di credenziali:
export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password initTutto ciò che segue init è identico per entrambe le destinazioni. Il resto di questa guida utilizza l'indirizzo SFTP; sostituiscilo con il tuo.
Il primo backup, con le esclusioni
Esegui il backup dei dati che non puoi reinstallare, non dell'intero filesystem. Il sistema operativo viene ripristinato con una reinstallazione; la configurazione e i dati no. In un VPS tipico, questo significa /etc, /home e le directory in cui le applicazioni archiviano il proprio stato, ad esempio /srv o /var/www. Escludi le cache, perché occupano molto spazio, cambiano ogni giorno e vengono ricreate automaticamente:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'Files: 4181 new, 0 changed, 0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c savedLa prima esecuzione carica tutti i dati, quindi richiede tempo. Esegui di nuovo lo stesso comando: terminerà in pochi secondi e segnalerà alcuni file modificati e alcuni MiB aggiunti, perché la deduplicazione carica solo i nuovi chunk. Elenca ciò che hai:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsOgni snapshot mostra un ID, un orario e i percorsi che contiene. Sono questi gli ID da cui eseguire il ripristino.
Esecuzioni notturne con un timer systemd
Digitare l'indirizzo del repository in ogni comando diventa rapidamente scomodo, mentre un backup eseguito manualmente smette di essere eseguito entro un mese. Un unico script e un unico timer risolvono entrambi i problemi. Lo script imposta le due variabili d'ambiente che restic legge, RESTIC_REPOSITORY e RESTIC_PASSWORD_FILE, così ogni comando al suo interno resta breve:
sudo nano /usr/local/bin/restic-backup.sh#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic checksudo chmod 700 /usr/local/bin/restic-backup.shLe righe forget e check sono spiegate nelle due sezioni successive. Ora è il momento della pianificazione: un servizio oneshot che esegue lo script e un timer che lo avvia ogni notte alle 03:00. In questo caso un timer è preferibile a una riga cron perché l'esecuzione viene registrata nel journal e Persistent=true esegue il backup saltato non appena il server torna operativo dopo un periodo di inattività.
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup
[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.targetAbilita il timer, quindi esegui manualmente il servizio una volta e monitorane l'esecuzione:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers mostra quando verrà eseguita la prossima esecuzione. In alternativa, puoi generare la coppia di file di unità invece di crearli manualmente:
Il modello completo alla base di questi due file, inclusa la sintassi del calendario e le direttive di hardening che un servizio può supportare, è disponibile in esecuzione di un programma come servizio systemd su un VPS.
Un backup è solo un'ipotesi finché non lo ripristini
Considera questa frase una regola fondamentale. Un job di backup che termina correttamente ogni notte dimostra soltanto che il job è stato eseguito. Non dimostra che i dati possano essere ripristinati. Due controlli colmano questa lacuna.
Primo, restic check, che lo script esegue già ogni notte. Verifica la struttura del repository e l'indice. In questo modo rileva la corruzione silenziosa sull'host di backup la notte successiva, invece che il giorno del ripristino. Una volta al mese, esegui la variante più approfondita, che scarica e verifica crittograficamente un decimo casuale dei dati effettivi:
sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%Poiché il sottoinsieme viene scelto casualmente a ogni esecuzione, la documentazione di restic specifica che le esecuzioni ripetute non garantiscono la verifica di ogni pack file, indipendentemente dal loro numero. Se vuoi che le esecuzioni mensili analizzino l'intero repository senza pagare mai il costo di un download completo, usa invece la forma con gruppo fisso: --read-data-subset=1/10 un mese, 2/10 il mese successivo e così via fino a 10/10. Restic divide i pack file in dieci gruppi di dimensioni approssimativamente uguali e controlla soltanto il gruppo n. Un ciclo completo di dieci esecuzioni legge quindi ogni gruppo una volta.
Secondo, la prova di ripristino. Sempre nella shell root usata sopra, ripristina una directory reale dall'ultimo snapshot in una posizione temporanea e confrontala con i file attivi:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshSe diff non stampa nulla, ogni byte è stato ripristinato in modo identico. Questa è l'unica verifica realmente valida. Elimina /srv/restore-drill al termine. Esegui questa prova ogni mese. Una o due volte l'anno, esegui la variante completa: ripristina l'intero snapshot più recente su una VPS temporanea e verifica che l'applicazione si avvii effettivamente da quella copia. Quando dovrai farlo sotto pressione, sarà importante avere già eseguito questa procedura.
Conservazione: forget e prune
Senza una policy, gli snapshot si accumulano indefinitamente e il repository continua a crescere. La riga forget dello script applica ogni notte una policy: --keep-daily 7 conserva uno snapshot al giorno degli ultimi sette giorni, --keep-weekly 4 uno alla settimana per quattro settimane e --keep-monthly 6 uno al mese per sei mesi. Tutto ciò che non è protetto da una regola viene dimenticato.
forget da solo rimuove soltanto i record degli snapshot; i blocchi di dati restano nel repository finché un'operazione non li elimina. Questo è il compito di --prune: individua i blocchi a cui nessuno snapshot fa più riferimento e li elimina. Solo a quel punto lo spazio su disco viene effettivamente liberato. Prune esegue operazioni reali sul repository, quindi su un repository di grandi dimensioni alcuni amministratori eseguono forget ogni notte e --prune ogni settimana; con le dimensioni tipiche dei VPS, l'esecuzione notturna va bene.
Database: prima il dump, poi il backup del dump
Restic copia i file mentre li legge, mentre un database scrive continuamente nei propri file. Se un file del database viene acquisito durante una scrittura, al ripristino il database risulta corrotto, perché la copia combina pagine precedenti e successive alla scrittura. La soluzione standard consiste nel fare produrre al motore del database un'esportazione coerente in un file, quindi lasciare che restic esegua il backup di quel file.
Per PostgreSQL, aggiungi una riga per il dump all'inizio di restic-backup.sh, prima del comando restic backup, e includi la directory del dump nei percorsi di backup:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump svolge lo stesso ruolo per MariaDB e MySQL. Per un esempio completo dell'intera procedura, la sezione sul backup di Nextcloud attiva la modalità di manutenzione, esegue il dump di Postgres e copia i file come un unico insieme coerente, cioè esattamente l'insieme che restic deve trasferire dal server ogni notte. Con SQLite il principio è lo stesso, ma la procedura è più semplice: la guida a Vaultwarden arresta il container per alcuni secondi per creare una copia a freddo di db.sqlite3, quindi restic trasferisce quell'archivio dal server.
FAQ
I backup restic sono crittografati?
Sì, sempre. Ogni repository restic è crittografato con AES-256 e non esiste una modalità non crittografata. Restic rifiuta inoltre una password vuota, a meno che non venga passato --insecure-no-password (disponibile da restic 0.17.0), quindi un repository configurato come descritto in questa guida richiede la password per ogni comando. La macchina o il provider che conserva il repository contiene soltanto blob crittografati. La compromissione dell'host di backup non espone quindi i file. Il compromesso è assoluto: senza la password, nessuno può recuperare i dati. Conserva una copia della password al di fuori del server.
Restic esegue backup incrementali?
Ogni snapshot restic si comporta come un backup completo, ma richiede spazio incrementale. Restic divide i file in chunk e carica soltanto quelli che il repository non contiene già. Un'esecuzione notturna trasferisce quindi all'incirca ciò che è cambiato quel giorno. A differenza degli schemi incrementali tradizionali, non esiste una catena da ricostruire: ogni snapshot viene ripristinato direttamente e l'eliminazione di uno snapshot precedente non danneggia quelli successivi.
Come posso ripristinare i file da un backup restic?
Esegui restic snapshots per trovare l'ID dello snapshot, quindi restic restore <id> --target /some/empty/dir per ripristinarlo. Aggiungi --include /path per ripristinarne soltanto una parte. latest può essere usato al posto dell'ID. Restic ricrea la struttura originale delle directory nella destinazione indicata, quindi il ripristino di /etc/ssh produce /some/empty/dir/etc/ssh. Esegui una prova prima di averne bisogno: un backup non verificato è solo un'ipotesi.
Con quale frequenza devo eseguire restic backup?
Per un server, la frequenza minima ragionevole è ogni notte. La deduplicazione mantiene bassi i costi, perché ogni esecuzione carica soltanto i chunk modificati dall'ultima esecuzione. I dati che cambiano rapidamente o la cui perdita anche per un solo giorno sarebbe problematica possono essere sottoposti a backup ogni poche ore usando lo stesso schema di timer. La frequenza è soltanto una parte della soluzione: esegui regolarmente anche restic check e una prova di ripristino ogni mese. Una pianificazione senza verifica dà solo una falsa sensazione di sicurezza.
Cosa succede se perdo la password del repository restic?
I backup non possono essere recuperati. La crittografia di restic non dispone di backdoor né di una procedura di reimpostazione. La password è quindi importante quanto i backup stessi. Conservane una copia nel password manager e in un altro luogo durevole, diverso dal server sottoposto a backup. Finché hai ancora accesso al repository, restic key add può registrare una seconda password per lo stesso repository e fornirti così una credenziale di riserva.