Un disco USB cifrato con Fedora Core 6

2007-02-15

Diario delle Revisioni
Revisione 0.1.02007-02-15MP
Prima versione

Presentazione

Come creare un disco USB cifrato senza troppi dolori con Fedora Core 6. Grazie al nuovo supporto per la crittografia LUKS (Linux Unified Key Setup), alle nuove caratteristiche di HAL e del desktop di Gnome, è possibile avere comodamente una migliore protezione dei propri dati.


Sommario

1. Impostazioni iniziali
2. Che tipo di disco?
3. Preparazione della partizione
4. La cifratura con LUKS
5. Il filesystem
6. Il collaudo finale
7. Quanto costa?
8. Riferimenti
9. Strumenti utilizzati
10. Versioni aggiornate

1. Impostazioni iniziali

L'installazione di Fedora dovrebbe avere già tutto il necessario per la creazione e l'uso di queste funzioni di sicurezza. C'è un piccolo pacchetto nel deposito Extras di Fedora che aiuta nella creazione del disco cifrato, ma è opzionale. Il pacchetto si chiama luks-tools ed è piccolissimo. Contiene una interfaccia grafica per la creazione e formattazione della unità cifrata, che si avvia con il comando gnome-luks-format (Figura 1, «Utility di creazione di unità cifrate»).

Figura 1. Utility di creazione di unità cifrate

Utility di creazione di unità cifrate

Controlliamo di aver installato il pacchetto cryptsetup-luks, senza il quale le operazioni sono un po' più difficoltose. Poi occorre una piccola modifica ad un file di configurazione di udev. A causa di alcuni problemi con un modulo del kernel, è stato disabilitato il supporto per il device mapper in udev. Per questo motivo ho perso alcune ore a capire dove era il problema, poi una ricerca in Bugzilla, il sistema di tracciamento dei bug di Fedora, mi ha portato su questa pagina che riporta la soluzione.

Aprire in modifica il file /etc/udev/rules.d/50-udev.rules, e commentare la riga 165 aggiungendo un carattere # ad inizio riga in questo modo:


#KERNEL=="dm-[0-9]*", ACTION=="add", OPTIONS+="ignore_device"

# alsa devices
KERNEL=="controlC[0-9]*",       NAME="snd/%k"
KERNEL=="hw[CD0-9]*",           NAME="snd/%k"

Non occorre riavviare il computer, la modifica è immediatamente attiva. Possiamo passare a creare il nostro disco ad alta sicurezza.

2. Che tipo di disco?

Possiamo usare qualsiasi disco esterno USB o Firewire. Possiamo anche usare un pen drive USB senza problemi. Ovviamente, dipende dal tipo di uso che vogliamo farne. La procedura funziona su qualsiasi tipo di disco riconosciuto da Linux.

Si potrebbe anche cifrare una partizione del sistema operativo, ma in questo caso la procedura è un po' più complicata, ed implica che all'avvio dobbiamo inserire noi la password di accesso alla partizione cifrata, altrimenti il sistema non potrà avviarsi. Potrebbe essere oggetto di un prossimo articolo, per ora concentriamoci su un disco esterno.

3. Preparazione della partizione

Se il disco è nuovo non abbiamo problemi, possiamo creare la partizione senza indugi. Diversamente, se contiene già dei dati, non possiamo creare la partizione cifrata senza distruggere il contenuto del disco: purtroppo è inevitabile. Quindi occorre svuotare il disco del contenuto e procedere poi a rimetterci i dati una volta creata la partizione cifrata.

Supponendo di avere il disco vuoto e pronto, partiamo dal capire a quale device fare riferimento, inserendo il disco sulla presa USB e usando il comando dmesg da un terminale dove siamo root:

# dmesg
... (altri messaggi)
usb-storage: device found at 35
usb-storage: waiting for device to settle before scanning
scsi 25:0:0:0: Direct-Access     SAMSUNG  HM060HC          YJ10 PQ: 0 ANSI: 0
SCSI device sdd: 117231407 512-byte hdwr sectors (60022 MB)
sdd: Write Protect is off
sdd: Mode Sense: 03 00 00 00
sdd: assuming drive cache: write through
SCSI device sdd: 117231407 512-byte hdwr sectors (60022 MB)
sdd: Write Protect is off
sdd: Mode Sense: 03 00 00 00
sdd: assuming drive cache: write through
 sdd: sdd1
sd 25:0:0:0: Attached scsi disk sdd
sd 25:0:0:0: Attached scsi generic sg3 type 0
usb-storage: device scan complete

In questo esempio il disco è assegnato al device /dev/sdd ha già una partizione all'interno, /dev/sdd1. Andiamo a vedere che partizione è:

# fdisk /dev/sdd

The number of cylinders for this disk is set to 7297.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/sdd: 60.0 GB, 60022480384 bytes
255 heads, 63 sectors/track, 7297 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdd1               1        7297    58613121    7  HPFS/NTFS

E' una partizione di tipo NTFS, con cui esce il disco dalla fabbrica. Per il nostro esempio scegliamo di usare tutto il disco con una singola partizione che conterrà un filesystem di tipo ext3, visto che lo useremo solo con Linux.

Si potrebbe usare anche FAT32, ma...

Il problema è che il supporto per le partizioni cifrate con LUKS è nativo per Linux, mentre per Windows esiste un progetto analogo, che però non ho provato. Per chi è interessato si trova qui.

Cancelliamo la partizione NTFS e andiamo a creare quella per Linux:

# fdisk /dev/sdd

The number of cylinders for this disk is set to 7297.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): d  (cancellare la partizione)
Selected partition 1

Command (m for help): p  (vediamo lo stato)

Disk /dev/sdd: 60.0 GB, 60022480384 bytes
255 heads, 63 sectors/track, 7297 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n  (nuova partizione)
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-7297, default 1): <Invio>
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-7297, default 7297): <Invio>
Using default value 7297

Command (m for help): w  (scriviamo le modifiche)
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

La partizione è pronta, con identificativo di device /dev/sdd1. Ora passiamo a creare il supporto per la cifratura.

4. La cifratura con LUKS

Per funzionare correttamente, LUKS deve creare una struttura di dati all'inizio della partizione fisica che andremo ad utilizzare. In questo blocco di dati saranno memorizzate fino a otto differenti password per sbloccare la chiave di cifratura, la chiave di cifratura stessa ed altre informazioni necessarie per il lavoro.

Per prima cosa allora andiamo a creare la struttura dati, usando sempre da utente root il comando:

# cryptsetup luksFormat /dev/sdd1

WARNING!
========
This will overwrite data on /dev/sdd1 irrevocably.

Are you sure? (Type uppercase yes): YES (tutto in maiuscolo)
Enter LUKS passphrase: inserire la password scelta
Verify passphrase: ripetere la password
Command successful.

Al termine del comando abbiamo la struttura dati pronta per l'uso, con la password di sblocco scelta da noi. E' possibile scegliere l'algoritmo di cifratura, che se non specificato è AES. Dato che il supporto per la cifratura è fornito dal kernel, attraverso una serie di moduli caricabili. Per sapere che tipo di algoritmi sono disponibili basta dare il comando (attenzione agli apici al contrario):

# ls /lib/modules/`uname -r`/kernel/crypto/
aes.ko        cast5.ko        deflate.ko  md5.ko          tea.ko
anubis.ko     cast6.ko        des.ko      michael_mic.ko  tgr192.ko
arc4.ko       cbc.ko          ecb.ko      serpent.ko      twofish_common.ko
blkcipher.ko  crc32c.ko       khazad.ko   sha256.ko       twofish.ko
blowfish.ko   crypto_null.ko  md4.ko      sha512.ko       wp512.ko

Non tutti i moduli rappresentano algoritmi di cifratura, alcuni sono di hash, come per esempio md4, md5 e sha256. Per capire con certezza se è adatto per la cifratura basta caricare il modulo corrispondente e vedere nel file /proc/crypto se nelle informazioni riporta la voce type : cypher. Se invece riporta type : digest è un algoritmo di hash.

In ogni caso il default è robusto quanto basta, e non troppo lento, oltre a non essere vulnerabile a tentativi di decifrazione con il watermarking attack, un metodo che attraverso la scrittura sul disco di ripetute sequenze predeterminate di dati consente di risalire alla chiave di cifratura. Vedremo che la cifratura ha un prezzo, non eccessivo, ma da tenere in conto.

Ora sblocchiamo la partizione cifrata per poter creare il filesystem voluto:

# cryptsetup luksOpen /dev/sdd1 enigma
Enter LUKS passphrase: (inseriamo la password)
key slot 0 unlocked.
Command successful.

I parametri del comando sono: l'operazione (luksOpen), sblocca la partizione cifrata; il dispositivo cifrato (/dev/sdd1); il nome di comodo assegnato al dispositivo in chiaro (enigma). Il nome che ho scelto non è proprio a caso...

Il risultato è che viene creato un nuovo device che rappresenta la partizione in chiaro, ossia dopo la decifrazione:

# ll /dev/mapper/
totale 0
crw------- 1 root root  10, 63 14 feb 08:22 control
brw-rw---- 1 root disk 253,  0 14 feb 16:02 enigma

Ora passiamo a creare il filesystem nella partizione in chiaro.

5. Il filesystem

Come abbiamo detto in precedenza, in questo esempio useremo un filesystem di tipo ext3, ma il tipo di filesystem è indifferente: la cifratura viene applicata sotto lo strato del filesystem, ed è trasparente all'uso.

Andiamo allora a creare il nostro filesystem:

# mkfs.ext3 -m 0 -L privato /dev/mapper/enigma
mke2fs 1.39 (29-May-2006)
Etichetta del filesystem=privato
Tipo SO: Linux
Dimensione blocco=4096 (log=2)
Dimensione frammento=4096 (log=2)
7340032 inode, 14653151 blocchi
0 blocchi (0.00%) riservati per l'utente root
Primo blocco dati=0
Maximum filesystem blocks=0
448 gruppi di blocchi
32768 blocchi per gruppo, 32768 frammenti per gruppo
16384 inode per gruppo
Backup del superblocco salvati nei blocchi: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624, 11239424

Scrittura delle tavole degli inode: fatto                           
Creazione del journal (32768 blocchi): fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto

Questo filesystem verrà automaticamente controllato ogni 34 mount, o
180 giorni, a seconda di quale venga prima. Usare tune2fs -c o -i per cambiare.

Con questo comando abbiamo creato nel device in chiaro (/dev/mapper/enigma) un filesystem di tipo ext3, che possiede la funzione di journaling, utile per ridurre il rischio di perdita di dati in caso di disconnessione accidentale. Non verrà riservato nessuno spazio ad uso esclusivo dell'utente root (-m 0), invece del normale cinque percento. Il volume creato avrà come etichetta privato: è il nome con cui verrà riconosciuto e montato dalle funzioni automatizzate di Gnome, cioè al momento del mount ci apparirà sul desktop una icona a forma di disco dal nome identico all'etichetta assegnata al filesystem. Non è obbligatorio, ma ci renderà più facile riconoscere il disco una volta montato, visto che verrà montato sotto la directory /media/privato, ossia una sottodirectory in /media con lo stesso nome del filesystem.

Abbiamo quasi terminato: possiamo ora bloccare di nuovo l'unità cifrata, con il comando:

# cryptsetup luksClose enigma

poi verifichiamo che sia stato eliminato il dispositivo in chiaro:

# ll /dev/mapper/
totale 0
crw------- 1 root root 10, 63 15 feb 08:51 control

Siamo pronti per il debutto.

6. Il collaudo finale

Con il desktop di Gnome attivo, con un utente normale, insomma il solito che usiamo per lavorare, scolleghiamo il disco USB, aspettiamo qualche secondo e ricolleghiamolo alla porta USB. Entro 5-10 secondi, dipende da quanto impiega il disco ad avviarsi, appare il pannello di Gnome di richiesta password (Figura 2, «Il pannello di richiesta password»). Possiamo inserire la password di sblocco e in pochi secondi abbiamo il disco pronto per l'uso.

Figura 2. Il pannello di richiesta password

Il pannello di richiesta password

Siamo pronti per scrivere e leggere i nostri dati dal disco. Se, pur comparendo il pannello di richiesta password e digitando la password corretta, il disco non viene montato automaticamente, vuol dire che non abbiamo modificato correttamente il file di configurazione di udev come spiegato in precedenza (Modifiche a udev).

7. Quanto costa?

Il metodo usato è chiamato transparent on-the-fly disk encryption, perché ogni operazione di lettura comporta la decifrazione ed ogni scrittura la cifratura di ogni singolo byte letto o scritto. Dato che la crittografia è praticamente pura matematica, stiamo parlando di calcoli a fiumi. La domanda che ci poniamo è: quanto “pesa” l'operazione di cifratura?

Il computer di test è un Pentium IV™ a 3,4GHz, con un gigabyte di RAM. Il disco USB è un tipico disco da notebook da 2,5 pollici.

Il test più semplice che possiamo fare implica una lettura a basso livello del contenuto del disco di un grosso volume di dati che non vengono poi utilizzati, in modo da non inquinare il test con altri fattori. L'operazione è prima di leggere due gigabyte di dati dalla partizione senza decifrarli, ossia direttamente dalla partizione fisica:

# dd if=/dev/sdd1 of=/dev/null bs=1M count=2000
2000+0 records in
2000+0 records out
2097152000 bytes (2,1 GB) copied, 67,119 seconds, 31,2 MB/s

Vediamo nel dettaglio: di 67 secondi, una minima parte è stata impegnata ad eseguire operazioni da parte del processore, il resto è stato speso in attesa dei dati dal disco, certamente molto più lento a fornirli del processore ad utilizzarli, cioè in questo caso a scriverli sul device speciale /dev/null, un device che ad ogni operazione di scrittura semplicemente ritorna dicendo “ho già fatto”, quindi un tempo praticamente nullo. La velocità calcolata dal comando dd è abbastanza normale per questo tipo di dischi.

Vediamo ora di leggere dati dal device cifrato allo stesso modo. Con il comando mount possiamo individuare su quale device è disponibile il disco in chiaro:

# mount
... altre righe che non ci interessano	
/dev/dm-0 on /media/privato type ext3 (rw,noexec,nosuid,nodev)

Il device è /dev/dm-0, passiamo a dare il comando identico a prima cambiando solo il device:

# time dd if=/dev/sdd1 of=/dev/null bs=1M count=2000
2000+0 records in
2000+0 records out
2097152000 bytes (2,1 GB) copied, 104,265 seconds, 20,1 MB/s

Come possiamo vedere l'impatto della cifratura è piuttosto consistente, ma non tale da rendere inutilizzabile il tutto. Anzi, possiamo tranquillamente usare il disco esterno anche per musica e video, la banda disponibile è sufficiente anche per questo tipo di applicazioni. Ovviamente, minore è la potenza di calcolo a disposizione, maggiore diventa la differenza fra normale e cifrato, ma questo è prevedibile.

In conclusione, possiamo dire che è un prezzo che potrebbe valere la pena di pagare, visto che in cambio chiudiamo i dati in cassaforte.

8. Riferimenti

Per ulteriori notizie ed approfondimenti:

9. Strumenti utilizzati

Per realizzare questo documento ho usato l'ambiente di creazione ed elaborazione testi di Fedora, aderente allo standard aperto DocBook XML, disponibile sul sito http://www.docbook.org/tdg/en/html/docbook.html. Il file XML sorgente di questo documento è stato realizzato con VIM, usando un file di personalizzazione dei comandi per velocizzare la digitazione dei tag più usati.

10. Versioni aggiornate

Versioni aggiornate di questo documento le potete trovare sul mio sito web: http://ismprofessional.net/pascucci, insieme a molto altro.