Script bash per montare una share di rete e un volume TrueCrypt

Può capitare di essere distanti da casa e di dover accedere a dei dati in "cassaforte". Nel mio caso la cassaforte è rappresentata da un bel volume criptato tramite TrueCrypt che risiede in un'unità condivisa. Accedervi però dall'esterno della propria rete non è poi così semplice. Innanzitutto bisognerebbe instaurare una connessione con il "campo base" tramite VPN o tunneling SSH ad esempio, ed in secondo luogo trasferire questo volume sul dispositivo remoto per poi aprirlo. Questo è ancora fattibile se il volume ha dimensioni contenute, la cosa diventa abbastanza improponibile quando il volume criptato comincia a superare i 100MB. Come sappiano tutti in Italia non brilliamo certo in connettività... anzi ora che ci penso non brilliamo proprio in niente 😀

Come fare quindi ad accedere a dati sensibili da remoto? Raspberry PI salvaci tu! L'idea è quella di usare il Raspberry per montare l'unità di rete su cui risiede il volume criptato e utilizzare TrueCrypt (anche esso installato sul Raspberry) per poterlo decifrare e leggerene il contenuto.

I dati nel mio caso risiedono in un NAS, ma il volume di TrueCrypt in questione può tranquillamente essere utilizzato direttamente dal Raspberry. Per la connessione con quest'ultimo invece io utilizzerò prima una OpenVPN e in seguito SSH per la connessione ((E se non ne siete ancora convinti fidatevi di me quanto vi dico che SSH è DIVINO)). In alternativa si può utilizzare anche un bel tunnel SSH opportunamente messo in sicurezza, magari anche con una autentificazione a due fattori e fail2ban (o simili). Evitate di esporre verso l'esterno un server SSH sulla porta standard, con account root attivo e magari una password debole.
La prima difficoltà che dovremmo superare è la mancanza di TrueCrypt nei repository del Raspberry. Magari in giro si riesce a trovare il pacchetto .deb già pronto per l'uso, personalmente lo ho compilato da zero. L'operazione non è difficile è solo lunghetta. Tutte le operazioni di effettuare sono riportate in modo semplice e preciso in questo post. 😉

Fatto questo il nostro piccolo Raspberry sarà in grado di gestire volumi criptati e quindi potremmo procedere con il nostro progetto.

Ora ci basterà dire a Debian di montare l'unità di rete su cui si trova il volume di TrueCrypt ed in seguito montare lo stesso. Per fare questo ho scritto questo semplice script in bash che ci permetterà appunto di fare le operazioni appena citate. Non è assolutamente niente di trascendentale però fa il suo sporco lavoro. Copiatelo in un file vuoto e dategli un'estensione sh.

#!/bin/bash
## samba configuration
SERVER_IP="<ip-server>"
SHARE_NAME="<share-name>"
FOLDER_NAME="<folder-name>"
USR_NAME="<share-credentials-username>"
USR_PASSWORD=""
#DOMAIN="<my-domain>"
UID_SHARE="<username>"
GID_SHARE="<username-group>"

## mount point configuration
PATH_MOUNT_SHARE="</home/user>"
FOLDER_MOUNT_SHARE="<my-folder>"
PATH_MOUNT_TC="</home/user>"
FOLDER_MOUNT_TC="<my-tc-folder>"

## truecrypt configuration
TC_VOLUME_NAME="<tc-filename.tc>"

## >>>>>>>>>>>>>>>>>>>>>>>>>
## DO NOT EDIT BELOW
## <<<<<<<<<<<<<<<<<<<<<<<<<
VERSION="0.2"

function help(){
	echo "This script mount a network share and a truecrypt volume

-h, --help			show this help text
-v, --version			show script version
-m, --mount			mount both network cifs share and truecrypt volume
-mtc, --mount-only-tc		mount only truecrypt volume
-ms, --mount-only-share		mount only network share
-u, --umount			unmount all
-utc, --umount-only-tc		unmount only the truecrypt volume
-us, --umount-only-share	unmount only the network share
-s, --status			show if network share and truecrypt are mounted or not
"
}


case "$1" in
	-h | --help)
		help
		;;
	-v | --version)
		echo $VERSION
		;;
	-m | --mount)
		stty -echo
		read -p "Enter password for the network share: " USR_PASSWORD; echo
		stty echo
		mount.cifs //$SERVER_IP/$SHARE_NAME/$FOLDER_NAME $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE -o username=$USR_NAME,password=$USR_PASSWORD,rw,uid=$UID_SHARE,gid=$GID_SHARE 0 	0
		truecrypt -t -k "" --protect-hidden=no $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE/$TC_VOLUME_NAME $PATH_MOUNT_TC/$FOLDER_MOUNT_TC -v -m=nokernelcrypto
		;;
	-mtc | --mount-only-tc)
		truecrypt -t -k "" --protect-hidden=no $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE/$TC_VOLUME_NAME $PATH_MOUNT_TC/$FOLDER_MOUNT_TC -v -m=nokernelcrypto
		;;
	-ms | --mount-only-share)
		stty -echo
		read -p "Enter password for the network share: " USR_PASSWORD; echo
		stty echo
		mount.cifs //$SERVER_IP/$SHARE_NAME/$FOLDER_NAME $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE -o username=$USR_NAME,password=$USR_PASSWORD,rw,uid=$UID_SHARE,gid=$GID_SHARE 0 	0
		;;
	-u | --umount)
		truecrypt -d $PATH_MOUNT_TC/$FOLDER_MOUNT_TC
		umount $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE
		;;
	-utc | --umount-only-tc)
		truecrypt -d $PATH_MOUNT_TC/$FOLDER_MOUNT_TC
		;;
	-us | --umount-only-share)
		umount $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE
		;;
	 -s | --status)
		if mountpoint -q $PATH_MOUNT_SHARE/$FOLDER_MOUNT_SHARE; then
			if mountpoint -q $PATH_MOUNT_TC/$FOLDER_MOUNT_TC; then
				echo "Both share and tc volume are mounted"
			else
				echo "Only the share is mounted"
			fi
		else
			echo "No mount detected"
		fi
		;;
	*)
		help
		;;
esac

Lo script è parametrizzato e necessita di una sistemata prima di poter essere utilizzato. Le variabili presenti ad inizio file dovranno essere correttamente compilate in modo da essere congrue con il vostro scenario di utilizzo. Ecco alcune note:
Diamo una sguardo alle prime righe, qua basterà inserire l'indirizzo del server dove risiede la cartella condivisa, il nome della stessa, e l'eventuale cartella in cui risiede il file .tc del volume criptato. Bisogna inserire SOLO il nome utente per l'autentificazione alla cartella condivisa. La variabile USR_PASSWORD non deve essere toccata. Questo perchè ho pensato lo script per non memorizzare su file le password. Non è per niente bello avere in plaintext le password per accedere a una share o quella per decifrare un volume criptato. Durante l'esecuzione vi verranno chieste entrambe le password. In questo modo nulla sarà visibile in plaintext o nella history del terminale. Il dominio penso che per la maggior parte dei casi non sia necessario, nel caso lo fosse basta levare il commento e modificare la riga dove viene effettuato il mount.cifs.
UID_SHARE e GID_SHARE sono due variabili molto importanti. Dato che il mount di una share deve essere fatto come utente root (quindi lo script andrà eseguito come root) solo l'amministratore avrà diritti di read/write su quel mount point. Questo significa che il nostro povero utente (a meno di utilizzare sempre l'utente root) sarà tagliato fuori. Utilizzando queste due variabili invece diamo i permessi di lettura a scrittura all'utente che a noi interessa. Quindi se noi utilizziamo l'utente "andrea" dovremmo scrivere: UID_SHARE="andrea".
Per risalire ai gruppi associati ad un utente possiamo usare il comando:

groups <username>

Le altre variabili contengono il path di dove si troverà la cartella su cui verrà effettuato il mount della share di rete e del volume di TrueCrypt con il nome della relativa cartella che farà da mount point. Infine l'immancabile variabile che contiene il nome del volume criptato.

L'utilizzo è molto semplice. Una volta completata la parametrizzazione basta lanciare il comando:

./mount.sh -m

Questo monterà sia share sia il volume criptato. Mi raccomando tutti i comandi che implicano il mount o l'unmount della share di rete devono essere eseguiti come root. Dobbiamo quindi utilizzare sudo.

Per mostrare a video l'help diamo il comando:

./mount.sh -h

Have fun 😉

NOTE

In questo spazio scrivo su alcuni problemi che ho riscontato e le relative soluzioni.

Permessi read/write sulla share ma solo lettura sul volume TrueCrypt
Nel mio caso il problema era dovuto al fatto che il volume criptato era partizionato in NTFS, che sappiano non essere proprio l'ideale se utilizzato in ambiente *UNIX. Basta copiare tutti i dati in una cartella temporanea, formattare il volume in FAT32, ricopiare i dati nel volume criptato e cancellare i dati temporanei (magari utilizzando Ereaser :D)