Un potente programma per effettuare backup: rsync

Un ringraziamento preventivo a Matteo, che a suo tempo, in un progetto in cui lavoravamo insieme, si occupò di determinare le migliori opzioni da utilizzare con il comando rsync per l’implementazione delle operazioni descritte in questo articolo.

Una delle utility più interessanti per effettuare copia di file, sincronizzazione di directory e backup nell’ecosistema GNU/Linux è il programma rsync. Come molto spesso capita, dietro l’apparenza banale di una utility command line si nasconde un programma molto potente che laconicamente si autodefinisce “a fast, versatile, remote (and local) file-copying tool“.

In questo articolo si dimostrerà come utilizzare la funzionalità di sincronizzazione tra directory offerta dal programma per copiare il contenuto di una directory in una seconda area. L’applicazione è ovvia: effettuare il backup della prima directory (che nel seguito chiameremo “primaria”) nella seconda (definita “secondaria”).

Per rendere più interessante la dimostrazione supporremo che le due directory risiedano su due PC diversi (ma le stesse operazioni possono essere effettuate anche con le due aree poste sullo stesso PC). Naturalmente occorre che i due PC siano connessi in rete possibilmente senza firewall nel mezzo che potrebbero bloccare le porte necessarie a rsync per lavorare.

La configurazione rsync scelta è quella client-server:

  • lato directory primaria si manterrà il programma in esecuzione come demone (server) pronto a rispondere alle interrogazioni dei client
  • lato directory secondaria si lancerà il comando da linea di comando (client); al termine di ogni sincronizzazione il programma esce.

Nel seguito indicheremo ip_server l’indirizzo IP del server e con ip_client quello del client.

Installazione

Normalmente rsync è già presente di default sulle più diffuse distribuzioni GNU/Linux. Nel caso non fosse presente, installarlo seguendo le procedure standard della distribuzione. Per esempio su Debian/Ubuntu e derivati dare il comando:

sudo apt-get install rsync

Configurazione e startup demone lato server

Per prima cosa definiamo la directory di cui si vuol effettuare il backup. Supponiamo sia /home/user/workarea. Supponiamo che al suo interno sia presente un unico file di nome foo.bar.

Come seconda cosa occorre preparare il file di configurazione per il server rsync. Supponiamo sia /home/user/rsyncd.conf. Nel nostro esempio il suo contenuto deve essere il seguente:

[WorkArea]
path=/home/user/workarea/
log=/home/user/logs/rsyncd.log
max verbosity

A questo punto per lanciare il server il comando da dare è il seguente:


user@host:~$ sudo rsync --daemon --config=/home/user/rsyncd.conf
user@host:~$ _

Se si controlla con il comando ps si vedrà il server in esecuzione.

Sincronizzazione lato client

Prima di effettuare la sincronizzazione vera e propria può essere utile lanciare il comando in modalità “dry-run”: si interroga il server per capire se deve essere effettuata un’operazione di sincronizzazione, cioè se lato server ci sono dei file nuovi o se alcuni file sono stati modificati. Per effettuare l’operazione il comando da dare è il seguente:


user@host:~$ rsync --dry-run -v --force --delete -a --port=873 <ip_server>::WorkArea workarea_backup
created directory workarea_backup
./
foo.bar
sent 36 bytes received 77 bytes 226.00 bytes/sec
total size is 56 speedup is 0.50 (DRY RUN)

Dall’output del comando si capisce che c’è la directory root della workarea modificata e il file foo.bar  modificato. Si capisce anche che verrebbe creata la directory di destinazione del backup, workarea_backup. Vediamo nel dettaglio il significato dei parametri utilizzati:

  • --dry-run: non effettua alcuna operazione, mostra solo le operazioni che verrebbero effettuate se non ci fosse questa opzione
  • -v: aumenta la verbosità delle informazioni mostrate a schermo
  • --force: forza la cancellazione delle directory non più esistenti anche se non vuote
  • --delete: se da server sono stati cancellati dei file ancora presenti nell’area di backup (come risultato di una precedente sincronizzazione), questi vengono cancellati
  • --port=873: cerca il server sulla porta 873 (la porta standard del comando rsync)
  • <ip_server>::WorkArea: indirizzo IP del server e “stanza” del file di configurazione con le informazioni dell’area da sincronizzare
  • workarea_backup: directory locale dove salvare il contenuto della sincronizzazione. Da notare che il contenuto di questa directory viene modificato in modo da rispecchiare il contenuto dell’area sul server, per cui eventuali file estranei verrebbero cancellati.

A questo punto, per effettuare la sincronizzazione ripetere il comando senza l’opzione –dry-run:

user@host:~$ rsync -v --force --delete -a --port=873 <ip_server>::WorkArea workarea_backup
created directory workarea_backup
./
foo.bar
sent 36 bytes received 77 bytes 226.00 bytes/sec
total size is 56 speedup is 0.50 (DRY RUN)

Verificare il contenuto della directory workarea_backup: adesso contiene il file foo.bar presente sul server.

D’ora in avanti, per mantenere aggiornata la directory di backup, basterà ripetere periodicamente il comando sul client.

Bonus track: uso di netcat per controllare lo stato di una porta

Infine un “bonus track” per vedere come lato client si può utilizzare la utility netcat per controllare se il server è attivo. Questo può essere utile soprattutto in script per controllare che il server sia presente prima di inoltrare i comandi visti in precedenza.

Come dice la sua manpage, “The nc (or netcat) utility is used for just about anything under the sun involving TCP or UDP“. In questo caso noi la useremo dal client per controllare che il server rsync sia in esecuzione. La porta su cui sta in ascolto il server rsync è la 873. Il comando netcat da dare per controllare se il server è attivo è il seguente:

user@host:~$ nc -z -n -w 1 <ip_server> 873
user@host:~$ _

Il significato delle opzioni è il seguente:

  • -z: effettua uno scan della porta senza inviare pacchetti
  • -n: non usa DNS
  • -w 1: imposta il timeout di attesa della risposta a 1 secondo

Il comando come spesso capita sulla command line di sistemi GNU/Linux, laconicamente, non scrive niente. Per controllare l’esito dell’interrogazione occorre verificare il valore ritornato dal comando tramite l’analisi della variabile $?. Se il valore di questa variabile è 0 vuol dire che il server è attivo (qualcuno è in ascolto sulla porta 873), altrimenti il server non risponde (nessuno è in ascolto sulla porta 873.

L’analisi della valore di ritorno del comando nc può essere fatto tramite il comando echo:

user@host:~$ echo $?
0
user@host:~$ _

o tramite, per esempio, tramite il seguente snippet di codice bash:

nc -z -n -w 1 <ip_server> 873
if [ $? -eq 0 ]; then
echo "rsync server is running!"
else
echo "rsync server not running"
fi