
Crittografia completa del disco per Kali su Raspberry utilizzando LUKS
Questo HOWTO è dedicato all'esecuzione di Kali su Raspberry (o altre architetture simili, es. ODROID-C2 usando la cifratura completa del disco con LUKS. Basato sul documento un po' datato qui.
Distribuire Kali su Raspberry Pi (o altro hardware simile, piccolo e a basso consumo) in una rete LAN come "throw-away-hackbox" è ovviamente utile. Tuttavia, mantenere segreti i dati raccolti è un requisito essenziale. Ecco che la cifratura completa del disco diventa un concetto di sicurezza obbligatorio.
Per prima cosa dobbiamo configurare un'immagine Kali ufficiale e attuale per Raspberry Pi (senza cifratura) su una scheda SD.
L'opzione consigliata (ora) è usare una build personalizzata per Raspberry Pi 3 con la patch nexmon (per usare le capacità di monitoraggio e injection del WiFi integrato). C'è uno script di build automatico nel repository ufficiale kali-arm-build-scripts che prepara l'immagine da zero (su una distro Kali). E qui c'è una versione patchata che funziona anche su distro diverse da Kali (testata su Gentoo). Attualmente (2017-08) lo script di build funzionante per ODROID-C2 è anche qui in quel repository forkato.
Ottieni gli strumenti di build e crea l'immagine da zero come root (può richiedere un paio d'ore):
$ git clone https://github.com/tothi/kali-arm-build-scripts
$ cd kali-arm-build-scripts
$ sudo ./rpi3-nexmon.sh 2.0
L'immagine risultante è rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz.
Copiala sulla scheda SD (usando pv per mostrare l'avanzamento):
# pixz -d rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz - | pv -treb | dd of=/dev/mmcblk0 bs=512k
(L'immagine dovrebbe funzionare, ora può essere testata.)
Montiamo l'immagine dalla scheda SD e prepariamo un initramfs
in grado di gestire LUKS in un ambiente chroot. Per far funzionare
il tutto, serve un binario x86 (host) qemu-arm-static
sul filesystem della scheda SD. Il suddetto script di build patchato rpi3-nexmon.sh
lo installa e lo lascia sull'immagine, quindi le cose dovrebbero funzionare.
(In caso contrario, è necessario copiare il binario qemu statico appropriato sull'immagine.)
Inizializzazione dell'ambiente chroot (sul sistema host come root):
# mkdir -p /mnt/chroot/boot
# mount /dev/mmcblk0p2 /mnt/chroot/
# mount /dev/mmcblk0p1 /mnt/chroot/boot/
# mount -t proc none /mnt/chroot/proc
# mount -t sysfs none /mnt/chroot/sys
# mount -o bind /dev /mnt/chroot/dev
# mount -o bind /dev/pts /mnt/chroot/dev/pts
# LANG=C chroot /mnt/chroot/
Innanzitutto cambiamo la password predefinita per root:
passwd
Installa i pacchetti richiesti (nell'ambiente chroot):
# apt-get update
# apt-get install busybox cryptsetup dropbear
Nota che dobbiamo inserire la chiave di decifratura a ogni avvio.
Lo facciamo preferibilmente in remoto tramite SSH,
ecco perché serve dropbear (nell'initramfs).
Ora modifica /boot/cmdline.txt, cambia il dispositivo root
con il dispositivo crypt mappato (/dev/mapper/crypt_sdcard)
e aggiungi il parametro cryptdevice appropriato.
Quindi ecco un /boot/cmdline.txt originale:
dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rootflags=noload net.ifnames=0
Ed ecco quello aggiornato (differenze nei parametri root e cryptdevice):
dwc_otg.fiq_fix_enable=2 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mapper/crypt_sdcard cryptdevice=/dev/mmcblk0p2:crypt_sdcard rootfstype=ext4 rootwait rootflags=noload net.ifnames=0
Ora crea /boot/config.txt con il seguente contenuto:
initramfs initramfs.gz followkernel
Nota che su altro hardware sono necessari passaggi simili
(il file che contiene i parametri di avvio su ODROID-C2 è
/boot/boot.ini).
Configuriamo l'autenticazione SSH con chiave per Dropbear. Crea una coppia di chiavi (senza password) sulla macchina host (fuori dalla chroot!) e leggi la chiave pubblica:
$ ssh-keygen -N "" -f kali-dropbear
$ cat ./kali-dropbear.pub
Aggiungi la chiave pubblica a /etc/dropbear-initramfs/authorized_keys.
Limita l'accesso SSH di Dropbear al solo setup di cryptroot
premettendo alla chiave questo:
command="/scripts/local-top/cryptroot && kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`"
Correggi i permessi:
chmod 600 /etc/dropbear-initramfs/authorized_keys
Modifica /etc/fstab. Originale:
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
Aggiornato: il dispositivo / è cambiato in /dev/mapper/crypt_sdcard:
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mapper/crypt_sdcard / ext4 defaults,noatime 0 1
Aggiungi questa riga a /etc/crypttab:
crypt_sdcard /dev/mmcblk0p2 none luks
Modifica /etc/cryptsetup-initramfs/conf-hook impostando
CRYPTSETUP=y
per includere i file di cryptsetup nell'immagine initramfs.
Infine, crea l'initramfs per la versione corrente del kernel ed esci dalla chroot (non preoccuparti di errori/avvisi durante mkinitramfs):
# ls -l /lib/modules/ |awk -F" " '{print $9}'
4.4.50-v7+
# mkinitramfs -o /boot/initramfs.gz 4.4.50-v7+
Nota che dobbiamo essere attenti quando generiamo l'immagine
(soprattutto su altro hardware), perché
uname -r restituisce la versione del kernel dell'host, non quella della chroot.
Quindi, ad esempio, su ODROID-C2 /boot/mkuinitrd non funziona
così com'è; dovremmo eseguire manualmente i comandi dello script
(adattando la versione del kernel PER ALTRO HARDWARE!):
# rm /boot/initrd.img-3.14.79
# update-initramfs -c -k 3.14.79
# mkimage -A arm64 -O linux -T ramdisk -C none -a 0 -e 0 -n "uInitrd" -d /boot/initrd.img-3.14.79 /boot/uInitrd
#
Esci dall'ambiente chroot
exit
Smonta i filesystem e fai un backup della rootfs prima di creare il volume cifrato (ed eliminare tutto) sulla scheda SD:
# umount /mnt/chroot/boot
# umount /mnt/chroot/sys
# umount /mnt/chroot/proc
# mkdir -p /mnt/backup
# rsync -avh /mnt/chroot/* /mnt/backup/
Smonta completamente la chroot:
# umount /mnt/chroot/dev/pts
# umount /mnt/chroot/dev
# umount /mnt/chroot
Elimina la partizione root non cifrata (num. 2) e creane una vuota (occupando l'intera scheda SD):
# echo -e "d\n2\nw" | fdisk /dev/mmcblk0
# echo -e "n\np\n2\n\n\nw" | fdisk /dev/mmcblk0
Ora (probabilmente) è necessario scollegare e reinserire la scheda SD per registrare le nuove partizioni.
Crea un volume cifrato con una passphrase robusta (questo passaggio distrugge la rootfs originale!):
# cryptsetup -v -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/mmcblk0p2
# cryptsetup -v luksOpen /dev/mmcblk0p2 crypt_sdcard
# mkfs.ext4 /dev/mapper/crypt_sdcard
Ripristina la rootfs sul volume cifrato e chiudi il disco:
# mkdir -p /mnt/encrypted
# mount /dev/mapper/crypt_sdcard /mnt/encrypted/
# rsync -avh /mnt/backup/* /mnt/encrypted/
# umount /mnt/encrypted/
# cryptsetup luksClose /dev/mapper/crypt_sdcard
# sync
Espelli la scheda SD e testala sul Raspberry.
Il primo avvio fallirà e cadrà in busybox. Immetti i seguenti comandi:
# cryptsetup luksOpen /dev/mmcblk0p2 crypt_sdcard
## inserire la password
# exit
Il dispositivo dovrebbe ora avviarsi. Accedi con la password scelta in precedenza ed esegui:
mkinitramfs -o /boot/initramfs.gz
reboot
Ti verrà ora chiesta la passphrase con un prompt più gradevole; inoltre dovresti poter fare ssh verso busybox e inserire la passphrase
(puoi usare un file known_hosts personalizzato se lo desideri):
$ ssh -o "UserKnownHostsFile=~/.ssh/known_hosts.initramfs" -i ~/.ssh/kali-dropbear [email protected]
Una volta che funziona, non dimenticare di pulire i file di backup sull'host:
# rm -fr /mnt/backup
# rm -fr /mnt/chroot
Per ottenere un debug completo durante l'avvio puoi aggiungere debug=1 in cmdline.txt.