Odroid U3 mit verschüsseltem rootfs und entsperren über SSH
Einleitung
Als Basis verwende ich das ubuntu image 14.04.2 von Hardkernel. Nachdem das Image auf die SD Karte kopiert wurde starten wir es ein erstes mal.
Um dies nach zubauen braucht es eine genügend große SD oder EMMC Karte (min 16GB). Ansonsten ist nicht genug Platz um zwei rootfs nebeneinander zu haben. Man kann das umgehen indem man das chroot, wie unten beschrieben nicht ausführt und die Veränderungen am rootfs direkt vornimmt. Dann die Karte an einen Linux Rechner mounted, das rootfs auf Festplatte zwischenspeichert, die Partition Verschlüsselt und wieder einhängt und das rootfs zurück kopiert. Dies müsste so funktionieren, habe ich aber nicht getestet.
Achtung Kontrolliert bitte zweimal was ihr eingebt. Wenn ihr euch vertippt müsst ihr im schlimmsten Fall nochmal von vorne anfangen.
Vorbereitungen
Als erstes installieren wir noch benötigte Pakete:
sudo apt-get install cryptsetup rsync dropbear
Nun vergrößern wir die root Partition, da sonnst nicht genug platz zur Verfügung steht. Ich benutze ein 32GB SDKarte. Die neue root Partition ist am Ende der Karte. Also habe ich die aktuelle root Partition soweit erweitert das am Ende der Karte noch eine 10GB Partition übrig bleibt, das wird dann die verschlüsselte root Partition die alte root Partition wird dann die neu home Partition.
Nun führen wir das ODROID Utility aus und gehen in den Menüpunkt zwei.
Dort führen wir alle punkte nach der Reihe aus.
Als letztes lassen wir den Updater durchlaufen um das System auf den neusten stand zu bringen.
Verschlüsseln der Root Partition
Prüfen der Voreinstellungen von cryptsetup mittels:cryptsetup --help
hier schauen wir auf die Einstellungen von luks. Bei mir waren sie:
- LUKS1: aes-xts-plain64, Schlüssel: 256 Bits, LUKS-Kopfbereich-Hashen: sha1, Zufallszahlengenerator: /dev/urandom
Darum habe ich im folgenden Befehl -s 512 und -h sha256 gesetzt. Das verdoppelt die Schlüsselgröße, und benutzt sha256 anstelle sha1. Wenn ihr nicht aes-xts-plain64
als Cypher habt dann setzt dies bitte im folgenden Befehl mittels -c aes-xts-plain64
. Nun folgenden Befehl ausführen, zum erstellen der Verschlüsselten Partition.
sudo cryptsetup -y -s 512 -h sha256 luksFormat /dev/mmcblk0p3
Mit diesen Befehl öffnen wir die Verschlüsselte Partition. Das Passwort für die Partition wird abgefragt.
sudo cryptsetup luksOpen /dev/mmcblk0p3 cryptroot
Nun erstellen wir ein EXT4 Dateisystem auf der verschlüsselten Partition.
sudo mkfs.ext4 /dev/mapper/cryptroot
Nach dem Erstellen hängen wir die Partition unter /mnt ein.
sudo mount /dev/mapper/cryptroot /mnt
Zum Abschluss kopieren wir alle Daten von / nach /mnt.
sudo rsync -av --exclude=/media --exclude=/mnt --exclude=/proc --exclude=/dev --exclude=/sys / /mnt
Nachdem alle Dateien auf die neue Partition kopiert wurden machen wir ein chroot in das neue root verzeichniss. Dazu erstellen wir als erstes die folgend Verzeichnisse.
sudo mkdir -p /mnt/dev
sudo mkdir -p /mnt/mnt
sudo mkdir -p /mnt/proc
sudo mkdir -p /mnt/sys
sudo mkdir -p /mnt/media
Danach binden wir die Verzeichnisse ein um das chroot auszuführen.
sudo mount -o rbind /dev /mnt/dev
sudo mount -t proc proc /mnt/proc
sudo mount -t sysfs sys /mnt/sys
sudo mount -t vfat /dev/mmcblk0p1 /mnt/media
Zum Schluss nun noch:
sudo chroot /mnt
Initrd scripte neu erstellen
In der Konsole befinden wir uns jetzt in dem neuen root System. Dort müssen wir noch einige Anpassungen vornehmen.
Als ersten brauchen wir die UUID der Verschlüsselten Partition die lassen wir uns mit cryptsetup luksUUID /dev/mmcblk0p3
anzeigen. Schreibt sie euch auf oder kopiert sie in die Zwischenablage.
Nun müssen wir die crypttab anpassen. Öffnet die Datei im editorsudo nano /etc/crypttab
. Dort fügt ihr folgende Zeile ein:
cryptroot UUID=<uuid die ihr ermittelt habt> none luks
Jetzt müssen wir die fstab anpassen. sudo nano /etc/fstab
. Dort ändert ihr folgen Zeile ab:
UUID=<Irgend eine UUID> / ext4 ....
Dort ersetzt ihr die UUID mit dem Pfad zur verschlüsselten Partition. Die Zeile sollte dann folgendermaßen aussehen:
/dev/mapper/cryptroot / ext4 ....
In der Datei /etc/initramfs-tools/modules tragen wir folgendes ein:
aes-arm
xts
sha256-generic
dm-crypt
dm-mod
smsc95xx
Wir erstellen nun ein neues Bootimage mit:
update-initramfs -u -k $(uname -r)
Nun müssen wir noch das Bootimage erzeugen das in die fat32 Bootpartion unsere sdkarte kommt. Dies machen wir mit:
mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n "uInitrd $(uname -r)" -d /boot/initrd.img-$(uname -r) /tmp/uInitrd-$(uname -r)
Nun kopieren wir das Image auf die Karte in die richtige Partition:
cp /tmp/uInitrd-$(uname -r) /boot
cp /tmp/uInitrd-$(uname -r) /media/uInitrd
Zuletzt müssen wir das Bootscript anpassen. Dazu editieren wir die boot.txt unter /media:
setenv bootargs "root=/dev/mapper/cryptroot cryptdevice=/dev/mmcblk0p3:cryptroot ...
Alles andere in der Zeile nicht verändern nur der Pfad hinter "root=" ändern und das cryptdevice in die Zeile setzen. Jetzt noch das boot.scr erstellen lassen mit:
mkimage -A arm -T script -O linux -d /media/boot.txt /tmp/boot.scr
Und die boot.scr auf die Partition kopieren:
cp /tmp/boot.scr /media/
Nun starten wir den U3 neu. Beim Start wird nun das Passwort abgefragt.
Alte root Partion als home verwenden
Nach dem Neustart, haben wir die verschlüsselte Partition als root. Die unverschlüsselte Partition soll ja nicht ungenutzt bleiben. Darum verschlüsseln wir sie ebenfalls und hängen sie als home Partition ein. Da wir beim booten nicht zwei Passwörter eingeben wollen lassen wir die Partition automatisch einhängen mit der root Partition.
Partition verschlüsseln mit Ableitung der root Partition:
sudo /lib/cryptsetup/scripts/decrypt_derived cryptroot | sudo cryptsetup -c aes-xts-plain64 -s 512 -h sha256 luksFormat /dev/mmcblk0p2
Wenn die root Partition mal beschädigt würde könnte die home Partition auch nicht mehr geöffnet werden. Darum fügen wir der home Partition noch ein Passwort hinzu:
sudo /lib/cryptsetup/scripts/decrypt_derived cryptroot
Die Ausgabe diese Befehls speichern wir in die Zwischenablage. Nun fügen wir ein Passwort zur home Partition hinzu:
sudo cryptsetup luksAddKey /dev/mmcblk0p2
Das erste Passwort was abgefragt wird fügen wir aus der Zwischenablage ein. Dann geben wir ein neues Passwort ein, was der Partition hinzugefügt wird. Wir erstellen ein ext4 Dateisystem und hängen die Partition nach /mnt ein und kopieren den Inhalt von /home dort hinein:
sudo /lib/cryptsetup/scripts/decrypt_derived cryptroot | sudo cryptsetup luksOpen /dev/mmcblk0p2 crypthome
sudo mkfs.ext4 /dev/mapper/crypthome
sudo mount /dev/mapper/crypthome /mnt
sudo rsync -av /home /mnt
Nachdem wir die gemacht haben, müssen wir noch die /etc/crypttab anpassen um die Partiton beim Booten als /home einzuhängen. Dazu fügen wir folgende Zeile in die crypttab ein:
crypthome UUID=<UUID> cryptroot luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived
Die UUID kann mit folgendem Befehl ermittelt werden:
cryptsetup luksUUID /dev/mmcblk0p2
Nun muss noch eine Zeile in die fstab eingefügt werden:
/dev/mapper/crypthome /home ext4 errors=remount-ro,noatime,nodiratime 0 0
Dropbear SSH server für Headless Entschlüsselung
Damit können wir den U3 entweder mit Tastatur oder per SSH über Fernzugriff entsperren. Das ist praktisch wenn man den U3 mal als Desktop oder mal als Server verwendet.
Um dies zu realisieren müssen wir den Dropbear SSH Server konfigurieren und die Netzwerkkarte für das Initrd.
Als erstes brauchen wir einen SSH Schlüssel mit dem wir uns am U3 anmelden können. Den erstellen wir als der Benutzer den wir auch im laufenden betrieb benutzen.
ssh-keygen -b 4096
Im Homeverzeichnis des Benutzers liegen nun im Ordner ".ssh" die Dateien "id_rsa" und "id_rsa.pub". Die "id_rsa" Datei kopieren wir auf einen USB-Stick, da wir diese nachher auf dem Rechner brauchen mit dem wir uns anmelden wollen.
Die "id_rsa.pub" fügen wir zu den authorize_keys hinzu:
sudo cat id_rsa.pub >> authorized_keys
sudo cat id_rsa.pub >> /etc/initramfs-tools/root/.ssh/autorized_keys
Nun ist der Schlüssel sowohl für den Dropbear als auch für den OpenSSH Server gültig.
Achtung der OpenSSH Server muss natürlich noch ordentlich konfiguriert werden.
Nun passen wir die Datei /etc/initramfs-tools/initramfs.conf
an. Dort änder wir folgendes:
MODULES=most
BUSYBOX=y
DEVICE=eth0
IP=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>
DROPBEAR=y
Die Zeile mit IP kann wie folgt aussehen:
IP=192.168.0.10::192.168.0.1:255.255.255.0::eth0:off
IP=::::::eth0:dhcp
Die erste Spalte zeigt eine Konfiguration mit einer festen IP, in der zweiten ist die Konfiguration mit DHCP zu sehen. Wichtig ist nur das ihr die Doppelpunkte macht.
Die Konfigurtion bezieht sich auf die Netzwerkbuchse nicht auf Wlan. Auf diese Art kann man ein Wlan nicht konfigurieren. Dazu müsste man das WPA-Suplikant mit scripten in das initramfs bekommen. Ich habe dazu zwar Anleitungen in Google gefunden, habe mich damit aber nicht weiter beschäftigt.
Nun müssen wir noch ein Script im Verzeichnis /etc/initramfs-tools/hooks
erstellen um einen Bug im Plymouth von Ubuntu zu umgehen der seit Version 10.04 nicht behoben ist (Sowas ist echt Nervig!!!)
Dazu erstellen wir die Datei "unlock" im oben genanten Verzeichnis und kopieren folgenden Inhalt dort herein:
#!/bin/sh
PREREQ="dropbear"
prereqs() {
echo "$PREREQ"
}
case "$1" in
prereqs)
prereqs
exit 0
;;
esac
. "${CONFDIR}/initramfs.conf"
. /usr/share/initramfs-tools/hook-functions
copy_exec /usr/bin/pkill /sbin
if [ "${DROPBEAR}" != "n" ] && [ -r "/etc/crypttab" ] ; then
cat > "${DESTDIR}/bin/unlock" <<-EOF
#!/bin/sh
if PATH=/lib/unlock:/bin:/sbin /scripts/local-top/cryptroot
then
/sbin/pkill cryptroot
/sbin/pkill -f "plymouth ask-for-pass"
/sbin/pkill cryptsetup
exit 0
fi
exit 1
EOF
chmod 755 "${DESTDIR}/bin/unlock"
mkdir -p "${DESTDIR}/lib/unlock"
cat > "${DESTDIR}/lib/unlock/plymouth" <<-EOF
#!/bin/sh
[ "\$1" == "--ping" ] && exit 1
/bin/plymouth "\$@"
EOF
chmod 755 "${DESTDIR}/lib/unlock/plymouth"
# Enable password login
if [ -n "$SSHUSERPASS" ]
then
sed -n "s/^${SSHUSERPASS}:/root:/p" /etc/shadow > "${DESTDIR}/etc/shadow"
chmod 640 "${DESTDIR}/etc/shadow"
fi
fi
So damit sollte es uns jetzt möglich sein den U3 per SSH zu entsperren. Um die Einstellungen wirksam zu machen müssen wir das initramfs updaten und ein neues uImage erstellen und auf die BOOT Partition kopieren. Dies machen wir folgendermaßen:
sudo update-initramfs -u -k $(uname -r)
sudo mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n "uInitrd $(uname -r)" -d /boot/initrd.img-$(uname -r) /tmp/uInitrd-$(uname -r)
sudo cp /tmp/uInitrd-$(uname -r) /boot
sudo cp /tmp/uInitrd-$(uname -r) /media/boot/uInitrd
Achtung die BOOT Partiton muss unter /media eingehängt sein. Bei mir wurde sie das immer automatisch.
Sop nun sollte alles funktionieren. Beim Neustart des U3 sollte die Netzwerkarte konfiguriert sein und der Dropbear sollte laufen. Die Netzwerkleitung muss vor dem Start eingesteckt sein.
Ihr könnt euch nun mit folgendem befehl per SSH anmelden:
ssh -i "Pfad zur id_rsa Datei" -l root "Adresse des U3"
Nach dem Anmelden seit ihr in der BUSYBOX des U3 dort gebt ihr unlock
ein, und werdet nach dem Paswort gefragt. Nach der Eingabe selbiges booted der U3 normal hoch. Ihr könnt euch wieder abmelden, da der DROPBEAR nach dem Booten gestopt wird und der OpenSSH Server gestarted wird. An dem könnt ihr euch wieder mit SSH Anmelden nur diesmal mit dem Benutzer unter dem ihr den SSH Schlüssel erzeugt habt.
Hinweis der Dropbear und der OpenSSH Server haben unterschiedliche Fingeprints. darum wäre es ratsem eine andere KnownHosts Datei zu verwenden. Dies könnt ihr machen indem ihr in den ssh Befehl folgendes mit hereinsetzt:
-UserKnownHostsFile "pfad zum hostfile"
Unter Windwos verwende ich cygwin mit instaliertem OpenSSH als SSH client. Dort könnt ihr euch eine config Datei anlegen um euch die Sache zu vereinfachen. Dazu werde ich in kürze noch einen Artikel verfassen.
Nun erstmal viel Spaß am Gerät :-)