Backup perfetti con rsync e ssh
Recentemente ho scoperto il potere occulto di rsync!
Che la bash (o console) sia un luogo magico, terra fertile per il proliferare di nerd, geek e folletti… beh è cosa risaputa (con mastercard).
Che esse-esse-acc-arsi * su di un server remoto per salvare files importantissimi sia una emozione unica… beh anche questo è cosa risaputa (con mastercard).
Ma controllare che ogni giorno, ogni ora, il proprio script si occupi in maniera veloce e leggera di fare i backup… non ha prezzo!
(*) ovvero aprire una shell sicura ** su di una macchina remota con ssh
(**) no, non è una pratica sessuale
Ok, veniamo al succo: due server. Uno principale su cui gli utenti salvano i loro files (magari attraverso samba) ed uno secondario, di backup, che è il clone del primo. Lo scopo è semplice, se il primo server salta, il secondo lo può sostituire all’istante. In più sul secondo server si possono eseguire operazioni di backup o altro, senza occupare risorse del primo, che così rimane tutto a disposizione degli utenti.
Per fare questo abbiamo bisogno di 4 cose:
- uno script che sicronizzi i due server (rsync)
- una sessione autenticata in ssh che permetta la sincronizzazione in maniera automatica
- l’esecuzione automatica ad un orario prestabilito dello script
- uno script che faccia i backup (anch’esso ad orari prestabiliti)
Cominciamo dal primo server (quello principale) che chiameremo server1.
Punto 1: Rsync
Il comando rsync è molto utile poichè permette la sincronizzazione di due directory tramite il confronto dei files e la copia esclusivamente dei cambiamenti tra le due cartelle. In pratica è come eseguire un scp (secure copy) tra due cartelle, ma con un notevole risparmio di banda dato che solo le modifiche vengono trasmesse (trasferimento incrementale).
rsync --delete -azv -e ssh [dir1] [dir2]
Dove naturalmente [dir1] e [dir2] sono le due cartelle da tenere “clonate”, con “–delete” vengono anche eliminati i files che sono stati cancellati dalla [dir1] e con “ssh” gli diciamo di utilizzare una sessione in ssh… appunto.
Per specificare che la [dir2] è remota si usa la sintassi:
utente@macchina:cartella
Bene, vediamo adesso lo script nel suo insieme:
#!/bin/sh #Author: fry@nerdsopolis.net #Description: Backup tramite rsync. #Variabili LOCAL=/srv/samba/pub REMOTE=/srv/samba/backup HOST=192.168.1.100 LOG=/srv/samba/backup.log SYNCLOG=/srv/samba/backup.synclog #Inizio log echo $(date +"%d/%m/%Y") | cat >> $LOG echo $(date +"%H:%M.%S") backup started... | cat >> $LOG #Rsync rsync --delete -azv -e ssh $LOCAL root@$HOST:$REMOTE | cat > $SYNCLOG #Fine log echo $(date +"%H:%M.%S") backup ended! | cat >> $LOG
Come si può vedere non ho fatto altro che specificare un po’ di variabili ed aggiungere un file di log che ci permette di fare del debug sull’esecuzione di rsync.
La cartella locale è /srv/samba/pub e quella remota è /srv/samba/backup sul server2 che ha indirizzo 192.168.1.100.
NB: lo script utilizza l’utente root su entrambi i server. Naturalmente tale opzione è sconsigliabile ma per il momento semplifica le cose!
Mettiamo lo script (che io ho chiamato semplicemente rsync_backup.sh) nella cartella
/usr/local/bin
su server1 e rendiamolo avviabile
chmod u+x /usr/local/bin/rsync_backup.sh
Ora se proviamo ad avviarlo
sh /usr/local/bin/rsync_backup.sh
ci verrà richiesta la password dell’utente root sul server2 (ed anche si accettare la chiave se è la prima volta che ci connettiamo in ssh a quella macchina).
Poichè però il nostro script dovrà essere eseguito automaticamente, non possiamo inserire a mano la password tutte le volte. E, prima che a qualcuno venga in mente, non vogliamo neanche far passare password in chiaro tutte le volte!
Punto 2: SSH senza password
Per automatizzare l’operazione di ssh tra il server1 ed il server2 dobbiamo fare in modo che il server2 si “fidi ciecamente” del server1 senza bisogno di una password. Come? Utilizzando una combinazione di chiavi pubbliche e private.
Senza scendere nel dettaglio mi limiterò a ricordarvi (dato che voi già lo sapete) che posso distribuire liberamente la mia chiave pubblica e tenere al sicuro la mia chiave privata. Grazie alla chiave pubblica chiunque potrà essere sicuro della mia identità fin tanto che deterrò la chiave privata.
Sul server1 generiamo la coppia di chiavi
ssh-keygen -t rsa
lasciando generare le chiavi nella directory predefinita e non inserendo nessuna password quando ci viene chiesto.
Ora andiamo nella cartella .ssh/ nella home del nostro utente, troveremo due files: id_rsa e id_rsa.pub.
Ovvero: id_rsa = chiave privata & id_rsa.pub = chiave pubblica
Inviamo la nostra chiave pubblica al server2
scp id_rsa.pub root@192.168.1.100:/root
ora andiamo sul server2 nella cartella /root dove troviamo il file che abbiamo appena copiato. Adesso controlliamo di avere una cartella che si chiama “.ssh”, se non c’è creiamola. Poi mettiamo la chiave pubblica nel file “autorized_keys” all’interno della directory.
mv id_rsa.pub .ssh/ cat id_rsa.pub >> authorized_keys chmod 644 authorized_keys
Ok! Adesso qualsiasi accesso in ssh dal server1 al server2 avverrà senza richiesta di password e quindi se proviamo a lanciare nuovamente il nostro script dal server1, la sincronizzazione avverrà senza richiesta di input.
NB. Come detto prima, eseguire queste operazioni con l’utente root è altissimamente sconsigliato!
Punto 3: Crontab
Crontab gestisce tutte le operazioni pianificate sul nostro server. L’utilizzo è semplicissimo:
0 4 * * * /usr/local/bin/rsync_backup.sh
esegue il nostro script alle 4:00 di tutti i giorni.
Per maggiori dettagli su crontab vi rimando a wikipedia.
La stringa che abbiamo visto sopra andrà inserita all’interno della coda di crontab, tramite il comando
crontab -e
si aprirà un editor (se è la prima volta ci chiede anche che editor usare, io consiglio vim) dove scrivere la stringa (in vim per modificare si preme “i”) e dopo averla salvata (premere “:x”) possiamo controllare che sia stata inserita tramite
crontab -l
Punto 4: Backup
Mentre il nostro server1 si becca tutti gli accessi degli utenti, il server2 rimane dormiente tutto il giorno e viene utilizzato solo per qualche minuto verso le 4 di notte, quando riceve gli aggiornamenti.
Possiamo quindi pianificare su server2 in qualsiasi altro momento della giornata dei backup (totali o incrementali) da masterizzare o da copiare su altri dischi.
Ecco lo script che uso io (backup totali tramite tar)
#!/bin/sh #Author: fry@nerdsopolis.net #Description: Script per la creazione di backup automatico e rimozione # vecchi backup. #Variabili LOG=/srv/samba/backup.log TARLOG=/srv/samba/backup.tarlog BASE=/srv/samba/backup/ DIR=pub/ #Inizio log echo $(date +"%d/%m/%Y") | cat >> $LOG echo $(date +"%H:%M.%S") backup started... | cat >> $LOG #Creazione del backup cd $BASE tar -zcvf $(date +"%y%m%d-%H%M").tar $DIR | cat > $TARLOG #Eliminazione backup piu' vecchio first=$(ls | grep tar | sort -n | head -1) rm $first echo $(date +"%H:%M.%S") deleted $first | cat >> $LOG #Fine log echo $(date +"%H:%M.%S") backup ended! | cat >> $LOG
In questo caso il mio script crea un archivio tar compresso di tutta la cartella /srv/samba/backup/pub e successivamente cancella il backup più vecchio.
Naturalmente questa tecnica ci consente di tenere in memoria (a seconda dello spazio sul disco) tanti backup che sono la “foto” della cartella in un determinato momento. Se ad esempio tengo 10 backup, lo script andrà a crearne uno nuovo e poi a cancellare il più vecchio, lasciandone sempre 10 sul mio disco. Per fare ciò però dovremo ricordarci di fargli fare prima 10 backup commentando per i primi 10 cicli la riga relativa alla cancellazione dei backup più vecchi.
Anche questo script, come il precendete va messo in /usr/local/bin e chmoddato in modo da essere eseguibile.
Ora sempre tramite crontab possiamo fare in modo che lo script sia eseguito una volta alla settimana, la domenica notte:
0 4 * * 0 /usr/local/bin/backup.sh
Fine. Se avete avuto la forza di seguire questo post fino a questa riga, significa che avete realemente bisogno di usare gli script per fare i backup.
Quindi perchè non andate oltre e li personalizzate per fare altre funzioni? Si sa, uno script tira l’altro!
>
ottobre 15th, 2009 at 16:34
Ciao molto interessante lo script per l’rsync. Cisono due errori
1) il file creato da ssh-keygen e’ id_dsa (non id_rsa)
2) il comando cat id_dsa.pub >> .ssh/authorized_keys da un errore in risposta e non crea il file autorized_keys
mentre per il punto 1 ho risolto non comprendo come risolvere per il punto 2… grazie e buon lavoro
ottobre 21st, 2009 at 15:46
Ciao Donato, c’era un errore, la chiave va creata in rsa e non dsa. Ho corretto l’articolo.
novembre 30th, 2009 at 14:17
Ma fa te se devo cercare delle info e trovare i miei vecchi compagni di corso… come va?… già che ci sei un buco nella mia memoria, è possibile dalla chiave privata recuperare la pubblica? o devo generare una nuova coppia di chiavi?
dicembre 1st, 2009 at 17:18
Ah ah ah! Grande Alex! Eh cosa ne direbbe il buon Santini?!
Certo che si può fare! Con la chiave privata puoi generare sempre la pubblica, è il contrario che (per fortuna) è impossibile.
Il comando è: ssh-keygen -y -f id_rsa > id_rsa.pub
Fammi sapere se ti funziona!
dicembre 5th, 2009 at 11:01
Il buon Santini tirerebbe un meritato scopellotto sulla mia testona… a ragione direi… ma lo comprerei a Lambrusco e torneremmo amici. Comunque si funziona grazie mille.