[glux] Crypto USB disk

Andrea aerdan@inventati.org
Gio 23 Feb 2006 22:54:19 CET


Creare una partizione cryptata su chiavetta USB

SO GNU/Debian Sarge 3.1 r0 aggiornata (oggi) da security.debian.org 

Per prima cosa occorre identificare in modo univoco la chiave affinchè i tools
per la gestione delle partizioni criptate operino solo sulla specifica chiavetta
e non su qualsiasi chiavetta USB sia collegata.

Per prima cosa occorre quindi creare una regola di udev che identifichi il
dispositivo in modo sicuro.

REGOLE UDEV
-------------------------------------------------------------------------------

Documentazione:

	-le man page:
		udev (8)             - Linux configurable dynamic device naming support
		udevd (8)            - udev event serializer daemon and udev event sender
		udevdsend (8) [udevsend] - udev event serializer daemon and udev event sender
		udevinfo (8)         - retrieve information from udev
		udevsend (8)         - udev event serializer daemon and udev event sender
		udevstart (8)        - populate initial device directory
		udevtest (8)         - simulates a udev run to test the configured rules
	-http://www.reactivated.net/writing_udev_rules.html

Per assegnare lo stesso file di dispositivo a  una periferica rimovibile.
Mi assicuro che l'opzione:

	udev_log

nel file /etc/udev/udev.conf sia impostata a "yes" così che gli eventi che
implicano udev siano loggati in /var/log/syslog. Serve ora per verificare la
regola, in seguito si può anche impostare a "no" anche se, a parer mio, è meglio
lasciarla impostata su "yes".

Collego la periferica e controllo nel file di log di sistema i messaggi
di udev con:

	# tail /var/log/syslog

Nel mio caso collego una chiave USB tail restituisce:

	Feb 16 22:40:55 localhost kernel: usb 3-3: new high speed USB device using
	address 5
	Feb 16 22:40:55 localhost kernel: scsi1 : SCSI emulation for USB Mass Storage
	devices
	Feb 16 22:40:55 localhost kernel:   Vendor: VBTM      Model: Store 'n' Go
	Rev: 1.02
	Feb 16 22:40:55 localhost kernel:   Type:   Direct-Access
	ANSI SCSI revision: 02
	Feb 16 22:40:56 localhost kernel: SCSI device sda: 2013184 512-byte hdwr sectors
	(1031 MB)
	Feb 16 22:40:56 localhost kernel: sda: assuming Write Enabled
	Feb 16 22:40:56 localhost kernel: sda: assuming drive cache: write through
	Feb 16 22:40:56 localhost kernel:  sda: sda1
	Feb 16 22:40:56 localhost kernel: Attached scsi removable disk sda at scsi1,
	channel 0, id 0, lun 0
	Feb 16 22:40:56 localhost kernel: USB Mass Storage device found at 5
	Feb 16 22:40:56 localhost udev[5880]: configured rule in
	'/etc/udev/rules.d/z_hal-plugdev.rules[2]' applied, 'sda' becomes '%k'
	Feb 16 22:40:56 localhost udev[5880]: creating device node '/dev/sda'
	Feb 16 22:40:56 localhost udev[5904]: configured rule in
	'/etc/udev/rules.d/z_hal-plugdev.rules[2]' applied, 'sda1' becomes '%k'
	Feb 16 22:40:56 localhost usb.agent[5908]:      usb-storage: already loaded
	Feb 16 22:40:56 localhost udev[5904]: creating device node '/dev/sda1'
	Feb 16 22:40:56 localhost scsi.agent[5934]:      sd_mod: loaded sucessfully (for
	disk)
	Feb 16 22:40:56 localhost kernel: EXT2-fs warning: mounting unchecked fs,
	running e2fsck is recommended

Ora so che la chiave viene collegata ad un file di dispositivo sd*, in questo
caso sda1 quindi cerco il percorso in /sys dove cercare informazioni sul
dispositivo:

	# udevinfo -q path -n /dev/sda1
	/block/sda/sda1

Ora elenco le informazioni specifiche del dispositivo:

	# udevinfo -a -p /block/sda/sda1 | less

faccio una pipe con less perchè le informazioni sono moltissime.

Per identificare univocamente il dispositivo utilizzo il numero seriale ed
eventualmente l'identificativo del produttore:

	SYSFS{idVendor}="08ec"
	SYSFS{serial}="0D312B510323092A"

Compongo la regola di udev:

BUS="scsi", KERNEL="sd*", SYSFS{idVendor}="08ec", \
SYSFS{serial}="0D312B510323092A", NAME="%k", SYMLINK="cryptohd%n", \
GROUP="andrea", OWNER="andrea", MODE="0700"

Solo il dispositivo che soddisfa le due condizioni: "idVendor" e "serial"
utilizzerà questa regola creando, di conseguenza, il symlink specificato.

Non capisco il perchè ma se utilizzo BUS="scsi" la regola non viene utilizzata
ed è sostituita con la regola:

	z_hal-plugdev.rules

In teoria le regole sono lette in ordine alfabetico nella dir /etc/udev/rules.d
e quindi doverebbe essere la nuova regola ad essere applicata.

Utilizzando:

	BUS="usb" ...

la regola funziona e il dispositivo crea il link simbolico correttamentei.

Inserendo, ad esempio, la linea:

	/dev/cryptohd1  /mnt/cryptousb  ext2    rw,user,noauto  0       0

in /etc/fstab e creando la directory /mnt/cryptousb posso montare il filesystem
sulla chiave usb semplicemente con:

	mount /mnt/cryptousb

Ovviamente, in /etc/fstab, devo indicare il filesystem corretto presente sulla
chiave USB.

Aggiunta la linea in /etc/fstab la chiave USB viene montata automaticamentei.

A questo punto si può procedere alla creazione della partisione cryptata.

Installo i pacchetti:

	-cryptsetup (configura i dispositivi a blocchi crittati)
	-dmsetup (gestore a basso livello di volumi logici)
	-libdevmapper1.01 (librerie per l'accesso a device-mapper)

sono aggiunti:

	Adding system startup for /etc/init.d/cryptdisks ...
	/etc/rc0.d/S48cryptdisks -> ../init.d/cryptdisks
	/etc/rc6.d/S48cryptdisks -> ../init.d/cryptdisks
	/etc/rcS.d/S28cryptdisks -> ../init.d/cryptdisks

Vedere docs:

	-man crypttab
	-man dmsetup
	-/etc/crypttab
	-man cryptsetup
	-/usr/share/doc/cryptsetup
	-/sbin/cryptsetup --help
	
Per utilizzare cryptsetup occorre sicuramente un kernel > 2.6.4 con dm-crypt
compilato (staticamente o come modulo).

Aggiungo la linea seguente in /etc/crypttab

	cryptousb       /dev/cryptohd1  none    cipher=aes,size=256,verify

Il primo campo è il nome del file che verrà creato in /dev/mapper/ e sarà il
nostro punto di accesso al filesystem, l'equivalente del primo campo nel file
/etc/fstab ma privo del percorso assoluto. Il secondo campo è il nome del link
simbolico che abbiamo fatto creare a udev. Per gli altri campi consulatare la
man page di crypttab

In questa fase sfrutto lo script:
	
	# /etc/init.d/cryptdisks restart

Verrà chiesto di digitare una frase ed in seguito di ridigitarla. Questa sarà
la frase per decriptare il filesysten!

Se il dispositivo è già montato lo script ritorna un errore e fallisce.

Il modulo kernel Device Mapper permette anche l'utilizzo di file system
journaled quindi RaiserFS e Ext3.

Per avere info sul dispositivo:

	# dmsetup ls
	cryptousb       (254, 0)

	# dmsetup info cryptousb
	Name:              cryptousb
	State:             ACTIVE
	Tables present:    LIVE
	Open count:        0
	Event number:      0
	Major, minor:      254, 0
	Number of targets: 1

Per altri comandi vedere la man page di dmsetup.

Creo il file system sulla chiave usb con il solito:

	# mkfs.ext3 /dev/mapper/cryptousb

Monto il file system in /media/cryptousb e verifico il risultato:

	# mount /dev/mapper/cryptousb /mnt/cryptousb
	# mount
	[...]
	/dev/mapper/cryptousb on /mnt/cryptousb type ext3 (rw)

A questo punto abbiamo creato la partizione criptata ed è attiva.
	
Dato che si tratta di un dispositivo removibile è assurdo che lo script
"cryptdisks" gestisca la linea in crypttab all'avvio per cui occorre mettere a
punto una modalità che permetta di attivare e disattivare la partizione a nostro
piacimento.

Iniziamo col rimuovere la linea aggiunta in precedenza a /etc/crypttab quindi
verifichiamo quali comandi l'utente non root può utilizzare... praticamente
nessuno.

La procedura per montare e smontare la partizione criptata si riassume così:

	1) creo il dispositivo in /dev/mapper con cryptsetup
	2) monto la partizione
	3) smonto la partizione
	4) distruggo il dispositivo in /dev/mapper

Per ovviare al problema dei permessi utilizzo sudo quindi edito il file
/etc/sudoers come segue:

	# Cmnd alias specification
	Cmnd_Alias CRYPTO = /sbin/cryptsetup, /sbin/dmsetup, /bin/mount -t ext3 \
	/dev/mapper/cryptousb /mnt/cryptousb, /bin/umount /mnt/cryptousb

	# User privilege specification
	root    ALL=(ALL) ALL
	utente  localhost = CRYPTO

Lo script che segue, per quanto obrobrioso e incompleto fa ciò che deve fare ;)

#!/bin/bash

# Numero seriale della chiave usb criptata
SERIALE=JJO9HGB79M87TF78

# File di dispositivo utilizzati (in funzione della regola udev
DEV=/dev/cryptohd1
DEV_CRYPT=cryptousb
DEV_MPPR=/dev/mapper/cryptousb
MOUNT_PNT=/mnt/cryptousb

# Comandi necessari allo script
SUDO_CMD=/usr/bin/sudo
UDEVINFO_CMD=/usr/bin/udevinfo
CRYPT_CMD=/sbin/cryptsetup
MOUNT_CMD=/bin/mount
UMOUNT_CMD=/bin/umount
DM_CMD=/sbin/dmsetup

# Opzioni dei comandi
CRYPT_UP_OPT=" create $DEV_CRYPT $DEV"
CRYPT_DWN_OPT=" remove $DEV_CRYPT"
MOUNT_OPT=" -t ext3 $DEV_MPPR $MOUNT_PNT"
UMOUNT_OPT=" $MOUNT_PNT"
DM_OPT=" info $DEV_CRYPT"

# File di configurazione
SUDO_FILE=/etc/sudoers

# Verifica la presenza dei comandi necessari
test -x $SUDO_CMD  || echo $SUDO_CMD: comando non trovato 
test -x $UDEVINFO_CMD  || echo $UDEVINFO_CMD: comando non trovato
test -x $CRYPT_CMD  || echo $CRYPT_CMD: comando non trovato
test -x $MOUNT_CMD  || echo $MOUNT_CMD: comando non trovato
test -x $UMOUNT_CMD  || echo $UMOUNT_CMD: comando non trovato
test -x $DM_CMD  || echo $DM_CMD: comando non trovato
test -f $SUDO_FILE  || echo il file $SUDO_FILE non esiste
#test -x $  || exit 0

# Cerca di scoprire se è stata montata la chiave usb criptata attraverso il
# numero seriale
for SD in a b c d none; do
	X=`$UDEVINFO_CMD -a -p /block/sd$SD | egrep $SERIALE`
	if [ $X =  "SYSFS{serial}="\"$SERIALE\" ]; then
		echo Il device con numero seriale $SERIALE è assegnato alla chiave $SD.
		break
	fi
done

if [ $SD = "none" ]; then echo Nessuna chiave crittografata attiva; fi

# Azioni
case "$1" in
	start)
		$SUDO_CMD mkdir $MOUNT_PNT
		echo "Avvio crypto usbdisk..."
		echo "Inserire la password utente quindi la chiave di decifrazione"
		#Il problema è che non è possibile distinguere tra l'una e l'altra,
		#occorre forzare sempre la pw utente per sudo per il cryptup 
		$SUDO_CMD $CRYPT_CMD $CRYPT_UP_OPT
		#Occorre gestire gli errori bad pw = mount fallito
		if [ -d $DEV_MPPR ]; then 
			echo Decrittazione del dispositivo fallita
			exit 0
		fi
		$SUDO_CMD $DM_CMD $DM_OPT
		$SUDO_CMD $MOUNT_CMD $MOUNT_OPT
		echo "Usbdisk correttamente montato"
		;;	
	stop)
		echo "Arresto crypto usbdisk"
		$SUDO_CMD $UMOUNT_CMD $UMOUNT_OPT
		$SUDO_CMD $CRYPT_CMD $CRYPT_DWN_OPT
		#Verificare l'effettivo umount e crypt down
		$SUDO_CMD rmdir $MOUNT_PNT
		;;
	*)
		echo "Opzione sconosciuta"
		;;
esac
-- 
ð Gli uomini sono fratelli fra loro. Cessano di esserlo quando
¶ la terra viene divisa da steccati e confini.
ñ
²			Heinmot-Tayala-Ket, Nez Percé
€
¯ KeyID:   5AF81406   2005-01-03   [scadenza: 2015-01-01]
3 KeyFpr:  A4E2 7C7C CFC7 1B1E E405  6443 9E07 AF95 5AF8 1406


Maggiori informazioni sulla lista glux