Passwörter sind ein gescheitertes Konzept. Nur leider haben wir immer noch kein Besseres für den flächendeckenden Einsatz. Die sogenannte Zwei-Faktor-Authentifizierung via SMS oder TOTP soll hier mehr Sicherheit bringen. Eine weitere Möglichkeit ist ein Security Key wie der YubiKey. Damit lassen sich auch verschlüsselte Volumes sichern.
Das eigentlich gute Berechtigungskonzept von Linux hat in den letzten Jahren gelitten. Komfort fordert seinen Preis. Viele Distributionen verzichten auf einen dezidierten root-Zugang und andere wie z.B. openSUSE empfehlen dem Nutzer, das root-Kennwort identisch mit dem des primäres Benutzers zu setzen. Viele nehmen dann gleich noch aus Bequemlichkeit dieses Kennwort für die LUKS Systemverschlüsselung.
Wenn wir mal ganz ehrlich sind, dann nutzen wir zudem doch eher triviale Kennwörter. Ein wirklich sicheres Kennwort mit ~30 Zeichen inklusive Groß-/Kleinschreibung, Zahlen und Sonderzeichen ohne erkennbares System – wer möchte das schon bei jedem Systemstart und jeder Administratorrechte-Abfrage eingeben. Die meisten Anwender machen hier also ein paar Abstriche und nehmen das, was sie für gerade noch vertretbar halten. Aus diesem Dilemma kann einen YubiKey befreien.
YubiKey für LUKS Volumes
Die Änderung der Authentifizierung für das System kann im schlimmsten Fall zur Aussperrung aus dem System und zu Datenverlust führen. Bitte daher ein aktuelles Backup anlegen und ggf. einen Rettungsstick vorbereitet haben.
Vorbemerkungen
Aller Nivellierung zum trotz gibt es zwischen den Distributionen noch immer erhebliche Unterschiede in der Art, wie sie Verschlüsselung konkret beim Systemstart einbinden. Es gibt deshalb nicht die eine Softwarelösung, die mit Anpassungen auf allen Distributionen läuft. Vielleicht ändert sich das mit den neuen Funktionen für systemd, die Lennart Poettering vor Kurzem bekannt gab. Allerdings bleibt abzuwarten, welche Distributionen dies kurz- oder mittelfristig wirklich nutzen.
Zum aktuellen Zeitpunkt gibt es funktionierende Implementierungen für Debian (und damit auch für alle Derivate inklusive Ubuntu) und Arch Linux. Die Debian-Lösung ist dabei von der Arch-Lösung inspiriert. Für openSUSE, Fedora, Red Hat & Co konnte ich zum aktuellen Zeitpunkt keine Lösungen ermitteln.
Ich persönlich fand die Debian-Lösung schlecht dokumentiert und konnte sie nicht erfolgreich umsetzen. Deshalb möchte ich das hier am Beispiel von Arch Linux demonstrieren, weil das hier verhältnismäßig einfach einzurichten ist und die Dokumentation wirklich gut ist.
Voraussetzung für die Einrichtung ist eine existierende Vollverschlüsselung mittels LUKS.
Installation & Konfiguration
YubiKey vorbereiten
Zur Einrichtung benötigt man das YubiKey-Personalisierungstool und das Paket yubikey-full-disk-encryption (im folgenden abgekürzt als ykfde)
# pacman -S yubikey-personalization <code> yubikey-full-disk-encryption</code>
Code-Sprache: HTML, XML (xml)
Anschließend bereitet man den YubiKey entsprechend vor. Normalerweise nutzt man Slot 2, weil Slot 1 für die OTP-Challenge genutzt wird. Sollte das bei euch anders sein, könnt ihr das auch anpassen.
$ <code>ykpersonalize -v -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible -ochal-btn-trig</code>
Code-Sprache: HTML, XML (xml)
ykfde konfigurieren
Die Einrichtung ist dann eigentlich sehr einfach. Die zentrale Konfigurationsdatei ist /etc/ykfde.conf. Hier gibt es eine hervorragende Inline-Dokumentation.
ykfde unterstützt zwei Modi für die Authentifizierung (genaueres über das Verfahren beim Entwickler nachzulesen):
- Automatische Anmeldung mit gespeicherter Challenge: Ihr hinterlegt in der Konfigurationsdatei ein Passwort. Die Entsperrung erfolgt über die Antwort des YubiKey auf diese gespeicherte Challenge und den Secret Key des Tokens.
- Manueller Modus mit geheimer Challenge: Ihr müsst jedes Mal das Kenntwort eingeben (deshalb geheim) und zusätzlich wird der Secret Key des Tokens benötigt.
Die erste Lösung ist bequem, bedeutet aber, dass jeder im Besitz des YubiKeys befindliche Mensch das System entsperren kann. Die zweite Lösung ist dafür extrem sicher. Es entsteht ein extrem langer Key, der sich nicht mit einem Brute Force Angriff knacken lässt, weil er Wissen und Besitz kombiniert.
Grundsätzlich empfehle ich die zweite Methode, aber es kann durchaus Anwendungsfälle geben, in denen die erste Methode ausreicht oder sogar sinnvoll ist. Deshalb ist es schön, dass beide Möglichkeiten existieren.
In der ykfde.conf Datei müssen je nachdem welche Variante man nutzen will, eine der beiden entsprechenden Zeilen aktiviert werden, indem man die Auskommentierung mittels # entfernt und ggf. die notwendigen Informationen hinterlegt. Solltet ihr oben nicht Slot 2 gewählt haben, könnt ihr hier auch einen anderen Slot einstellen.
### *REQUIRED* ###
# Set to non-empty value to use 'Automatic mode with stored challenge (1FA)'.
#YKFDE_CHALLENGE=""
# Use 'Manual mode with secret challenge (2FA)'.
#YKFDE_CHALLENGE_PASSWORD_NEEDED="1"
# YubiKey slot configured for 'HMAC-SHA1 Challenge-Response' mode.
# Possible values are "1" or "2". Defaults to "2".
#YKFDE_CHALLENGE_SLOT="2"
Code-Sprache: PHP (php)
Bei dieser Konfiguration gehe ich davon aus, dass ihr euer LUKS Device mittels cryptdevice=UUID Bootparameter einbindet. Leicht nachzuprüfen in der GRUB oder systemd-boot Konfiguration. Solltet ihr das nicht machen, müsst ihr ggf. weitere Anpassungen vornehmen. Das konnte ich aber nicht austesten.
Exkurs: LUKS Keyslots
Bevor wir weitermachen, ist ein kleiner Exkurs zu LUKS Keyslots notwendig. LUKS Volumes können bis zu 8 unterschiedliche Kennwörter zur Entsperrung vorhalten. Normalerweise sollte man mindestens das primäre Kennwort (meist Slot 0) und einen Wiederherstellungsschlüssel konfigurieren. Wie es dem jeweiligen Volume aussieht kann man mit folgendem Befehl prüfen:
# cryptsetup luksDump /dev/nvme0n1p3
Code-Sprache: PHP (php)
Im vorliegenden Beispiel sieht das dann wie folgt aus:
LUKS header information for /dev/nvme0n1p3
Version: 1
Cipher name: aes
Cipher mode: xts-plain64
Hash spec: sha256
Payload offset: 4096
MK bits: 512
MK digest: 87 51 d5 12 69 a7 4e 5d 6a 56 b3 f6 5e 6b 5d ef 21 81 d6 ce
MK salt: b9 9f 9e bf 34 da ba 5f 33 10 f5 e3 c2 7b 1f 33
9e f4 6d 1c e6 cd bc 8b 48 ad 34 56 98 79 cd ce
MK iterations: 126517
UUID: 3c4624a7-2e5b-4aa3-a7b8-76e4d8dc0aa8
Key Slot 0: ENABLED
Iterations: 2024276
Salt: 22 5c b6 24 c5 47 e2 71 23 dd 57 3a d3 4a 58 9a
94 28 f9 be 41 b7 5d 28 b1 5c e2 bf 84 4a 39 a6
Key material offset: 8
AF stripes: 4000
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: ENABLED
Iterations: 2312184
Salt: da 50 7a a7 76 96 3b 50 35 be aa dd e8 29 a8 ff
f6 6f a5 c2 67 31 22 c7 ba a2 09 61 1f 3b 1a 23
Key material offset: 3536
AF stripes: 4000
Man sieht den primären Schlüssel in Slot 0, der bei der Installation des Systems angelegt wurde und den Wiederherstellungsschlüssel in Slot 7. Alle anderen Slots stehen noch zur Verfügung. Hier können wir nun einen mit der YubiKey-Lösung belegen.
YubiKey in LUKS hinterlegen
Nun rollt man den Schlüssel aus. Die entsprechende Partitionsnummer ist ebenso anzupassen wie der gewünschte Slot.
<code># ykfde-enroll -d /dev/<LUKS-Device> -s <Keyslot-Nummer></code>
Code-Sprache: HTML, XML (xml)
Dabei wird ein bereits existierendes Kennwort abgefragt. Dies kann entweder das bisherige Primärkennwort oder irgendein anderes wie z.B. der Wiederherstellungsschlüssel sein.
Danach kann man mit dem luksDump Befehl prüfen ob das erfolgreich geschehen ist.
ykfde in den Arch Bootprozess einbinden
ykfde ist eigentlich „nur“ ein angepasster encrypt hook. Dadurch ist die Integration in den Bootprozess denkbar simpel und auch überhaupt nicht fehleranfällig. Erst wenn Arch hier Grundlegendes was ändert, kommen wir damit in die Bredouille. In der Konfigurationsdatei /etc/mkinitcpio.conf
hinterlegt man den ykfde hook. Die Zeile sollte dann erst mal wie folgt aussehen (Abweichungen je nach System natürlich möglich):
HOOKS=(base udev autodetect modconf block consolefont keymap keyboard ykfde encrypt filesystems)
Eigentlich braucht man nicht ykfde und encrypt. Aber wenn bei den bisherigen Schritten irgendwas schief gegangen ist, hat man mit dem normalen encrypt hook erst mal noch ein Sicherungsnetz.
Danach noch mkinitcpio aktualisieren:
# mkinitcpio -p linux
Code-Sprache: PHP (php)
Danach kommt ein Neustart und der Moment der Wahrheit. Nach dem Start sollte nun eine veränderte Abfrage kommen. Ihr habt 30 Sekunden (lässt sich aber auch anpassen) Zeit. den YubiKey einzustecken und ggf. eure Passphrase einzugeben. Je nachdem für welche Variante ihr auch oben entschieden habt. Nach Ablauf der Zeit kann man das LUKS Volume auch mit einem der anderen hinterlegten Keys entsperren.
Hat alles geklappt könnt ihr den encrypt hook aus der mkinitcpio.conf entfernen.
Genau die Möglichkeit, nach 30 Sekunden einen anderen Key einzugeben, ist Fluch und Segen zugleich. Einerseits ist das eine essenzielle Möglichkeit das System bei Verlust, kurzfristiger Nicht-Verfügbarkeit oder Beschädigung des Keys zu entsperren. Andererseits besteht diese Möglichkeit halt immer. Das System ist daher nur so sicher wie eure übrigen Passphrasen. Ich empfehle deshalb nur den sogenannten Wiederherstellungsschlüssel zusätzlich zu Hinterlegen und andere ggf. vorhandene einfachere Passwörter zu entfernen.
Der YubiKey muss im laufenden Betrieb nicht permanent eingesteckt sein. Nach einem normalen Standby ist er ebenfalls nicht notwendig. Für Suspend lässt sich der YubiKey laut Entwicklerseite konfigurieren, aber diesen Modus nutze ich nicht und habe es deshalb nicht getestet.
Dies bedeutet im Klartext: Der YubiKey schützt als Sicherungsmethode das System nur im ausgeschalteten Zustand. Exzessive Nutzer des Standby-Modus hängen von den Sicherungsmechanismen ihrer Desktopumgebung ab (und die sind teilweise schlecht). Also lieber ab und an das System mal komplett herunterfahren, wenn ihr es einen längeren Zeitraum nicht benötigt.
Ebenso sollte man den YubiKey natürlich nicht neben dem Gerät liegen lassen.
Die deaktivierten Keyslots sind scheinbar nur mit LUKS1 sichtbar. Hat mich ein bisschen verwirrt.
Das hat sich tatsächlich geändert. Der Artikel ist halt noch von Anfang 2021.
Danke für den hilfreichen Guide, lieber Gerrit!