In questa sezione sono raccolti alcuni articoli su come fare backup locali e in rete con rsnapshot, rsync e dar. Oltre alle procedure, sono indicati alcuni suggerimenti per migliorare le nostre strategie di backup e di disaster recovery.
Quanto scritto può essere applicato su qualsiasi sistema unix, come gnu/linux e Mac Os X. In particolare, io ho usato questi metodi per fare backup in rete di sistemi Debian, Mandriva e Mac Os X 10.3 Panther, ma ho letto di persone che hanno usato le stesse soluzioni anche con MS Windows.
Per i backup da tenere a "breve" termine gli snapshot vanno benissimo: sono facili da fare, ed è facile il ripristino in caso di necessità. Per backup a più lungo termine, per esempio su dischi esterni o su DVD, ci vuole un approccio diverso: gli archivi. In questa pagina vediamo come creare archivi in gnu/linux con dar, un ottimo programma di archiviazione ispirato a tar, ma con molte interessanti e vantaggiose funzioni.
Al contrario delle copie snapshot, gli archivi spesso sono file "monolitici" o separati in più parti di dimensioni pari al supporto (CD, DVD, ...) cui sono destinati, sono compressi e hanno accorgimenti utili a verificare l'integrità dell'archivio, per prevenire le perdite di dati.
Riguardo a questa differenza, e riguardo ad altri accorgimenti importanti quando si fanno backup, vedere: Good Backup Practice Short Guide
Come detto in una articolo recente, la mia politica di backup è fare snapshot settimanali e
mensili.
Successivamente, ogni 4 mesi, viene creato un pacchetto dar compresso con gzip
dallo snapshot più recente (/mnt/backup/private/snapshots/weekly.0/castor) per
ogni directory salvata, e tenuto nello stesso hard disk secondario degli
snapshot.
Periodicamente, e manualmente, masterizzo gli archivi di dar su DVD.
Se non vogliamo creare degli archivi compressi, ma vogliamo comunque copiare i nostri dati su CD/DVD, può esserci utile usare dirsplit per dividere directory di grandi dimensioni in tante directory più piccole che possano essere contenute nei CD/DVD. Per maggior sicurezza, usiamo dvdisaster per proteggere i supporti.
Semplicemente, chiamo questo script (/root/backup_script/backup_dar.sh)
periodicamente con anacron:
#!/bin/bash
# crea archivi dar dallo snapshot più recente
# imposta alcune variabili utili
BKPATH=/mnt/backup/darchivi
RADICE=/mnt/backup/private/snapshots/weekly.0
CONFIG=/root/backup_script/dar_config.dcf
DATA=`date -I`
# sposta temporaneamente i vecchi archivi
for i in `ls $BKPATH/*.dar`
do
mv $i old.$i
done
# crea i nuovi archivi
dar --create $BKPATH/home-$DATA --fs-root $RADICE/castor --go-into home --batch $CONFIG
dar --create $BKPATH/sistema-$DATA --fs-root $RADICE/castor --go-into etc \
--go-into root --batch $CONFIG
dar --create $BKPATH/dati-$DATA --fs-root $RADICE/castor --go-into mnt/win_d --batch $CONFIG
dar --create $BKPATH/linutop-$DATA --fs-root $RADICE/ --go-into linutop \
--go-into linutop-dpkg \
--go-into linutop-mysql --batch $CONFIG
dar --create $BKPATH/pollux-$DATA --fs-root $RADICE/pollux --go-into Users --batch $CONFIG
# rimuove i vecchi archivi
rm old.*.dar
exit
Questo è il contenuto del mio file di configurazione di dar,
/root/backup_script/dar-config.dcf (i commenti dovrebbero essere sufficienti a capire cosa fa):
###############################
# file di configurazione per dar
# chiamare con l'opzione --batch dar_config.dcf
###############################
# Opzioni per qualsiasi azione
all:
# Fa un beep quando c'e' bisogno di un intervento dell'utente
--beep
# Restituisce un output dettagliato di quello che fa
#--verbose
###############################
##### Opzioni di creazione ####
create:
# --fs-root /
# Rimane sul file system corrente
--no-mount-points
#### SLICE ####
# Dividi gli archivi in slice da 680MB (per stare in CD-R da 700MB)
#--slice 680M
# per i DVD-R
--slice 4300M
# crea file di controllo con par2, appoggiandosi allo script dar_par_create.duc
# la ridondanza è fissata al 2%
--execute "/root/backup_script/dar_par_create.duc %p %b %n %e %c 2"
# con slice da 4300M i file par creati sono <100M
#### COMPRESSIONE ####
# Comprimi i file con gzip
--gzip=6
# a list of file to not try to compress (-Z == --exclude-compression)
-Z "*.bz2" -Z "*.dar" -Z "*.gz" -Z "*.rar" -Z "*.tbz" -Z "*.tgz" -Z "*.zip" -Z "*.ZIP"
-Z "*.deb" -Z "*.rpm"
# ho molti video avi non compressi che voglio comprimere
# -Z "*.avi"
-Z "*.flv" -Z "*.mp4" -Z "*.MP4" -Z "*.mpeg" -Z "*.mpg" -Z "*.MPG"
-Z "*.jpeg" -Z "*.jpg" -Z "*.JPG" -Z "*.png" -Z "*.PNG"
-Z "*.mp3" -Z "*.MP3" -Z "*.ogg"
#### ESCLUSIONE ####
# create empty dir for excluded directories
--empty-dir
# we don't save theses directories (-P == --prune)
# -P tmp -P var/tmp -P proc -P dev -P sys
# here we say we don't want to save dar files
-X "*.*.dar"
# Non vogliamo salvare i dischi virtuali di vmware e di virtualbox (facile reinstallazione)
-X "*.vmdk" -X "*.vmem" -X "*.vdi"
# per non salvare le immagini ISO
# -X "*.iso"
###############################
# opzioni per la verifica degli archivi
test:
-E "/root/backup_script/dar_par_test.duc %p %b %n %e %c"
###############################
# opzioni per l'estrazione di archivi
extract:
# --fs-root /
# non sovrascrive
# --no-overwrite
# ripristina solo i file piu' recenti di quelli presenti
# --recent
###############################
# opzioni predefinite se non corrisponde nessuna delle precedenti azioni
default:
# if no action is given then show the version
# in place of the usage help
-V
Perché funzioni la creazione e la verifica con i file di controllo con par2, sono
necessari anche questi script, presi direttamente dal sito di dar (non c'è nulla di mio).
/root/backup_script/dar_par_create.duc e /root/backup_script/dar_par_test.duc.
E questa è la riga da aggiungere ad /etc/anacrontab per fare il backup ogni quattro mesi:
120 40 darchivi.4mesi /root/backup_script/backup_dar.sh
La verifica avviene tramite i controlli interni di dar e tramite parchive, con ridondanza al 2%. Ci si porta nella directory che contiene gli archivi (/mnt/backup/darchivi) e si dà il comando:
dar --test $ARCHIVIO -B $CONFIG
$ARCHIVIO è il nome dell'archivio, senza estensione e senza il numero di slice (cioè senza .N.dar, dove N è il numero di slice) $CONFIG è il percorso del file di configurazione, si può omettere se è /etc/darrc.
Grazie a parchive, se viene trovata corrotta una quantità di dati minore o
uguale al 2%, viene automaticamente riparata (è necessario che sia presente dar_par_test.duc).
Per ripristinare gli archivi, ci si porta nella directory che contiene gli archivi, si crea una directory temporanea per estrarre i file, e si dà il comando:
dar --extract $ARCHIVIO -B $CONFIG -R /path/to/temp/directory
l'opzione --extract si può abbreviare con -x.
Per ripristinare solo alcuni file, dobbiamo prima conoscere il percorso completo di questi file nell'archivio. Se non lo conosciamo, ma conosciamo solo il nome del file da ripristinare, possiamo chiedere a dar di mostrarci la lista dei file nell'archivio, e poi filtrarla con grep.
Per vedere una lista del contenuto di un archivio:
dar --list $ARCHIVIO
Successivamente, per estrarre il file:
dar -x $ARCHIVIO -B $CONFIG -R /path/to/temp/directory -g path/to/the/file
Se usiamo l'opzione -B dar eseguirà automaticamente il controllo dell'archivio tramite parchive prima di estrarre i file. Per evitare questo controllo, che può essere molto lungo con archivi grandi (e superfluo, se dobbiamo estrarre file piccoli), dobbiamo omettere il riferimento al file di configurazione con -B.
Come riferimento, ecco una lista dei percorsi e dei file di configurazione o degli script usati per i backup con dar (allegati a questa pagina gli script citati):
/mnt/backup/private/rsnapshot/weekly.0/: dir root dei file da archiviare/mnt/backup/darchivi/: dir che contiene gli archivi dar/mnt/backup/darchivi/[home|sistema|dati|linutop|pollux]-2009-05-05.N.dar:
modello dei nomi delle slice degli archivi create/mnt/backup/darchivi/[home|sistema|dati|linutop|pollux]-2009-05-05.N.dar.vol00+40.par2:
modello dei nomi dei file di verifica par creatiQuesta volta vediamo come fare backup dei dati importanti del nostro sistema usando degli snapshot, in stile Time Machine.
Uno snapshot non è altro che una copia esatta dei file esistenti. Usando rsnapshot possiamo creare degli snapshot periodici avvantaggiandoci dell'efficienza di rsync (che copia solo i file cambiati) e degli hard link (che ci permettono di risparmiare spazio su disco). Il risultato, dopo una semplice configurazione, è un deposito da cui possiamo recuperare versioni passate dei nostri file, proprio come fa Time Machine di Apple! (ma gratis, senza Leopard, e per qualsiasi computer della rete locale!)
Nel seguito illustro la mia strategia di backup con rsnapshot. È una trascrizione quasi esatta dei miei appunti, per cui è molto sintetica e stringata. Se qualcosa non vi è chiaro, consultate la documentazione di rsnapshot, molto semplice e ben fatta, e poi chiedetemi chiarimenti, usando i commenti in questa pagina.
castor.local, talvolta abbreviato in castor è il nome host del mio sistema locale.
Vengono fatti degli snapshot settimanali di /etc, /home, /root e /mnt/win_d.
rsnapshot fa snapshot di file system da usare come backup, usando rsync. Supporta backup incrementali che usando gli hard link occupano lo spazio di un backup completo + le differenze tra i backup periodici.
Permette di mettere a disposizione backup periodici in stile "time machine".
Successivamente, ogni 4 mesi, ho degli script che creano dei pacchetti dar
compressi con gzip dagli snapshot più recenti (/mnt/backup/private/snapshots/weekly.0/). In proposito, vedere la prossima pagina.
I backup vengono fatti settimanalmente, e vengono ruotati automaticamente. Dopo
un mese, sono conservati mensilmente per due mesi.
Usiamo anacron per assicurarci che i job programmati vengano eseguiti comunque
entro la data più vicina all'intervallo fissato.
Elenco qui solamente le modifiche rilevanti per il mio sistema di backup locale.
Ecco le righe modificate dal mio file di configurazione /etc/rsnapshot.conf (riporto solo le righe che ho modificato):
# All snapshots will be stored under this root directory.
snapshot_root /mnt/backup/private/snapshots/
# LINUX USERS: Be sure to uncomment "cmd_cp". This gives you extra features.
cmd_cp /bin/cp
# Uncomment this to enable remote ssh backups over rsync.
cmd_ssh /usr/bin/ssh
# 4 backup settimanali (1 mese) e 2 mensili (vado nel "passato" al max per 2 mesi)
interval weekly 4
interval monthly 2
# If this is enabled, rsync won't span filesystem partitions within a
# backup point. This essentially passes the -x option to rsync.
# The default is 0 (off).
one_fs 1
# The include_file and exclude_file parameters, if enabled, simply get
# passed directly to rsync. Please look up the --include-from and
# --exclude-from options in the rsync man page for more details.
exclude_file /root/backup_script/rsync_escludi
###############################
### BACKUP POINTS / SCRIPTS ###
###############################
# LOCALHOST
backup /root/ castor/
backup /etc/ castor/
backup /mnt/win_d/ castor/
backup /home/ castor/
"castor" specifica in quale sottodirectory "destinazione" vanno messi i backup di ciascuna directory originale. Di solito si usa il nome dell'host di cui si fa il backup.
Aggiunti i job a cron (in realtà, ad anacron):
[gerlos@castor ~]$ cat /etc/cron.weekly/rsnapshot_weekly.cron
#!/bin/bash
/usr/bin/rsnapshot weekly
exit 0
[gerlos@castor ~]$ cat /etc/cron.monthly/rsnapshot_monthly.cron
#!/bin/bash
/usr/bin/rsnapshot monthly
exit 0
Ecco il contenuto del file delle esclusioni, /root/backup_script/rsync_escludi. La sintassi è quella delle regole di matching di rsync:
+ **/tmp
- **/tmp/**
+ **/cache
- **/cache/**
+ **/Cache
- **/Cache/**
+ **/.thumbnails
- **/.thumbnails/**
+ **/.beagle/Indexes
- **/.beagle/Indexes/**
+ **/.beagle/TextCache
- **/.beagle/TextCache/**
- *~
- *.swp
- *.vmdk
- *.vdi
+ **/Download/distro/
- **/Download/distro/*.iso
Gli snapshot sono in /mnt/backup/private/snapshots/. La struttura è questa:
# ls -l private/snapshots/
totale 16
drwxr-xr-x 3 root root 4096 2009-04-26 04:38 weekly.0/
drwxr-xr-x 3 root root 4096 2009-04-20 11:21 weekly.1/
drwxr-xr-x 3 root root 4096 2009-04-19 06:25 weekly.2/
drwxr-xr-x 3 root root 4096 2009-04-13 02:05 weekly.3/
drwxr-xr-x 3 root root 4096 2009-04-06 02:05 monthly.0/
drwxr-xr-x 3 root root 4096 2009-03-03 02:05 monthly.1/
Ogni directory contiene la struttura completa delle directory salvate, esattamente come nel file system originale:
# tree -dL 2 /mnt/backup/private/snapshots/weekly.0/
/mnt/backup/private/snapshots/weekly.0/
`-- castor
|-- etc
|-- home
|-- mnt
`-- root
Gli snapshot che abbiamo creato sono copie esatte dei file originali (con le stesse proprietà), e conservano gli stessi permessi degli originali, sono cioè modificabili dagli utenti proprietari, cosa non desiderabile per un backup.
Per ovviare a questo, ho messo la directory che contiene gli snapshot in una directory cui ha accesso solo root, e poi ho montato questa directory su un'altra directory in modalità "bind" in sola lettura (read-only):
# mkdir /mnt/backup/private/
# mkdir /mnt/backup/private/snapshots/
# mkdir /mnt/timemachine/
# chmod 0700 /mnt/backup/private/
# chmod 0755 /mnt/backup/private/snapshots
# chmod 0755 /mnt/timemachine
# mount -o bind /mnt/backup/private/snapshots /mnt/timemachine
# mount -o remount,ro,bind /mnt/timemachine
Perché il mount in bind in sola lettura funzioni è necessario avere un kernel linux pari o superiore al 2.6.26. Inoltre non è possibile il mount direttamente in sola lettura, ma è necessario procedere in due passi, come sopra. Vedi:
Read-only bind mounts
In questo modo gli utenti non potranno accedere agli snapshot direttamente, ma attraverso la directory /mnt/timemachine (nome molto appropriato :-), che essendo montata in sola lettura impedisce la modifica dei backup.
Per ripristinare una vechia versione di un file è dunque sufficiente sfogliare /mnt/timemachine, cercare la directory corrispondente alla versione che vogliamo (una settimana fa -> weekly.0, due settimane fa -> weekly.1, ecc.), e andare
a recuperare il file dalla copia dell'albero originale.
Per montare /mnt/timemachine in modo permanente non possiamo usare fstab (ci vogliono 2 comandi), ma possiamo aggiungere i comandi necessari in /etc/rc.local, che viene eseguito al termine della procedura di avvio del sistema.
rsnapshot. A remote file system snapshot utility, based on rsync
Dopo aver visto come usare rsnapshot per fare backup locali, vediamo come usarlo per fare backup su altri computer in rete. Dopo tutto, non è molto più difficile che fare backup locali...
Nella mia rete locale ho tre computer: castor, il mio desktop con Mandriva gnu/linux che viene usato spesso e che fa già i backup in locale su un hard disk secondario, pollux, un iMac G3 con su Mac Os X 10.3 che viene usato saltuariamente e linutop, il mio serverino di sviluppo LAMP Debian che è sempre acceso, privo di schermo.
Evidentemente linutop e pollux richiedono approcci di backup differenti.
Questo è il più facile: aggiungo queste righe a /etc/rsnapshot.conf su castor:
backup root@linutop:/etc/ linutop/
backup root@linutop:/var/ linutop/
backup root@linutop:/root/ linutop/
backup root@linutop:/home/ linutop/
backup_script /root/backup_script/backup_mysql.sh linutop/
backup_script /root/backup_script/backup_dpkg.sh linutop/
Le prime tre righe salvano il contenuto di /etc, /var e /home dal serverino
linutop su castor, le ultime due eseguono degli script. Il primo fa un dump
dei database di mysql, che essendo in esecuzione al momento della copia di /var/
probabilmente avrà restituito una copia inutilizzabile, il secondo salva la
lista dei pacchetti installati, in modo che sia possibile ripristinarli in
seguito.
Più in dettaglio, questo è il contenuto del primo script,
/root/backup_script/backup_mysql.sh, tratto dalla documentazione di rsnapshot:
#!/bin/bash
##############################################################################
# backup_mysql.sh
#
# by Nathan Rosenquist <nathan@rsnapshot.org>
# http://www.rsnapshot.org/
#
# This is a simple shell script to backup a MySQL database with rsnapshot.
#
# The assumption is that this will be invoked from rsnapshot. Also, since it
# will run unattended, the user that runs rsnapshot (probably root) should have
# a .my.cnf file in their home directory that contains the password for the
# MySQL root user. For example:
#
# /root/.my.cnf (chmod 0600)
# [client]
# user = root
# password = thepassword
# host = localhost
#
# This script simply needs to dump a file into the current working directory.
# rsnapshot handles everything else.
##############################################################################
# $Id: backup_mysql.sh,v 1.5 2005/04/03 13:52:02 scubaninja Exp $
# backup the database
ssh root@linutop -i ~/.ssh/rsnapshot_dsa /usr/bin/mysqldump --defaults-extra-file=/root/.my.cnf --all-databases > mysqldump_all_databases.sql
# make the backup readable only by root
/bin/chmod 600 mysqldump_all_databases.sql
Questo invece è il contenuto del secondo script,
/root/backup_script/backup_dpkg.sh:
#!/bin/bash
# salva una lista di pacchetti ripristinabile con la sequenza di comandi:
# apt-get update
# apt-get dist-upgrade
# dpkg --clear-selections
# dpkg --set-selections < dpkg-restore.txt
# apt-get -u dselect-upgade --purge
#
# in questo modo si possono ripristinare i pacchetti installati a partire
# da un'installazione minimale. Ripristinando /etc, /home e /var si ripristina
# anche la configurazione e i dati. Ricordarsi di controllare anche /boot/grub
ssh root@linutop -i ~/.ssh/rsnapshot_dsa /usr/bin/dpkg --get-selections > dpkg-restore.txt
exit 0
Nota: per accedere via ssh a linutop è necessario configurare l'accesso tramite chiave publbica. Vedi la parte "Accesso SSH con chiave pubblica".
Per un ripristino completo, posso fare un'installazione minimale o ripristinare un vecchio dump del file system, reinstallare i pacchetti mancanti (installati dopo il dump più recente) con i comandi:
aptitude update
aptitude dist-upgrade
dpkg --clear-selections
dpkg --set-selections < dpkg-restore.txt
apt-get -u dselect-upgrade --purge
Poi ricopiare a posto /etc, /home, /root e /var, e poi ripristinare i database con il comando:
mysql < mysqldump_all_databases.sql
Poiché è un piccolo server, si assume che ogni operazione di riprstino venga fatta da root, che può montare/smontare liberamente dischi e condivisioni di rete senza problemi. Per questo non ho previsto alcun modo esplicito per accedere ai backup da linutop (se necessario root fa un mount tramite sshfs).
Su pollux mi interessa solo avere backup della directory utenti /Users.
Poiché pollux è un sistema desktop piuttosto lento, e non è acceso frequentemente, non posso contare su backup settimanali fatti da castor, su cui gira rsnapshot, ne salterebbero troppi, visto che non ho la certezza che pollux sia acceso mentre anacron su castor avvia il backup.
Per questo i backup devono partire da pollux verso castor, visto che è molto probabile che quest'ultimo sia comunque acceso. Vengono sincronizzati i dati di pollux con una directory di castor, e poi da questa vengono fatti gli snapshot periodici. Dunque per pollux, weekly.0 nella dir degli snapshot risalirà a un tempo compreso tra una settimana e dieci giorni fa. Per ora è il meglio che sono riuscito a fare.
Uso allora rsync per fare backup completi di /Users su castor in /mnt/backup/imac-pool con questo script:
script rsync
Lanciato tramite anacron su pollux ogni 3 giorni, così che le modifiche da trasferire siano poche e il backup molto rapido:
configurazione anacron su pollux
Su castor, invece, aggiungo questa riga a /etc/rsnapshot.conf:
backup /mnt/backup/imac-pool/Users pollux/
E configuro samba su castor in modo da condividere in rete la directory
/mnt/timemachine, così che gli utenti di pollux (che sono gli stessi utenti di
castor) possano recuperare i propri file dai backup. Per questa configurazione
ho usato il comodo draksambashare nel Centro di Controllo di Mandriva
(naturalmente dopo la configurazione ho controllato il risultato in
/etc/samba/).
Accedo a questa condivisione samba da pollux in questo modo:
procedura per accedere a samba da pollux