SSD Nodes Learn
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-07-24

Come fare backup VPS con Restic

Usa Restic su Ubuntu 24.04 per inviare snapshot criptati e deduplicati su storage S3 o SFTP. Configura timer systemd e verifica il restore dei dati.

Perché un backup sullo stesso server non è un backup

Restic è uno strumento di backup open source e gratuito. Invia snapshot criptati e deduplicati dei file verso un repository esterno: un secondo VPS, una macchina domestica o uno storage a oggetti compatibile con S3. Questa guida ne illustra la configurazione su Ubuntu 24.04, dall'installazione alla creazione di un repository via SFTP, includendo il primo backup, un timer systemd notturno, una policy di retention e la procedura di restore per verificare il corretto funzionamento. La destinazione deve essere una macchina diversa, poiché una copia salvata sullo stesso server viene persa insieme al server stesso.

Una directory backup/ sulla macchina di origine protegge solo da un evento: l'eliminazione accidentale di un file. Non garantisce la sicurezza in caso di guasto del disco, poiché i dati risiedono su quel disco. Non garantisce la sicurezza contro un attaccante con privilegi root, poiché l'attaccante eliminerà prima le copie. Non garantisce la sicurezza in caso di errore amministrativo che comporta la rimozione del VPS stesso. Il datacenter meno efficiente al mondo scherza su un archivio tar denominato backup_final_v2_REAL salvato sullo stesso array dei dati; lo scherzo è efficace perché molti utenti hanno commesso esattamente questo errore. La regola è salvare i dati su una macchina esterna, e restic è il metodo più semplice per applicarla.

Restic in quattro concetti

Repository. Il luogo in cui restic scrive i dati. È una directory nel formato proprietario di restic, composta da blob criptati, leggibile solo da restic. Non modificare mai il repository manualmente; interagisci con esso tramite i comandi restic e l'indirizzo -r.

Snapshot. Una rappresentazione dei file in un preciso istante temporale. Ogni esecuzione del backup crea uno snapshot; ogni snapshot può essere ripristinato singolarmente e ogni snapshot si comporta come una copia completa dei dati in quel momento.

Deduplicazione. Restic divide i file in chunk definiti dal contenuto e carica solo i chunk non presenti nel repository. Il primo backup carica tutti i dati; ogni esecuzione successiva carica solo le parti modificate. Uno snapshot notturno da 20 GB con 50 MB di modifiche occupa circa 50 MB; per questo motivo conservare decine di snapshot è economico.

Crittografia predefinita. Un repository restic è sempre criptato (AES-256) e ogni comando richiede la password del repository. L'host di backup o il provider di storage vedono solo blob criptati. La conseguenza diretta: se si perde la password, i dati sono persi definitivamente per design. Conserva una copia della password in un luogo diverso da questo server. Questo aspetto è fondamentale e viene menzionato altre due volte di seguito.

Install restic on Ubuntu 24.04

sudo apt update && sudo apt install -y restic
restic version

Su Ubuntu 24.04 viene installata la versione 0.16.4 di restic, mentre l'ultima release ufficiale è la 0.19.1. La differenza è dovuta al fatto che una release LTS (long term support) blocca le versioni dei pacchetti. Tuttavia, la versione 0.16.4 è sufficiente per eseguire tutte le operazioni descritte in questa guida. Se si desidera la versione più recente per i miglioramenti delle prestazioni, scaricare il file binario singolo dalla pagina GitHub releases del progetto restic, estrarlo con bunzip2 e installarlo in /usr/local/bin/restic; l'installazione di restic non richiede ulteriori passaggi.

Crea il repository su un altro server tramite SFTP

È necessaria una macchina di destinazione: un secondo piccolo VPS è la soluzione standard; è sufficiente un server con un servizio SSH e spazio disco disponibile. Restic utilizza il protocollo SFTP (file transfer over SSH), quindi l'host di backup non richiede alcuna installazione. In questa guida, l'host di backup è 10.0.0.12 con un utente denominato restic. Non nominare l'utente backup: Ubuntu e Debian includono un account di sistema riservato chiamato backup (uid 34, no login shell) in ogni installazione; pertanto adduser backup fallisce e ssh backup@... finisce in nologin.

Il job notturno verrà eseguito come root sul server di backup, quindi root deve poter effettuare il login tramite chiave sull'host di backup. Crea una chiave dedicata senza passphrase, poiché nessun utente sarà presente alle 3am per digitarla, e copiala sul server:

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 works

Se non hai esperienza con le chiavi, concetti base della gestione delle chiavi SSH spiega il modello, i permessi e come revocare una chiave in seguito.

Successivamente, la password del repository. Generane una sicura in un file accessibile solo a root:

openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-password

Copia la password nel tuo password manager prima di procedere. Se questo VPS viene distrutto, il repository insieme a questa password permette il ripristino totale; il repository senza password non permette alcun ripristino.

Inizializza il repository:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password init
created restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1

L'alternativa è l'object storage compatibile con S3, la scelta corretta se 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 init

Tutto ciò che segue init è identico per entrambe le destinazioni. Il resto di questa guida mostra l'indirizzo SFTP; sostituiscilo con il proprio.

Il primo backup, con esclusioni

Esegui il backup dei dati che non possono essere reinstallati, non dell'intero filesystem. Il sistema operativo può essere ripristinato tramite reinstallazione; le configurazioni e i dati no. Per un tipico VPS, questo significa /etc, /home e le directory dove le applicazioni salvano lo stato, come /srv o /var/www. Escludi le cache, poiché sono voluminose, cambiano ogni giorno e vengono ricostruite 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 saved

La prima esecuzione carica tutto il contenuto, quindi richiede tempo. Esegui nuovamente lo stesso comando: la procedura terminerà in pochi secondi, indicando solo i file modificati e i MiB aggiunti, poiché la deduplicazione carica solo i nuovi chunk. Elenca i backup presenti:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshots

Ogni snapshot mostra un ID, un timestamp e i percorsi contenuti. Gli ID sono necessari per il ripristino.

Esecuzioni notturne con un timer systemd

Digitare l'indirizzo del repository per ogni comando è inefficiente. Un backup eseguito manualmente smette di essere costante dopo un mese. Entrambi i problemi si risolvono con uno script e un timer. Lo script imposta le due variabili d'ambiente lette da restic, RESTIC_REPOSITORY e RESTIC_PASSWORD_FILE, così ogni comando interno rimane 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 check
sudo chmod 700 /usr/local/bin/restic-backup.sh

Le righe forget e check sono spiegate nelle prossime due sezioni. Per quanto riguarda la pianificazione: un servizio oneshot che esegue lo script e un timer che lo avvia ogni notte alle 03:00. Un timer è preferibile a una riga cron perché i log di esecuzione vengono salvati nel journal e Persistent=true avvia un backup saltato non appena il server riprende l'attività dopo un downtime.

# /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.target

Abilitare il timer, quindi eseguire il servizio una volta manualmente per verificarne il funzionamento:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -f

systemctl list-timers indica quando avverrà la prossima esecuzione. È possibile generare la coppia di file unit invece di digitarli manualmente:

ToolGenerate the backup service and timer

Il modello completo utilizzato per questi due file, inclusa la sintassi del calendario e le direttive di hardening per i servizi, è disponibile in eseguire un programma come servizio systemd su un VPS.

Un backup è solo un rumor fino al restore

Considera questa frase come un comando. Un job di backup che termina con esito positivo ogni notte dimostra solo che il job è stato eseguito; non garantisce il recupero dei dati. Due controlli eliminano questo rischio.

Primo, restic check, che lo script esegue già ogni notte. Verifica la struttura del repository e l'index, così la corruzione silenziosa sul host di backup viene rilevata la notte successiva invece che durante il restore. Una volta al mese, esegui la versione 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 subset è casuale ogni volta, le esecuzioni mensili coprono l'intero repository senza richiedere il download completo.

Secondo, la prova di restore. Sempre dalla root shell indicata 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/ssh

Se diff non stampa nulla, significa che ogni byte è stato recuperato in modo identico; questa è l'unica prova valida. Elimina /srv/restore-drill al termine. Esegui questa prova mensilmente e una o due volte all'anno esegui la versione completa: ripristina l'intero ultimo snapshot su un VPS temporaneo e verifica che l'applicazione si avvii correttamente da esso. Il giorno in cui avrai bisogno di questo sistema sotto pressione, deve essere una procedura di routine già testata.

Retention: forget e prune

Senza una policy, gli snapshot si accumulano all'infinito e il repository cresce costantemente. La riga forget dello script applica una policy ogni notte: --keep-daily 7 mantiene uno snapshot al giorno per gli ultimi sette giorni, --keep-weekly 4 uno a settimana per quattro settimane e --keep-monthly 6 uno al mese per sei mesi. Tutto ciò che non è protetto da una regola viene eliminato.

forget da solo rimuove solo i record degli snapshot; i chunk dei dati rimangono nel repository finché qualcosa non li elimina. Questo è il compito di --prune: trova i chunk senza riferimenti a snapshot esistenti e li elimina, liberando effettivamente lo spazio su disco. Prune esegue l'operazione reale sul repository; per repository di grandi dimensioni, alcuni utenti eseguono forget ogni notte e --prune ogni settimana; per dimensioni tipiche di un VPS, l'esecuzione nightly è sufficiente.

Databases: eseguire il dump, poi eseguire il backup del dump

Restic copia i file durante la lettura, mentre un database scrive sui propri file continuamente. Un file di database attivo catturato durante una scrittura si ripristina come database corrotto, poiché la copia mescola pagine scritte prima e dopo l'operazione. La soluzione standard consiste nel far generare al motore del database un export coerente in un file, quindi lasciare che restic esegua il backup di quel file.

Per PostgreSQL, aggiungere una riga di dump all'inizio di restic-backup.sh, prima del comando restic backup, e includere 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.gz

mysqldump svolge la stessa funzione per MariaDB e MySQL. Per un esempio pratico dell'intero processo, la sezione di backup di Nextcloud attiva la modalità manutenzione, esegue il dump di Postgres e copia i file come un unico set coerente, esattamente il set che restic deve trasferire fuori dal sistema ogni notte. Per SQLite il concetto è identico ma con un approccio più semplice: la guida per Vaultwarden arresta il container per alcuni secondi per effettuare una copia a freddo di db.sqlite3, e quell'archivio è ciò che restic invia fuori dal server.

FAQ

I backup di restic sono criptati?

Sì, sempre. Ogni repository restic è criptato con AES-256. Non esiste una modalità non criptata e ogni comando richiede la password del repository. La macchina o il provider che ospita il repository contiene solo blob criptati; pertanto, un host di backup compromesso non espone i file. Il compromesso è assoluto: senza la password i dati non possono essere recuperati da nessuno. Conserva una copia della password in un luogo sicuro, separato dal server.

restic esegue backup incrementali?

Ogni snapshot di restic si comporta come un backup completo, pur occupando spazio in modo incrementale. Restic divide i file in chunk e carica solo i chunk che il repository non ha ancora memorizzato. Di conseguenza, un backup notturno trasferisce solo i dati modificati durante il giorno. A differenza dei tradizionali schemi incrementali, non esiste una catena da riprodurre: ogni snapshot permette il ripristino diretto e l'eliminazione di uno snapshot vecchio non compromette quelli più recenti.

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 ripristinare solo una parte di esso. latest può essere usato al posto di un ID. Restic ricrea la struttura delle directory originale sotto la destinazione; ad esempio, il ripristino di /etc/ssh avverrà in /some/empty/dir/etc/ssh. Esegui delle prove prima di farne necessario il ripristino, poiché un backup non testato è solo un'ipotesi.

Ogni quanto devo eseguire restic backup?

L'esecuzione notturna è il limite minimo consigliato per un server. La deduplicazione rende il processo economico: ogni esecuzione carica solo i chunk modificati rispetto alla precedente. Per i dati che cambiano rapidamente, o per i quali la perdita di un solo giorno sarebbe critica, è possibile eseguire il backup ogni poche ore con lo stesso intervallo temporale. La frequenza è la parte semplice; esegui regolarmente anche restic check e una prova di ripristino mensile, poiché una pianificazione senza verifica è un falso conforto.

Cosa succede se perdo la password del repository restic?

I backup non sono recuperabili. La criptazione di restic non prevede backdoor né funzioni di reset; la password è importante quanto i backup stessi. Conserva una copia nel tuo password manager o in qualsiasi altro supporto duraturo che non sia il server di backup. Finché hai ancora accesso, restic key add può registrare una seconda password per lo stesso repository, fornendoti una copia di riserva.