produzione software
consulenze informatiche
programmazione web

Oggi i prezzi per acquistare un server LAMP sono diventati abbordabili, molti providers offrono server virtuali LAMP a meno di 20 Euro al mese.

Se avete un server LAMP, una delle prime esigenze che sentirete è quella di fare il backup dei dati.

Il backup ci mette al sicuro in caso di disastri che possono accadere, ed il rischio è reale. Può succedere di danneggiare le configurazioni dei programmi,possono succedere perdite accidentali di dati, può addirittura succedere che la macchina remota si rompa, ma la minaccia più concreta è l'attacco da parte di software malevoli.

Io mi sono posto il problema e questa è la soluzione che ho trovato:

COPIA DEI DATI NEL SERVER CON IL COMANDO TAR

Per accedere al server uso il protocollo ssh che garantisce la connessione criptata per evitare attacchi malevoli. Per collegarmi da ambiente windows uso il programma PuTTY che mi permette di aprire una console nella macchina remota.

Da linux invece basta aprire un terminale e digitare:

ssh user@server_name_or_ip

Nel server faccio una copia dei soli dati rilevanti per evitare di consumare banda e tempo copiando dati ricostruibili, per questo motivo ho prdisposto un automatismo che tutti i giorni copia i files di configurazione ed i files dei database mysql.

per fare questo uso il comando tar, ad esempio con:

tar -jcf /var/bak_root/etc.tar.bz2 /etc

genero un file compresso di tutta la cartella /etc nel file etc.tar.bz2 che ho depositato in /var/bak_root.

L'opzione -j esegue la compressione in formato bz2 che è la compressione massima. Se si desidera si puo sostituire -jcf con -jcvf che ci permette di vedere il progresso dei files che vengono copiati.

Per i files del database mysql invece uso il comando mysqldump che genera un file sorgente sql in grado di ricostruire il database.

mysqldump -u root -pmysecretpwd --all-databases | bzip2 -v > /var/bak_root/mysql-db.sql.bz2

In questo caso il file di dump, lo passo immediatamente al comando bzip2 che lo comprime e lo salva.

Potrei anche copiare i files binari di MySQL con il comando:

tar -jcf /var/bak_root/mysql-db.tar.bz2 /var/lib/mysql

Ma in caso di disaster recovery avrei maggiori difficoltà a ricostruire il database.

Nel mio caso il database è contenuta nella cartella /var/lib/mysql ma potrebbe non essere così, per verificare la posizione esatta nel file di configurazione /etc/my.cnf

Infine faccio una copia anche dei files del server web. La mia macchina ha un server Apache2 con pannello di controllo Plesk e server virtuali condivisi, id dati sono nella cartella /var/www ed in particolare nella cartella /var/www/vhosts sono conservati di dati dei siti installati. Il comando in questo caso è:

tar -jcf /var/bak_root/vhosts_mysite.tar.bz2 --exclude-from=/root/tarexclude.txt /var/www/vhosts/mysite.it

In questo caso decido di copiare il sito mysite.it, e posso ripetere il comando per tutti i siti che desidero, ignorando quelli che non mi interessano, ad esempio i siti di prova. Probabilmente si potrebbe scrivere uno script bash che esegua il comando per tutte le cartelle (e quindi i siti) contenuti sotto /var/www/vhosts, ma al momento non mi interessa e preferisco scegliere che cosa copiare.

Nella copia decido di escludere tutti i files multimediali, perché pesano molto e quindi rallentano la copia dei dati in locale che vedremo dopo. Perciò consiglio di conservare la copia dei files multimediali altrove. Per fare questo si aggiunge al comando tar il parametro --exclude-from=/root/tarexclude.txt che indica che la lista delle esclusione si trova nel file: /root/tarexclude.txt che nel mio caso contiene:

*.jpg
*.JPG
*.jpeg
*.mp4
*.png
*.wmv
*.gif
*.pdf
*.PDF
*.zip
*.ZIP
*.EXE
*.exe
*.so
*.so.*
bin
dev
logs
tmp

e oltre ai files multimediali esclude anche alcune cartelle conosciute che non contengono dati del sito.

Ora desidero che il comando venga eseguito automaticamente tutti i giorni

ESECUZIONE AUTOMATICA DEI COMANDI DI COPIA

I sistemi linux permettono l'esecuzione automatica di comandi utilizzando il daemon cron che permette vari tipi di esecuzioni temporizzate.

La configurazione di cron può cambiare da sistema a sistema, i dettagli sulla configurazione dei sistemi linux si trovano nei tutorial di sistemistica, di solito nella cartella /etc/init.d sono presenti script di shell che vengono eseguiti ad ogni riavvio di sistema e fanno partire tutti i daemon necessari alla propria configurazione.

Se si desidera eseguire un comando tutti i giorni di solito è sufficiente inserire il comando in uno script nella cartella /etc/cron.daily

Nel mio caso lo script è si chiama bak_root e contiene:

#!/bin/bash
#
# backup /etc dir and mysql files every day with a different name
#
DOW=$(date +%u)
tar -jcf /var/bak_root/etc$DOW.tar.bz2 /etc
mysqldump -u root -pmysecretpwd --all-databases | bzip2 -v > /var/bak_root/mysql-db$DOW.sql.bz2
tar -jcf /var/bak_root/vhosts_mysite$DOW.tar.bz2 --exclude-from=/root/tarexclude.txt /var/www/vhosts/mysite.it

In questo caso desideravo avere la storia delle copie per una settimana e perciò ho aggiunto il comando:

DOW=$(date +%u)

che genera una variabile d'ambiente che contiene il giorno della settimana, infatti: date +%u restituisce il giorno della settimana come numero da 1 a 7 in cui 1 è lunedì e 7 è domenica.

Il comando date prevede molti parametri, maggiori dettagli si possono trovare ad esempio su: http://unixhelp.ed.ac.uk/CGI/man-cgi?date o da molte altre parti.

poi con:

tar -jcf /var/bak_root/etc$DOW.tar.bz2 /etc

aggiungo al nome il numero del giorno, ad esempio di lunedì avrò un file di nome: etc1.tar.bz2, di martedì etc2.tar.bz2 e così via. Poi il prossimo lunedì sovrascriverò quello del lunedì precedente.

Con questi comandi, mi troverò sul server una settimana di storico dei dati, ora è giunto il momento di scaricare i dati un una macchina localizzata fisicamente in un posto diverso.

REGOLE PER LE COPIE

Le copie predisposte sul server possone essere copiate su client locali in molti modi, il numero di copie e le dislocazioni dipendono dal livello di paura di perdita dei dati e dalla criticità dei dati stessi.

Personalmente consiglio di essere piuttosto paranoici nei confronti delle copie, la perdita dei dati è sempre un dramma che può essere piccolo o grande a seconda della facilità e del costo necessari per la ricostruzione degli stessi.

Le regole per le copie sono semplici:

1 - Localizzazione fisica diversa: fare le copie sullo stesso disco fisso serve a poco, infatti se si rompe il disco perdiamo sia i dati che le copie, anche le copie su dischi o macchine diverse presenti negli stessi uffici può non essere sufficiente, infatti un fulmine, un incendio o un furto possono portare alla perdita di dati e copie, due locazioni diverse di solito sono sufficienti perché la concomitanza di due eventi eccezzionali i posti diversi è veramente quasi impossibile, ma non fa danno averne anche di più.

2 - Storico delle copie: In alcuni casi possono accadere danni di cui non ci si accorge subito, ad esempio se il nostro sito subisce l'attacco di un hacker o di un software malevolo, potrebbe succedere che per alcuni giorni non ci si accorge del danno, allora è utile conservare un storico di copie. Nel esempio precedente facevamo una copia diversa per ciascun giorno della settimana e questo ci garantisce uno storico di 7 giorni, si potrebbe andare anche oltre, ma bisogna considerare che dopo un certo tempo i dati invecchiano, quindi consigliamo comunque di monitrare i dati frequentemente ed in caso di dati statici di fare copie a lungo termine.

SCARICAMENTO DELLE COPIE SU CLIENT LOCALE

Le copie si possono fare utilizzano un client FTP o con diversi comandi e programmi, io ho scelto di usare il comando rsync in una macchina linux locale.

Il comando rsync a differnza di altri sistemi consente di fare il mirroring di una cartella in modo molto veloce ed efficace, se rsync non è presente lo possiamo installare con il comando:

sudo apt-get install rsync

su sistemi debian oppure

yum install rsync

su sistemi basati si fedora.

Già che ci siamo facciamo anche:

sudo apt-get install sshpass

o

yum install sshpass

che ci servirà dopo.

anche rsync ha molti comandi che si possono trovare anche su: http://unixhelp.ed.ac.uk/CGI/man-cgi?rsync io uso questo:

rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/bak_root /home/mydata/bak

Naturalmente si deve sostiutire l'indirizzo ip con l'indirizzo o il dominio della propria macchina remota, e si può sostiutire /home/mydata/bak con la posizione in cui si desidera salvare i dati.

In questo caso le opzioni indicano:

-r recursive: indica che si desidera copiare tutto il contenuto delle directory
-l links: significa che in caso di links simbolici non si desidera copiare i dati linkati, ma solo il link, in questo modo si evitano inutili copie di dati che possono essere copiati esplicitamente.
-p perms: vengono mantenuti i permessi dei files
-t times: conserva la data di modifica

poi

--del indica che in caso che un file non sia più presente nella cartella sorgente si desidera che venga cancellato anche nella destinazione.

e

-e ssh indica che si desidera utilizzare il protocollo ssh per ottenere la connessione criptata.

la cartella sorgente è:

Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/bak_root

che copia la cartella /var/bak_root sul server 192.111.111.111 a cui si accede con l'utente root.

infine

/home/mydata/bak

è la posizione di destinazione dei dati:

Questo comando esegue una copia incrementale e quindi vengono copiati solo i dati diversi da quelli presenti in locale, nel nostro caso saranno scaricati solo i dati del giorno corrente, mentre invece i dati dei giorni precedenti non verranno toccati perché sono uguali nel server e nel client.

Quando lanciamo questo comando, rsync ci chiede la password dell'utente root nella macchina remota, per automatizzare l'esecuzione (ad esempio con il comando cron), ci sono alcuni modi presenti nella documentazione di rsync. Se non avete problemi di sicurezza nella macchina client locale potete usare:

sshpass -p "my_remote_password" rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/bak_root /home/mydata/bak

che passa a rsync la password per accedere.

già che ci siamo facciamo anche la copia incrementale di tutta la cartella dei dati dei server web del server con il comando:

sshpass -p "my_remote_password" rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/www /home/mydata/bak

Costa poco perché è una copia incrementale e copia solo i files modificati ed è anche velocissima se ci sono pochi files modificati rispetto alla volta scorsa, tra l'altro in questo caso si fa il backup anche di tutti i files multimediali.

Che cosa si può fare ancora?

Beh, sicuramente si può fare un script da automatizzare con cron, possibilmente facendo in modo che gli orari del cron remoto e di quello locale siano sfalsati abbastanza da fare in modo che il client parta dopo che il server ha finito le operazioni giornaliere.

Poi se abbiamo spazio sul disco client (e sicuramente visto il costo dei dischi fissi non è un problema), potremmo effettuare il salvataggio addirittura con lo storico di un mese, ade esempio:

#!/bin/bash
#
# syncronize local directory
#
DOM=$(date +%d)
sshpass -p "my_remote_password" rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/bak_root /home/mydata/bak
sshpass -p "my_remote_password" rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/var/www /home/mydata/bak$DOM

Forse si potrebbe copiare l'intero sistema con:

sshpass -p "my_remote_password" rsync -rlpt --del -e ssh Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo.:/ /home/mydata/bak

Ma non sono sicuro che poi si possa ripristinare tutto.

A questo punto abbiamo tutti gli strumenti per dormire sonni relativamente tranquilli con la certezza che i nostri dati sono al sicuro. In caso di disastro dovremo solo ripristinare l'ambiente e con un po di pazienza ricaricare tutti i dati.

E POI?

Per il momento fermiamoci quì, ma dato che abbiamo acquisito alcune tecniche di backup, cosa potremmo fare per rendere i dati ancora più sicuri?

Beh, ad esempio potremmo fare l'operazione inversa. Dato che abbiamo dello spazio disponibile in una macchima remota chi ci impedisce di copiare i nostri dati locali sulla macchima remota? I comandi sono gli stessi, solo che i dati viaggiano in senso inverso.

Potremmo anche utilizzare samba per attivare una rete tra il nostro client Linux ed i nostri PC Windows e attraverso samba fare il backup da windows a client Linux e da client Linux a server linux.

Per difenderci invece da attacchi malevoli con furti di credenziali sul server, potrebbe essere utile mettere a punto una procedura che confronti data e dimensioni dei files sensibili per controllare che non siano stati modificati a nostra insaputa.

Ad esempio si potrebbero controllare tutti i files con estensioni *.php, *.htm, *.html e *.js nella directory /var/www/vhosts/ per controllare che non siano stati modificati a nostra insaputa.