Backup Restic del VPS su un server esterno
Configura Restic su Ubuntu 24.04: backup cifrati e deduplicati via SFTP, timer systemd notturno, conservazione e ripristino verificato su un'altra macchina.
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 posizione in cui restic scrive i dati. È una directory nel formato proprietario di restic, composta da blob crittografati che solo restic può leggere. Non modificarla mai manualmente: accedi al repository tramite i comandi restic e l'indirizzo -r.
Snapshot. È la fotografia dei file di cui hai eseguito il backup in un determinato momento. Ogni esecuzione del backup crea uno snapshot. Ogni snapshot può essere ripristinato autonomamente e si comporta come una copia completa dei dati in quel momento.
Deduplicazione. Restic suddivide i file in chunk definiti dal contenuto e carica solo quelli che il repository non contiene ancora. Il primo backup carica tutti i dati. Ogni esecuzione successiva carica in genere solo i dati modificati. Uno snapshot notturno da 20 GB con 50 MB modificati richiede circa 50 MB di spazio aggiuntivo. Per questo è conveniente conservare decine di snapshot.
Crittografia attiva per impostazione predefinita. Un repository restic è sempre crittografato con AES-256 e ogni comando richiede la password del repository. L'host che esegue il backup o il provider di storage vede esclusivamente blob crittografati. La conseguenza è importante: se perdi la password, i dati sono persi definitivamente, per progettazione. Conserva una copia della password in una posizione diversa 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.
Crea il repository su un altro server tramite SFTP
Serve una macchina di destinazione: in genere si usa una seconda VPS di piccole dimensioni, ma va bene qualsiasi sistema con un server SSH e spazio su disco disponibile. Restic supporta SFTP (trasferimento di file tramite SSH), quindi sul server di backup non è necessario installare nulla. In questa guida il server di backup è 10.0.0.12 e l'utente si chiama restic. Non chiamare l'utente backup: Ubuntu e Debian installano in ogni sistema l'account di sistema riservato backup (uid 34, senza shell di login), quindi adduser backup non funziona e ssh backup@... crea la directory nologin.
Il job notturno verrà eseguito come root sul server di cui viene eseguito il backup, quindi root deve poter accedere tramite chiave al server di backup. Crea una chiave dedicata senza passphrase, perché alle 3am non ci sarà nessuno a inserirla, quindi 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 worksSe non hai mai usato le chiavi, Nozioni di base sulla gestione delle chiavi SSH spiega il modello, i permessi e come revocare una chiave in seguito.
Ora crea la password del repository. Generane una robusta in un file accessibile solo a root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordCopia ora questa password nel tuo password manager, prima di procedere. Se questa VPS si guasta, il repository e questa password consentono di ripristinare tutto; il repository senza la password non consente di ripristinare nulla.
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/web1L'alternativa è l'object storage compatibile con S3, la scelta corretta quando non vuoi gestire una seconda macchina. Qualsiasi bucket compatibile con S3 funziona nello stesso modo; cambiano solo l'indirizzo e le due variabili delle 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 mostra 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 viene ripristinato
Considera questa frase un principio fondamentale. Un job di backup che termina correttamente ogni notte dimostra solo che il job è stato eseguito; non dimostra che i dati possano essere recuperati. Due verifiche colmano questa lacuna.
La prima è restic check, che lo script esegue già ogni notte. Verifica la struttura del repository e l’indice, quindi rileva la corruzione silenziosa sull’host di backup la notte successiva, invece che il giorno del ripristino. Una volta al mese, esegui la versione 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 ogni volta, le esecuzioni mensili analizzano progressivamente l’intero repository senza dover mai sostenere il costo di un download completo.
La seconda è la prova di ripristino. Sempre nella shell root precedente, ripristina una directory reale dell’ultimo snapshot in una posizione temporanea e confrontala con i file in produzione:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshdiff che non stampa nulla significa che ogni byte è stato ripristinato in modo identico. Questa è l’unica prova che conta. Successivamente, elimina /srv/restore-drill. Esegui questa prova ogni mese. Una o due volte all’anno esegui la versione completa: ripristina l’intero snapshot più recente su una VPS temporanea e verifica che l’applicazione si avvii effettivamente da quel ripristino. Quando dovrai farlo in condizioni di pressione, vorrai che sia una procedura già eseguita di routine.
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 di restic sono crittografati?
Sì, sempre. Ogni repository restic è crittografato con AES-256; non esiste una modalità non crittografata e ogni comando richiede la password del repository. La macchina o il provider che archivia il repository contiene esclusivamente blob crittografati, quindi un host di backup compromesso non espone i file. Il compromesso è netto: senza la password nessuno può recuperare i dati, quindi conserva una copia lontano dal server.
restic esegue backup incrementali?
Ogni snapshot restic si comporta come un backup completo, ma richiede spazio incrementale. Restic suddivide i file in chunk e carica soltanto quelli che il repository non contiene già, quindi un'esecuzione notturna trasferisce all'incirca ciò che è cambiato durante la giornata. 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 compromette 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, aggiungendo --include /path per ripristinarne soltanto una parte. latest funziona al posto di un ID. Restic ricrea la struttura originale delle directory nella destinazione, quindi il ripristino di /etc/ssh viene eseguito in /some/empty/dir/etc/ssh. Prova questa procedura prima di averne bisogno, perché un backup non verificato è soltanto un'ipotesi.
Con quale frequenza devo eseguire restic backup?
Per un server, l'esecuzione notturna è il minimo ragionevole e la deduplicazione ne riduce i costi: ogni esecuzione carica soltanto i chunk modificati dall'esecuzione precedente. 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 è solo metà del lavoro: esegui regolarmente anche restic check e una prova di ripristino ogni mese, perché una pianificazione senza verifica dà una falsa sicurezza.
Cosa succede se perdo la password del repository restic?
I backup non possono essere recuperati. La crittografia di restic non prevede backdoor né reimpostazioni, quindi la password è importante quanto i backup stessi. Conservane una copia nel password manager e in un'altra posizione durevole che non sia il server sottoposto a backup. Finché hai ancora accesso, restic key add può registrare una seconda password per lo stesso repository, fornendoti una password di riserva.