Linux Festplatten Verschlüsselung mit LUKS

Aus Laub-Home Wiki

Möchte man unter Linux eine Festplatte, oder einen Datei Container verschlüsseln, so kommt man um LUKS (Linux Unified Key Setup) nicht herum. Um dieses nutzen zu können kommt das Packet cryptsetup zum Einsatz.

Verschlüsselungs Arten

Es gibt drei verschiedene Arten um eine Festplatte zu verschlüsseln. Zusätzlich ist es auch möglich einen Datei Container, den ihr vorher mit dd angelegt habt zu verschlüsseln und diesen zu mounten.

normale Partitionen:

  • Vorteil: Keine weitere Komplexität durch LVM
  • Nachteil weniger flexibel gegenüber Änderungen als LVM
Partition 1 <-> verschl. Volume 1 <-> /mnt1
Partition 2 <-> verschl. Volume 2 <-> /mnt2
Partition 3 <-> verschl. Volume 3 <-> /mnt3

LVM auf verschlüsseltem Volume:

  • Vorteil: nur eine Partition muss entsperrt werden
  • Nachteil: im nun verwendeten Platz des LVMs können keine unverschlüsselten Partitionen mehr angelegt werden
                                  log. Volume 1 <-> /mnt1
Partition <-> verschl. Volume <-> log. Volume 2 <-> /mnt2
                                  log. Volume 3 <-> /mnt3

verschlüsselte Volumes auf LVM:

  • Vorteil: Auf dem LVM können neben verschlüsselten auch unverschlüsselte Volumes angelegt werden
  • Nachteil: Alle verschlüsselten Volumes müssen einzeln entsperrt werden
              log. Volume 1 <-> verschl. Volume 1 <-> /mnt1
Partition <-> log. Volume 2 <-> verschl. Volume 2 <-> /mnt2
              log. Volume 3 <-> verschl. Volume 3 <-> /mnt3

Um verschlüsselte oder logische Volumes anzulegen, muss einem vorhandenen Volume beziehungsweise einer Partition der Verwendungszweck physikalisches Volume für Verschlüsselung oder physikalisches Volume für LVM zugewiesen werden. Ist das abgeschlossen, muss im Menü der Punkt Verschlüsselte Datenträger konfigurieren beziehungsweise Logical Volume Manager konfigurieren aktiviert werden.

Mehr zum Thema LVM findest du hier LVM - Logical Volume Manager

verschlüsselter Datei Container

  • Vorteil: eine Datei, die man zum Beispiel auf einem USB Stick kopieren kann
  • Nachteil: Eine Dateisystemschicht mehr.
              file container 1 <-> verschl. Volume 1 <-> /mnt1
Partition <-> file container 2 <-> verschl. Volume 2 <-> /mnt2
              file container 3 <-> verschl. Volume 3 <-> /mnt3

Installation cryptsetup

Zuerst sollte das Paket cryptsetup installiert werden.

Unter Debian oder Ubuntu Linux genügt dieser Befehl:

apt update
apt install cryptsetup

Bestes Verschlüsselungsverfahren

Möchte man schauen, welches die beste, schnellste Verschlüsselung auf eurem System ist kann man dies mit dem folgenden Befehl testen:

cryptsetup benchmark

Dies testet alle verfügbaren Ciphers auf eurem System:

# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1       327680 iterations per second for 256-bit key
PBKDF2-sha256     543303 iterations per second for 256-bit key
PBKDF2-sha512     447344 iterations per second for 256-bit key
PBKDF2-ripemd160  281270 iterations per second for 256-bit key
PBKDF2-whirlpool  121362 iterations per second for 256-bit key
argon2i       4 iterations, 380248 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id      4 iterations, 381440 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b        82.5 MiB/s        87.1 MiB/s
    serpent-cbc        128b               N/A               N/A
    twofish-cbc        128b        62.1 MiB/s        61.9 MiB/s
        aes-cbc        256b        66.0 MiB/s        67.5 MiB/s
    serpent-cbc        256b               N/A               N/A
    twofish-cbc        256b        62.2 MiB/s        62.0 MiB/s
        aes-xts        256b        89.7 MiB/s        91.0 MiB/s
    serpent-xts        256b               N/A               N/A
    twofish-xts        256b        64.3 MiB/s        63.4 MiB/s
        aes-xts        512b        69.3 MiB/s        69.7 MiB/s
    serpent-xts        512b               N/A               N/A
    twofish-xts        512b        63.9 MiB/s        63.2 MiB/s

Nun kann man sich den besten Kompromiss an Geschwindigkeit und Sicherheit auswählen. Der Test hier war auf einem Raspberry Pi 4 und ich würde hier aes-xts 256b wählen.

Partition einer Festplatte verschlüsseln

Möchte man nun eine bestehende Partition einer Festplatte verschlüsseln dann führen die folgenden Befehle zum Ziel:

# Verschlüsselung der gesamten Partition /dev/sda1
cryptsetup -y luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha256 /dev/sda1
# Entschlüsseln / Öffnen der verschlüsselten Partition nach my_mount
cryptsetup luksOpen /dev/sda1 my_mount
# Formatieren der entschlüsselten Partition mit ext4
mkfs.ext4 /dev/mapper/my_mount
# Mountpoint anlegen
mkdir /mnt/my_data/
# Mounten der entschlüsselten ext4 Partition nach /mnt/my_data
mount /dev/mapper/my_mount /mnt/my_data/

Datei Container verschlüsseln

Hierfür muss man zunächst eine Datei mit der gewünschten Größe mit dd als Container anlegen:

dd if=/dev/zero of=/mnt/usb/my_container bs=1M count=20480

Dies legt eine 20GB große Datei Namens my_container an.

Dies kann nun wie eine Partition / Festplatte oder Logical Volume verschlüsselt werden:

cryptsetup -y luksFormat --cipher aes-xts-plain64 --key-size 256 --hash sha256 /mnt/usb/my_container

Nun kommt es zu folgender Eingabemaske:

WARNING!
========
This will overwrite data on /mnt/usb/my_container irrevocably.

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /mnt/usb/my_container1: 
Verify passphrase: 

Nachdem nun die Verschlüsselung erstellt ist, öffnen wir nun die Datei:

# Verschlüsselung öffnen - Passkey eingeben
cryptsetup luksOpen /mnt/usb/my_container my_mount
# Formatieren
mkfs.ext4 /dev/mapper/my_mount
# Mounten
mount /dev/mapper/my_mount /mnt/my_data/


Im Folgenden werde ich an einem Beispiel erklären, welche Befehle benötigt werden um eine verschlüsselte Partition mit dm-crypt/LUKS einzurichten und zu verwenden.

Vorbereitung: Es wird eine verfügbare Partition oder ein leeres Logical Volume benötigt. Es ist *nicht* möglich, eine bestehende Partition ohne Verlust aller auf ihr gespeicherten Daten zu verschlüsseln. Vor der Initialisierung kann die Partition mit Zufallswerten überschrieben werden. Von außen kann man später die verschlüsselten Daten nicht von den leeren Bereichen mit Zufallswerten unterscheiden. Außerdem werden dabei alte noch vorhandene Datenreste überschrieben.

In meinem Beispiel wird nun die Partition /dev/hda3 mit Zufallswerten überschrieben. Dazu dient /dev/urandom als Quelle:

dd if=/dev/urandom of=/dev/hda3 bs=10M

liest jeweils Blöcke von 10 Megabytes Größe aus /dev/urandom und schreibt diese dann auf die Platte, solange bis die Partition voll ist.

Nachdem die Partition vorbereitet wurde muss sie nun über cryptsetup initialisiert werden. Praktischerweise gibt es ein kleines Skript namens luksformat, welches dieses mit vernünftigen Voreinstellungen für die Verschlüsselung erledigt. Außerdem legt es zusätzlich noch ein Dateisystem auf der Partition an. Da die Partition nur unter Linux benutzt werden soll werde ich das ext3-Dateisystem verwenden:

# luksformat -t ext3 /dev/hda3
creating encrypted device on /dev/hda3

WARNING!
========
Daten auf /dev/hda3 werden unwiderruflich überschrieben.

Are you sure? (Type uppercase yes): YES

luksformat fragt nach einem Passwort für die Partition, welches insgesamt dreimal eingegeben werden muss. Abschließend entsperrt es die Partition, legt ein ext3-Dateisystem an und sperrt sie dann wieder. Statt luksformat könnte man auch direkt cryptsetup benutzen, die entsprechenden Befehle wären:

cryptsetup luksFormat --cipher aes-cbc-essiv:sha256 /dev/hda3
cryptsetup luksOpen /dev/hda3 luksformatxxx
mkfs.ext3 /dev/mapper/luksformatxxx
cryptsetup luksClose /dev/mapper/luksformatxxx

Damit sind die Vorbereitungen angeschlossen und die Partition kann verwendet werden.

Luks Device Öffnen

Um ein LUKS-Gerät verwenden zu können, muss es erstmal wie im Folgenden beschrieben geöffnet werden, wobei der Name variabel ist, aber keine Sonder- und Leerzeichen enthalten sollte. Nach Eingabe des Passwortes wird die Partition unverschlüsselt auf /dev/mapper/<Name> abgebildet und kann mit dieser Bezeichnung beispielsweise zum Formatieren oder Ein-/Aushängen angesprochen werden.

cryptsetup luksOpen <Gerät> <Name>

Luks Device Schließen

Sobald das enthaltene Dateisystem nicht mehr eingehängt ist oder anderweitig verwendet wird, kann das LUKS-Gerät wie folgt geschlossen werden:

cryptsetup luksClose <Name>

Passwörter verwalten

LUKS bietet insgesamt acht Speicherplätze (genannt "Slot" 0-7) für änderbare Passwörter, die jeweils den Zugriff auf die Daten erlauben. Die belegten Speicherplätze und Headerinformationen lassen sich mittels dieses Befehl überprüfen:

cryptsetup luksDump <Gerät>

Passwort hinzufügen

Zuerst das alte Passwort eingeben,dann das neue.

cryptsetup luksAddKey <Gerät>

Passwort löschen

Ein bekanntes Passwort kann ab Intrepid mit folgendem Befehl entfernt werden:

cryptsetup luksRemoveKey <Gerät>

Will man hingegen einen bestimmten Slot löschen, kann man dies mit folgendem Befehl tun:

cryptsetup luksKillSlot <Gerät> <Speicherplatz>

Alternativ muss in Ubuntu Dapper und Ubuntu Hardy wie folgt ein Slot entfernt werden:

cryptsetup luksDelKey <Gerät> <Speicherplatz>

Passwort ändern

Zum Ändern eines Passworts wird zuerst das neue Passwort hinzugefügt und anschließend das alte entfernt.

Einbinden automatisieren - crypttab

Auf die oben beschriebene Art und Weise kann man die verschlüsselten Partitionen von Hand aktivieren und deaktivieren. Auf die Dauer ist das aber sehr lästig. cryptsetup sieht allerdings eine Möglichkeit vor, Partitionen automatisch beim Hochfahren des Systems zu entsperren. Dazu trägt man diese in der Datei /etc/crypttab ein. Folgende Informationen können dort eingetragen werden:

  • Der Name der Device-Mapper-Verknüpfung, hier also hda3_crypt
  • Der Name der verschlüsselten Partition, hier /dev/hda3
  • Der Pfad zu einer Schlüsseldatei, oder bei Verwendung eines Passwortes stattdessen none
  • Angaben über die verwendete Verschlüsselung - da diese Informationen bei LUKS im Anfangsbereich der Partition gespeichert werden in diesem Fall einfach nur luks

Die komplette Zeile für das oben genannte Beispiel würde also so aussehen:

# <target name> <syntaxhighlight device>         <key file>      <options>
     hda3_crypt       /dev/hda3               none           luks

Beim nächsten Neustart des Systems wird cryptsetup automatisch die Partition entsperren und dabei nach dem Passwort fragen. Um die Partition beim Systemstart automatisch einzuhängen muss nur noch ein Eintrag in der /etc/fstab angelegt werden, zum Beispiel:

/dev/mapper/hda3_crypt    /mnt    ext3    auto,defaults    0    0

Datei statt Passwort als Schlüssel

Im vorangegangenen Beispiel wurde ein Passwort zum Entsperren der verschlüsselten Partition benutzt. Der Debian-Installer kann ebenfalls nur verschlüsselte Partitionen mit Passwörtern einrichten (oder, im Falle von Swap, mit Zufallsschlüsseln).

Alternativ kann man aber auch eine Datei, zum Beispiel auf einem USB-Stick, als Schlüssel verwenden. Während man bei der Benutzung von Passwörtern diese (für jede verschlüsselte Partition) beim Hochfahren eintippen muss, bleibt einem bei Schlüsseldateien diese Arbeit erspart - man muss nur dafür sorgen, daß auf den Schlüssel zugegriffen werden kann (zum Beispiel indem der USB-Stick eingesteckt wird).

Wie oben geschrieben kann man für eine LUKS-Partition bis zu acht Passwörter oder Schlüssel verwenden. Vom Debian-Installer oder von luksformat angelegte Partitionen können also mit einer Schlüsseldatei nachgerüstet werden. Die dazu nötigen Schritte lassen sich mit cryptsetup erledigen. Zunächst einmal muss aber eine Schlüsseldatei erstellt werden. Sie sollte nicht zu klein sein (unsicher), aber auch nicht zu groß (lange Dauer beim Entsperren). Ich verwende eine vier kilobyte große Datei:

# dd if=/dev/urandom of=/media/usb/key bs=4k count=1
1+0 Datensätze ein
1+0 Datensätze aus
4096 Bytes (4,1 kB) kopiert, 0,0018383 Sekunden, 2,2 MB/s

Als nächstes muss der Schlüssel der LUKS-Partition hinzugefügt werden. Dabei wird das bestehende Passwort eingegeben und damit dann der Datenschlüssel dechiffriert. Dann wird er durch die Schlüsseldatei neu chiffriert und in einer freien Speicherstelle gesichert:

cryptsetup luksAddKey /dev/hda3 /media/usb/key
Enter any LUKS passphrase:
key slot 0 unlocked.
Command successful

Nun kann testweise die Partition mit dem neuen Schlüssel statt dem Passwort entsperrt werden:

# cryptsetup luksOpen /dev/hda3 hda3_crypt --key-file /media/usb/key
key slot 1 unlocked.
Command successful

Damit kann die Partition ähnlich wie mit einem Passwort manuell entsperrt werden. Dieser Vorgang lässt sich aber auch über die crypttab automatisieren. An dieser Stelle kommt nun die keyfile-Option ins Spiel. Aus dem vorherigen Beispiel wird:

# <target name> <syntaxhighlight device>         <key file>      <options>
     hda3_crypt       /dev/hda3     /media/usb/key           luks

Das ist allerdings noch nicht alles. cryptsetup muss angewiesen werden, das Medium mit dem Schlüssel vor dem Abarbeiten der crypttab zu mounten. Dazu muss es einen Eintrag für das Medium in der /etc/fstab geben, außerdem muss die der Mountpunkt in /etc/default/cryptdisks eingetragen werden:

CRYPTDISKS_MOUNT="/media/usb"

Nach dem Entsperren aller verschlüsselten Partitionen wird das Medium automatischwieder ausgehängt. Zur Sicherheit kann nun noch die initial ram disk neu gebaut werden:

update-initramfs -u

Das Passwort kann auch weiterhin als Ersatz beibehalten (oder mit cryptsetup luksDelKey entfernt) werden. Ist der USB-Stick mit dem Schlüssel eingesteckt, fährt das System ohne Benutzereingaben hoch und entsperrt alle in der crypttab eingetragenen Partitionen selbstständig. Diese Konfiguration funktioniert für alle Partitionen außer der Root-Partition. Da auf dieser Partition gerade die zum Entsperren notwendigen Programme liegen sind hier einige weitere Maßnahmen notwendig.

Tuning???

Ich las irgendwo dass man mit einen renice des crypt Prozesses mehr Performance rausholen kann. Ich habe es getestet und es ist wirklich gefühlt etwas schneller wenn ich per Samba drauf zugreife.

renice 0 `pgrep kcryptd`

Die Zeile lässt sich gut in die /etc/rc.local eintragen, damit beim hochfahren die Prozesse gereniced werden.

Weiterführende Links

http://www.andreasjanssen.de/cryptodisk.html
http://wiki.ubuntuusers.de/LUKS