Il furto di dati di ho.mobile e l’informatica moderna

ho.mobile

Non avrebbe senso descrivere di nuovo ciò che è accaduto, ormai lo sanno praticamente tutti: ho.mobile ha subito un attacco e i dati personali di moltissime persone sono stati trafugati e messi in vendita nel dark web. Il gestore ha prima negato, poi indagato, poi ammesso (in ritardo), minimizzato (incredibilmente, vista la gravità della situazione) e, ad oggi, sembra ci sia un gran pastrocchio (cambiano codici seriali delle SIM ad alcuni utenti, ad altri, anche se "bucati", no...) così come sembra molto difficile cambiare gestore (portabilità bloccate o molto, molto lente).

Tanto per dirla in tono amichevole stanno facendo una magra figura da qualunque punto di vista la si voglia vedere, specialmente considerando che Ho è di Vodafone, dunque dovrebbe avere le spalle e l’esperienza di un colosso abituato a problemi di ogni genere.

Alla mia età sono ancora abbastanza giovane da avere una mente assetata di novità ma abbastanza vecchio da aver fatto esperienza e averne viste di ogni genere.

Intanto dico subito che tutto ciò non mi meraviglia. Può davvero accadere, anche se non dovrebbe. E vi spiego uno dei motivi per cui ciò avviene.

Mi trovo sempre più spesso, per ragioni professionali, a discutere con dei clienti o colleghi. Ormai il motto non è più quello di fare un lavoro fatto bene, con tecnologie e metodi chiari e semplici, mantenerlo in buona salute e far funzionare il tutto. Oggi o si seguono le mode ("tutti vogliono la blockchain, la facciamo anche noi?", "mettiamo su un cluster Kubernetes per il nostro sito statico da 10 visite al giorno") oppure si fanno delle cose, spesso in maniera dozzinale, e si lasciano in produzione per anni, senza curarsi delle conseguenze. Prima o poi se ne paga il prezzo. E, spesso, il prezzo è altissimo.

Alcuni miei clienti si sono rivolti, in passato, a team di sviluppatori cinesi o indiani. I costi erano ridicoli, i presupposti ottimi. Il lavoro svolto è stato pessimo, con una bella facciata ma colonne di sabbia e sono spariti appena incassato il dovuto. Lasciando guai e problemi a chi deve mandare avanti l’infrastruttura.

Un (ex) cliente mi ha telefonato dicendo che il server appena fatto era stato bucato pochi giorni dopo essere stato messo online. Da un’indagine molto breve è venuto fuori che il Wordpress aveva utente amministrativo "admin" e password, da loro impostata, "admin". Come si può tamponare una leggerezza del genere? Ho risolto, mio malgrado, dicendo al cliente che non avremmo più potuto collaborare visti i loro standard di sicurezza.

Caratteristica del mestiere informatico è sempre stata il non richiedere una particolare formazione ma consentire a chiunque di svolgerla, pur senza studi specifici.

Oggi stiamo assistendo alle estreme conseguenze di questa situazione: ci si trova a lavorare molto spesso con persone con scarsa formazione e che fanno esperienza solo sul campo. Mancando però delle basi teoriche e di partenza, volenti o nolenti avranno molto spesso delle lacune. Il guaio è che, come spesso accade, chi sa è pieno di dubbi mentre chi non sa è pieno di certezze. Il risultato è semplice: si mette in produzione qualcosa di insicuro, carente, pericoloso e dozzinale. Il risultato? Ciò che è accaduto ad ho.mobile.

Ammetto con un certo grado di tristezza di essere preoccupato per alcune delle situazioni che gestisco online. Pur essendo abbastanza intransigente, vengo a volte costretto (ubi maior...) a dover chiudere un occhio di fronte a cantonate tecniche, pratiche di sicurezza inesistenti, sistemi non aggiornati e vulnerabili in quanto "non abbiamo tempo per aggiornare" o "i ragazzi sono giovani, non sanno prendere in mano la situazione".

In altri casi passo la vita a ripristinare da backup dei CMS che vengono bucati quotidianamente. "Non abbiamo tempo di aggiornare, tu ripristina poi vedremo". Poi il silenzio, fino all'hack successivo.

No, non è questo il modo corretto di lavorare, purtroppo. Oggi di base mancano due cose: vera formazione (non un corso online ma della vera formazione strutturata) prima di affacciarsi al mondo dell’IT e, come causa e conseguenza di ciò, l’umiltà di capire i propri limiti e mettersi in gioco. Ci sono persone che arrivano senza esperienza ma che, con buona volontà e impegno, imparano sul campo anche meglio di chi magari ha passato anni a studiare certificazioni o in facoltà. Per fortuna ho molti colleghi e amici che rientrano in questa categoria.

Ma molti oggi si affacciano senza titoli, senza esperienza, senza formazione e senza preparazione di alcun genere ma vogliono comandare, decidere, imporre ed avere ragione. Tutto si può imparare ma ci vogliono la volontà di farlo e la giusta umiltà di capire cosa studiare, non quell’estrema tracotanza che contraddistingue, purtroppo, molte figure (specialmente giovani) nel mondo dell’IT.

Dunque no, ciò che è accaduto ad ho.mobile non dovrebbe accadere. Ma fretta, scarsa attenzione, arroganza e incompetenza creano delle voragini che, prima o poi, verranno sfruttate.

Backup efficienti di container LXC in Proxmox (e non solo)

Proxmox

NOTA: Il seguente post è la traduzione dell'equivalente sul blog it-notes. L'originale sarà sempre più aggiornato.

A volte un container lxc può essere un'alternativa più valida rispetto ad ad una macchina virtuale KVM. Ha un overhead inferiore, una gestione delle risorse più semplice ed efficiente e un minore impatto sulla macchina fisica.

Si ottiene (potenzialmente) meno isolamento dalla macchina fisica e si è costretti ad usare il kernel dell’host. Inoltre, non è possibile eseguire un sistema operativo diverso.

Proxmox supporta in maniera nativa i container lxc ed essi sono spesso una buona scelta. Ho recentemente convertito alcune VM in container lxc e sono più veloci, più leggeri e l'occupazione della ram è abbastanza bassa.

Ci sono due grossi svantaggi: non è possibile migrare un container lxc in esecuzione (deve essere spento, spostato e riavviato - se si usa uno storage condiviso, spesso è una questione di secondi) e i backup su Proxmox Backup Server sono più lenti rispetto al backup di una VM.

Questo perché una VM può monitorare, grazie alle dirty bitmap di KVM, le sue operazioni su disco per sapere in anticipo quali blocchi devono essere controllati e copiati. Quando si ha a che fare con i container lxc non è possibile farlo, quindi ogni operazione di backup dovrà controllare ogni singolo file - questo si è dimostrato efficiente in termini di spazio e deduplicazione, ma piuttosto lento in termini di tempo. Una delle mie VM (750 GB memorizzati ma con sporadico accesso al disco) ha richiesto solo alcuni minuti per il backup con dirty bitmap, ma più o meno 2 ore per il backup da quando è stata trasformata in un contenitore lxc.

Il backup con borg si è dimostrato abbastanza efficiente, così ho cercato di trovare un modo per eseguire il backup di quei contenitori eseguendo una snapshot, eseguendo il backup e, poi, rilasciandola.

Non possiamo usare dattobd sul container, quindi dobbiamo fare una snapshot e fare il backup direttamente dall'host. Questo ha un grande vantaggio: non abbiamo bisogno che il container conosca la sua posizione di backup in quanto ogni operazione sarà fatta dall'host Proxmox.

I miei container sono generalmente memorizzati in volumi rbd di Ceph o in thin pool di LVM.

Ho creato uno script per affrontare entrambe queste situazioni - e non dipende da Proxmox, quindi funziona anche se non lo si usa.

Prima di tutto, si dovrebbe creare un utente e un repository borg su una macchina remota e permettere all'host Proxmox di effettuare il login via ssh usando una chiave. Poi, creare una directory (/tobackup nei seguenti script, sull'host) dove verranno montate le snapshot.

Nell'esempio/script seguente, non verrà utilizzata alcuna crittografia per la memorizzazione di backup. Se si desidera crittografare il backup, sarà necessario eseguire piccole modifiche.

Ecco il mio rbd_borg_bck.sh :

#!/bin/bash
set -e
export SOURCE_DISK=$1
export USERNAME=$2
export HOST=$3
PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes;
echo "Creating and mapping snapshot..."
rbd snap create $SOURCE_DISK@tobackup && DDISK=`rbd map $SOURCE_DISK@tobackup`
echo "Creating backup directory..."
mkdir -p /tobackup/$DDISK
echo "Mounting snapshot..."
mount -o noload $DDISK /tobackup/$DDISK
echo "DOING BACKUP..."
REPOSITORY=$USERNAME@$HOST:$USERNAME/
TAG=daily
borg create -v --stats --progress --compression zlib,9                           \
    $REPOSITORY::$TAG'-{now:%Y-%m-%dT%H:%M:%S}'          \
    /tobackup/$DDISK/                                       \
    --exclude '*/home/*/.cache*'                  \
    --exclude '*/home/*/.local*'                  \
    --exclude '*/home/*/.pki*'                    \
    --exclude '*/home/*/Virtualbox VMs*'          \
    --exclude '*/home/*/.vagrant.d*'              \
    --exclude '*/root/.cache*'                    \
    --exclude '*/var/swap*'
sleep 3s;
echo "Unmounting snapshot..."
umount /tobackup/$DDISK
sleep 3s;
echo "Unmapping snapshot..."
rbd unmap $DDISK
echo "Remove snapshot..."
rbd snap remove $SOURCE_DISK@tobackup
echo "Pruning..."
borg prune -v $REPOSITORY --stats --prefix $TAG'-' \
    --keep-daily=14 --keep-weekly=8 --keep-monthly=12
echo "Done!"

Per esempio, per eseguire il backup di un disco memorizzato nel pool "vmrbdpool" denominato vm-101-disk-0 tramite ssh sul server backupserver.mydomain.org, nome utente sul server (e nome del repository, all'interno della directory home di quell'utente, chiamato server01), si può lanciare lo script in questo modo:

/usr/local/bin/rbd_borg_bck.sh vmrbdpool/vm-101-disk-0 server01 backupserver.mydomain.org

Questo può anche essere programmato e lanciato da cron (sull'host Proxmox) o in qualsiasi altro modo.

Per i thin pool di LVM, lo script è un po' diverso. Ecco il mio lvm_thin_borg_bck.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash
set -e

export SOURCE_DISK=$1
export USERNAME=$2
export HOST=$3
export LVM=$4
export DDISK=$4/$2-borgsnap

PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH

export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes;

echo "Creating and mapping snapshot..."
lvcreate -n $2-borgsnap -s $1
lvchange -ay -Ky $DDISK


echo "Creating backup directory..."
mkdir -p /tobackup/$DDISK

echo "Mounting snapshot..."
mount -o ro /dev/$DDISK /tobackup/$DDISK

echo "DOING BACKUP..."

REPOSITORY=$USERNAME@$HOST:$USERNAME/
TAG=daily

borg create -v --stats --progress --compression zlib,9                           \
    $REPOSITORY::$TAG'-{now:%Y-%m-%dT%H:%M:%S}'          \
    /tobackup/$DDISK/                                       \
    --exclude '*/home/*/.cache*'                  \
    --exclude '*/home/*/.local*'                  \
    --exclude '*/home/*/.pki*'                    \
    --exclude '*/home/*/Virtualbox VMs*'          \
    --exclude '*/home/*/.vagrant.d*'              \
    --exclude '*/root/.cache*'                    

sleep 3s;

echo "Unmounting snapshot..."
umount /tobackup/$DDISK

sleep 3s;

echo "Remove snapshot..."
yes | lvremove $DDISK

echo "Pruning..."
borg prune -v $REPOSITORY --stats --prefix $TAG'-' \
    --keep-daily=14 --keep-weekly=8 --keep-monthly=12

echo "Done!"

In questo esempio, vogliamo fare il backup di un disco "/dev/prox1/vm-120-disk-0", il nome utente sul server è server01 (stesso nome del repository), il server è backupserver.mydomain.org e, come ultimo argomento, "prox1" che è il pool lvm.

/usr/local/bin/lvm_thin_borg_bck.sh /dev/prox1/vm-120-disk-0 server01 backupserver.mydomain.org prox1

Borg è efficiente e veloce e, grazie a questo tipo di configurazione, posso creare un backup del container da 750 GB in 2 minuti.

Grazie a questo tipo di configurazione, i backup possono essere effettuati in modo coerente ed efficiente.

Proxmox Backup Server - Consigli per una buona implementazione

Proxmox

NOTA: Il seguente post è la traduzione dell'equivalente sul blog it-notes. L'originale sarà sempre più aggiornato.

Proxmox Backup Server (PBS) è stato rilasciato. È ancora in beta ma è già perfettamente utilizzabile. Dopo molti anni, è ora possibile eseguire backup incrementali delle VM e grazie alle dirty bitmap di qemu, i backup sono anche veloci.

La documentazione è ben fatta e chiara, quindi suggerisco di darle un'occhiata per tutte le opzioni disponibili.

In breve, permette di eseguire il backup di qualsiasi VM o Container Proxmox su uno specifico server PBS (che può anche eseguire Proxmox o meno - non è indicato eseguire il backup sullo stesso server dove sono in esecuzione le VM). Non richiede alcun file system o impostazione speciale in quanto divide i file in blocchi (quindi la deduplicazione è possibile ed efficiente) e lo storage può essere effettuato in qualsiasi FS supportato.

Lo uso sin dal primo giorno ed è abbastanza efficiente e affidabile, ho fatto il backup di centinaia di server e ne ho ripristinati molti senza problemi.

Ecco alcuni suggerimenti (questo post sarà aggiornato in base alle novità):

  • Il primo backup sarà lento - almeno quanto un backup tradizionale Proxmox. Non preoccupatevi, è perfettamente normale.
  • NON EFFETTUARE IL TRIM DELLE VM, ma usare l'opzione "discard" come opzione di mount (se Linux): il trim passerà tutti i blocchi "sporchi" e li azzererà, riempiendo il database delle dirty bitmap da considerare per il backup e rallentando il backup successivo (anche se non sarà più grande).
  • Per lo stesso motivo, se volete mantenere più server di backup, ricordate di fare il backup su UN SOLO server PBS e poi di sincronizzarlo su un altro. Il backup delle stesse VM su più server "confonderà" le dirty bitmap e ogni backup sarà più lento (non più grande).
  • A volte la sincronizzazione su un altro server può fallire e rimanere bloccata. Al momento (0.8.11-1), ho scoperto che lo stop non risolve il problema e bisogna riavviare la PBS, altrimenti il task sembrerebbe essere ancora in esecuzione.

Il PBS ha risolto un problema di lungo corso: eseguire backup efficienti, deduplicati e incrementali di Proxmox VM.

BTRFS: effettuare automaticamente snapshot e backup remoti

BTRFS

Utilizzo con soddisfazione BTRFS (ne ho parlato nel 2014 e, più recentemente, nel blog IT-Notes). Non lo considero ottimale per tutti i tipi di carico, ma risolve molti problemi in moltissime situazioni. Una delle cose che utilizzo con più soddisfazione è la funzione di generazione dinamica di snapshot, che garantisce la possibilità di avere una copia perfetta e immediata di uno specifico volume (o subvolume). Quando è necessario un backup, ad esempio, l'utilizzo delle snapshot è fondamentale e averle a livello di file system è senza dubbio un buon ausilio.

Quando si tratta di volumi BTRFS, però, abbiamo ulteriori opzioni. Ci sono strumenti nativi che sono in grado di inviare e ricevere dati da e verso volumi BTRFS in maniera ottimizzata, sfruttando le caratteristiche intrinseche del file system stesso. Ecco dunque un metodo per fare automaticamente delle snapshot e trasferirle, in maniera ottimale, su un altro volume BTRFS (locale o remoto).

Da un po' di tempo mi avvalgo di due script interessanti. In passato ho utilizzato snapper ma non l'ho trovato ottimale per il mio utilizzo. Ho dunque continuato ad effettuare ricerche e trovato delle valide alternative, ovvero l'accoppiata di btrfs-snp e btrfs-sync

btrfs-snp

btrfs-snp permette di essere lanciato con un path, un prefisso legato alla snapshot effettuata, il numero massimo di snapshot con quel prefisso da tenere e un tempo minimo tra una snapshot e l'altra.

Ad esempio:

root@foobar:~# /usr/local/sbin/btrfs-snp / hourly  10 3600

Effettuerà una snapshot di /, mettendo come prefisso il termine hourly (ma può essere qualsiasi prefisso), ne terrà massimo 10 e non ne effettuerà altri (ovvero il programma uscirà senza fare azioni) a meno di 3600 secondi dal precedente.

Si possono ovviamente combinare in questo modo, per avere più snapshot di tipo diverso:

/usr/local/sbin/btrfs-snp / hourly  10 3600
/usr/local/sbin/btrfs-snp / daily    3 86400
/usr/local/sbin/btrfs-snp / weekly   1 604800

Può essere lanciato da un cron ogni ora (o ogni quarto d'ora, tanto non effettuerà snapshot a meno di 3600 secondi dal precedente).

btrfs-sync

A questo punto, possiamo copiare su altro file system (locale o remoto) tutte le snapshot grazie a btrfs-sync.

Il comando può essere di questo tipo:

root@foobar:~# /usr/local/sbin/btrfs-sync -d -v /.snapshots btrfs@host:/backups/host01/

Ovviamente il file system di destinazione deve essere un volume BTRFS.

Di solito lancio il comando attraverso uno script nel cron.daily, per avere una copia giornaliera delle snapshot fuori.

Questo tipo di setup mi ha già tolto dai guai più volte e sembra essere efficiente.

Docker: come limitare la crescita incontrollata dei log dei container

(English version, Rotating Docker log files available on IT-Notes blog)

Ho già scritto in merito al fatto che io apprezzi Docker come soluzione per il deploy di specifici servizi. Invece che "sporcare" le singole distribuzioni e dover tenere tutto aggiornato alle versioni delle stesse, si può avere un sistema pulito, replicabile, aggiornabile rapidamente.

Uno dei problemi che ho riscontrato è però questo: quando si hanno dei container che non vengono aggiornati spesso (o, meglio, ricreati spesso), il loro output continua ad accumularsi in un file di log legato al container stesso. Alla fine si rischia di trovarsi con un log enorme e nessuna cognizione di come ridurne le dimensioni.

In un caso specifico, ho avuto un riempimento di disco proprio a causa di uno di questi container (gitlab) che, producendo molto output, aveva creato un json di log di svariate decine di giga in pochi mesi. Facendo una breve ricerca ho trovato la soluzione. E' semplice e Docker supporta, tramite parametri di creazione dei singoli container, la gestione dei log.

Basta dunque passare questi parametri:

--log-opt max-size=50m --log-opt max-file=5

Il container, a quel punto, limiterà il log a 50 mega (limite da definirsi in base alle proprie necessità) ed effettuerà una rotazione dei log stessi (nell'esempio, terrà al massimo 5 log).

In questo modo l'occupazione disco sarà sotto controllo. Perché, dunque, non hanno impostato un limite sano di default? Perché si parte dal presupposto che i container siano usa e getta e che, dunque, vengano spesso buttati e ricreati. La cosa ha una sua logica, ma non è certamente adatta a tutti gli innumerevoli utilizzi.