
Vollständige Festplattenverschlüsselung für Kali auf Raspberry mit LUKS
Diese Anleitung widmet sich dem Betrieb von Kali auf Raspberry (oder ähnlicher Architektur, z. B. ODROID-C2) unter Verwendung vollständiger Festplattenverschlüsselung mit LUKS. Basiert auf dem leicht veralteten Dokument hier.
Das Bereitstellen von Kali auf Raspberry Pi (oder ähnlicher, kleiner, stromsparender Hardware) in einer LAN-Umgebung als „Wegwerf-Hackbox“ ist offensichtlich nützlich. Jedoch ist die Geheimhaltung der gesammelten Daten eine wesentliche Anforderung. Hier kommt die vollständige Festplattenverschlüsselung als zwingendes Sicherheitskonzept ins Spiel.
Zunächst sollten wir ein offizielles aktuelles Kali-Image für den Raspberry Pi (ohne Verschlüsselung) auf einer SD-Karte einrichten.
Die empfohlene Option (jetzt) ist die Verwendung eines benutzerdefinierten Raspberry Pi 3 Builds mit dem nexmon-Patch (zur Nutzung der integrierten WLAN-Überwachungs- und Injectionsfähigkeiten). Es gibt ein automatisiertes Build-Skript im offiziellen Repository kali-arm-build-scripts, das das Image von Grund auf erstellt (auf einer Kali-Distribution). Und hier ist eine angepasste Version, die auch auf anderen Distributionen als Kali funktioniert (getestet auf Gentoo). Derzeit (2017-08) befindet sich auch ein funktionierendes Build-Skript für ODROID-C2 in diesem Fork.
Besorge die Build-Tools und erstelle das Image von Grund auf als root (kann einige Stunden dauern):
$ git clone https://github.com/tothi/kali-arm-build-scripts
$ cd kali-arm-build-scripts
$ sudo ./rpi3-nexmon.sh 2.0
Das resultierende Image ist rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz. Kopiere es auf die SD-Karte (mit pv zur Fortschrittsanzeige):
# pixz -d rpi3-nexmon-2.0/kali-2.0-rpi3-nexmon.img.xz - | pv -treb | dd of=/dev/mmcblk0 bs=512k
(Das Image sollte funktionieren, es kann jetzt getestet werden.)
Wir mounten das Image von der SD-Karte und bereiten ein initramfs vor, das LUKS-Funktionen in einer chroot-Umgebung unterstützt. Damit dies funktioniert, wird ein x86 (Host) qemu-arm-static-Binary auf dem SD-Karten-Dateisystem benötigt. Das oben genannte angepasste Build-Skript rpi3-nexmon.sh installiert und belässt es auf dem Image, sodass alles gut funktionieren sollte. (Andernfalls ist das Kopieren des entsprechenden qemu statischen Binärs auf das Image erforderlich.)
Initialisieren der chroot-Umgebung (auf dem Host-System als 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/
Zuerst ändern wir das Standard- Passwort für root:
passwd
Installiere erforderliche Pakete (in der chroot-Umgebung):
# apt-get update
# apt-get install busybox cryptsetup dropbear
Beachte, dass wir den Entschlüsselungsschlüssel bei jedem Booten eingeben müssen. Wir erledigen dies vorzugsweise remote über SSH, weshalb dropbear (im initramfs) benötigt wird.
Bearbeite jetzt /boot/cmdline.txt, ändere das root-Gerät auf das gemappte crypt-Gerät (/dev/mapper/crypt_sdcard) und füge den entsprechenden cryptdevice-Parameter hinzu.
Hier ist eine original /boot/cmdline.txt:
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
Und hier die aktualisierte (Unterschiede bei den Parametern root und 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
Erstelle nun /boot/config.txt mit folgendem Inhalt:
initramfs initramfs.gz followkernel
Beachte, dass auf anderer Hardware ähnliche Schritte erforderlich sind (die Datei mit den Boot-Parametern auf ODROID-C2 ist /boot/boot.ini).
Richten wir die Dropbear SSH-Key-Authentifizierung ein. Erstelle ein (passwortloses) Schlüsselpaar auf dem Host-Rechner (außerhalb der chroot!) und lies den öffentlichen Schlüssel aus:
$ ssh-keygen -N "" -f kali-dropbear
$ cat ./kali-dropbear.pub
Füge den öffentlichen Schlüssel zu /etc/dropbear-initramfs/authorized_keys hinzu. Beschränke den Dropbear SSH-Zugriff für das Einrichten von cryptroot nur, indem du dem Schlüssel folgendes voranstellst:
command="/scripts/local-top/cryptroot && kill -9 `ps | grep -m 1 'cryptroot' | cut -d ' ' -f 3`"
Setze die Berechtigungen:
chmod 600 /etc/dropbear-initramfs/authorized_keys
Bearbeite /etc/fstab. Original:
# <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
Aktualisiertes /-Gerät geändert zu /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
Füge diese Zeile zu /etc/crypttab hinzu:
crypt_sdcard /dev/mmcblk0p2 none luks
Ändere /etc/cryptsetup-initramfs/conf-hook indem du
CRYPTSETUP=y
setzt, um cryptsetup-Dateien in das initramfs-Image aufzunehmen.
Erstelle schließlich initramfs für die aktuelle Kernel-Version und verlasse die chroot (mache dir keine Sorgen über Fehler/Warnungen während mkinitramfs):
# ls -l /lib/modules/ |awk -F" " '{print $9}'
4.4.50-v7+
# mkinitramfs -o /boot/initramfs.gz 4.4.50-v7+
Beachte, dass wir beim Erstellen des Images (insbesondere auf anderer Hardware) vorsichtig sein müssen, weil
uname -r die Host-Kernel-Version zurückgibt, nicht die der chroot.
So funktioniert z.B. auf ODROID-C2 /boot/mkuinitrd nicht out of the box, wir sollten die Befehle im Skript manuell ausführen (die Kernel-Version FÜR ANDERE HARDWARE anpassen!):
# 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
#
Verlasse die chroot-Umgebung
exit
Hänge die Dateisysteme aus und erstelle ein Backup des rootfs, bevor du das verschlüsselte Volume erstellst (und alles auf der SD-Karte löschst):
# umount /mnt/chroot/boot
# umount /mnt/chroot/sys
# umount /mnt/chroot/proc
# mkdir -p /mnt/backup
# rsync -avh /mnt/chroot/* /mnt/backup/
Hänge die gesamte chroot aus:
# umount /mnt/chroot/dev/pts
# umount /mnt/chroot/dev
# umount /mnt/chroot
Lösche die unverschlüsselte Root-Partition (Nr. 2) und erstelle eine leere (die SD-Karte ausfüllend):
# echo -e "d\n2\nw" | fdisk /dev/mmcblk0
# echo -e "n\np\n2\n\n\nw" | fdisk /dev/mmcblk0
Jetzt ist (wahrscheinlich) das Abziehen und Wiedereinstecken der SD-Karte erforderlich, um die neuen Partitionen zu registrieren.
Erstelle ein verschlüsseltes Volume mit einer starken Passphrase (dieser Schritt zerstört das ursprüngliche rootfs!):
# 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
Stelle das rootfs auf dem verschlüsselten Volume wieder her und schließe die Platte:
# 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
Entferne die SD-Karte und teste sie auf dem Raspberry.
Der erste Bootvorgang wird fehlschlagen und in busybox zurückfallen. Gib die folgenden Befehle ein:
# cryptsetup luksOpen /dev/mmcblk0p2 crypt_sdcard
## Passwort eingeben
# exit
Dein Gerät sollte jetzt booten. Melde dich mit dem zuvor gewählten Passwort an und führe aus:
mkinitramfs -o /boot/initramfs.gz
reboot
Du wirst nun mit einer schöneren Eingabeaufforderung nach der Passphrase gefragt, außerdem solltest du dich per SSH mit der busybox verbinden und die Passphrase eingeben können (du kannst bei Bedarf eine benutzerdefinierte known_hosts-Datei verwenden):
$ ssh -o "UserKnownHostsFile=~/.ssh/known_hosts.initramfs" -i ~/.ssh/kali-dropbear [email protected]
Sobald es funktioniert, vergiss nicht, die Backup-Dateien auf dem Host zu bereinigen:
# rm -fr /mnt/backup
# rm -fr /mnt/chroot
Um während des Bootens vollständige Debug-Ausgaben zu erhalten, kannst du debug=1 in cmdline.txt hinzufügen.