Gefällt dir dieser Artikel?

Gentoo: Linux komplett verschlüsseln

erschienen in der Kategorie Software, am 10.09.2013
Schnatterente
Ich habe euch doch letztens erzählt, dass ich mir einen USB 3.0 Blu-ray-Brenner gekauft habe. Weil ich somit über ein externes Laufwerk verfüge, dass ich bei Bedarf schnell anschließen kann und man eigentlich ohnehin eher selten ein optisches Laufwerk braucht, habe ich den DVD-Brenner aus meinem Laptop ausgebaut und ihn durch ein SSD ersetzt, das mir netterweise von meinem Freund P. zur Verfügung gestellt wurde - Danke P. ;-)

Da SSDs ja sehr hohe Schreib-/Lese-Raten und vor allem niedrige Zugriffszeiten aufweisen, eignen sie sich sehr gut zur effizienten Verschlüsselung von Daten. Daher habe ich mich entschlossen, mein komplettes Linux-Root-Filesystem zu verschlüsseln. Auch meine Swap-Partition habe ich chiffriert. Unverschlüsselt geblieben ist somit nur noch die Boot-Partition, die den Linux-Kernel und ein Initramfs enthält, welches man braucht, um das verschlüsselte Linux-Dateisystem beim Hochfahren wieder freizulegen.

Im Folgenden werde ich mal versuchen zu erklären, wie ich beim Verschlüsseln meines Gentoo Linux vorgegangen bin. Generell sei dazu gesagt, dass sich diese Beschreibung an Linux-Nutzer richtet, die ein gewisses Maß an Vorkenntnissen mitbringen (wie man einen Kernel kompiliert, mit Cryptsetup umgeht, wie man GRUB einrichtet, was fstab ist, etc.).

Ich habe keine Neuinstallation vorgenommen, sondern mein bestehendes System auf das verschlüsselte SSD verschoben. Wer also ein neues Linux aufsetzen will, findet dazu vielleicht irgendwo anders noch bessere Anleitungen. Und es sei auch noch gesagt, dass ich keinen LVM benutze - dementsprechend wird das also auch nicht thematisiert.

Der Masterplan: Dracut, BtrFS, DM-Crypt/Luks und Co.

Wie schon gesagt, war es das Ziel meiner Maßnahme, das verschlüsselte Linux mithilfe eines Initramfs bootbar zu machen. Das Mittel meiner Wahl nennt sich hierbei Dracut.

Beim verschlüsselten Dateisystem habe ich mich von Ext4 verabschiedet. Stattdessen kommt jetzt BtrFS zum Einsatz, weil es besser auf SSDs zugeschnitten ist.

Die Verschlüsselung selbst erfolgt mit DM-Crypt/Luks.

Vielleicht versteht manch ein Leser bisher nur Bahnhof. Daher noch eine kurze Erklärung, wie das mit dem verschlüsselten Linux funktioniert:

Immer wenn man den Computer anschaltet und Linux startet, kommt das Dracut-Initramfs zum Einsatz. Dracut liegt zusammen mit dem GRUB-Bootloader und dem Linux-Kernel auf einer unverschlüsselten Boot-Partition und bringt die nötigen Werkzeuge mit, um das Root-Dateisystem unter Abfrage des Passwortes zu mounten.

Ist dies geschehen, kann das Linux dann normal hochfahren werden und man bekommt im Betrieb nichts mehr von der ganzen Verschlüsselei mit.

Wie bereits gesagt, habe ich auch die Swap-Partition verschlüsselt. Die Swap-Partition dient zur Auslagerung von Dateien auf der Festplatte, wenn der verfügbare Arbeitsspeicher nicht mehr ausreicht, um sie dort abzulegen. Da es sich hierbei üblicherweise um die Daten handelt, mit denen man gerade arbeitet, liegt es auf der Hand, dass man auch Swap-Partitionen verschlüsseln sollte.

Es führen verschiedene Wege nach Rom. Ich habe mich dafür entschieden, dass ich keine fest angelegte Swap-Partition haben will, sondern dass diese jedes Mal beim Booten automatisch erstellt und verschlüsselt werden soll. DM-Crypt bringt die dafür notwendigen Features mit.

Partitionierung: Meine Ausgangssituation und wo die Reise hinführte

Meine Partitionierung habe ich vor einiger Zeit mal in diesem Artikel beschrieben. Bisher hatte ich in meinem Dell Vostro Notebook eine 1TB-Festplatte mit vielen Partitionen (Dell Rescue-Partition, Linux Boot-Partition, Windows Bootloader, Windows Dateisystem, Linux Dateisystem, Linux Swap-Partition).

Mit dem SSD habe ich nun eine zweite Festplatte in meinem Notebook. Ich habe das Linux-Dateisystem und die Swap Partition auf den neuen Datenträger verschoben und auf dem alten platt gemacht. Die Boot-Partition habe ich dort belassen, wo sie war und entsprechende Anpassungen vorgenommen.

So, nun aber das Ganze Mal etwas detaillierter. Ich erkläre jetzt Schritt für Schritt, wie man vorgehen kann, um zum verschlüsselten Linux zu kommen. Bis zum Schritt 3 habe ich alle Änderungen im (noch auf der alten Festplatte) laufenden System vorgenommen. Im Schritt 4 kommt eine Linux-Boot-CD zum Einsatz (erst in diesem Schritt wird das Dateisystem kopiert).

Schritt 1: Installation der benötigten Pakete und Kernel-Module

Für den ganzen Crypto-Spaß braucht man natürlich ein paar Tools. Via emerge installiert man also sys-fs/cryptsetup, sys-fs/btrfs-progs und natürlich sys-kernel/dracut. Auf anderen Linux-Distributionen sollten diese Pakete auch (unter ähnlichen Namen) zu finden sein.

Im Kernel Setup (ich benutze übrigens die Vanilla-Sources) sollte man die folgenden Optionen aktivieren:

General setup  --->
  Local version - append to kernel release
  [*] Automatically append version information to the version string
  [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
Device Drivers  --->
  [*] Multiple devices driver support (RAID and LVM)  --->
    <*>   Device mapper support
      <*>     Crypt target support
File systems  --->
  <*> Second extended fs support
  <*> The Extended 4 (ext4) filesystem
  <*> Btrfs filesystem support
-*- Cryptographic API  --->
  *** Crypto core or helper *** 
    {*}   XTS support
  *** Digest ***
    <*>   SHA256 digest algorithm (SSSE3/AVX/AVX2)
    <*>   SHA512 digest algorithm (SSSE3/AVX/AVX2)
    <*>   SHA224 and SHA256 digest algorithm
  *** Ciphers ***
    -*-   AES cipher algorithms
    <*>   AES cipher algorithms (x86_64)
    <*>   AES cipher algorithms (AES-NI)
    <*>   Blowfish cipher algorithm

Wer eine CPU hat, die (noch) kein AES-NI unterstützt, kann sich das Aktivieren des entsprechenden Eintrags sparen. Mein Intel Core i5 Mobile Prozessor der ersten Generation beherrscht es leider auch noch nicht. Die Performanz des verschlüsselten Systems ist dennoch mehr als ausreichend.

Wenn das Kernelsetup beendet ist, baut man den Kernel und die dazugehörigen Module und installiert ihn.

Schritt 2: Vorbereiten des neuen Laufwerks

Die neue (in meinem Fall SSD-) Festplatte kann man mit einem Tool seiner Wahl partitionieren (z.B. fdisk oder gparted). Ich habe eine große Partition für das Linux-Dateisystem angelegt und eine kleinere (zwei Gigabyte) Swap-Partition.

Vor der Partitionierung kann man den Datenträger (bei mir /dev/sdb) noch mal komplett mit Nullen überschreiben, um alte Datenreste zu beseitigen.

Bei herkömmlichen Festplatten kann dies zum Beispiel mithilfe von dd geschehen:

# dd if=/dev/zero of=/dev/sda

SSDs löscht man hingegen besser mittels "Secure Erase". Nähere Infos dazu, gibt es hier.



Hat man die Partitionierung vorgenommen, kann man dazu übergehen, die spätere Root-Partition zu verschlüsseln:

# cryptsetup -c aes-xts-plain64:sha512 -y -s 512 luksFormat /dev/sdb1

Danach formatiert man die verschlüsselte Partition mit BtrFS:

# cryptsetup --allow-discards luksOpen /dev/sdb1 ssd
# mkfs.btrfs /dev/mapper/ssd

Cryptsetup bindet hierbei den verschlüsselten Datenträger unter dem Namen "ssd" ein. Dadurch entsteht unter /dev/mapper/ eine gleichnamige Datei, über die man Zugriff auf die entschlüsselten Daten erlangt. Man formatiert also die entschlüsselte Partition mit BtrFS und nicht die Partition /dev/sdb1 (welche die verschlüsselten Daten enthält). Wer mit diesem Prinzip noch nicht vertraut ist, sollte sich am besten erst einmal ein Cryptsetup-Tutorial durchlesen.

ACHTUNG: Die Option "--allow-discards" ist nur bei SSDs anzugeben. Bei herkömmlichen Festplatten sollte man das weglassen. Wer wissen will, was es damit auf sich hat, lese sich dies durch.

Schritt 3: Vorbereitungen im laufenden System

Da es das Ziel ist, später jenes System auf den neuen Datenträger zu kopieren, in dem man gerade arbeitet, kann man viele der notwendigen Modifikationen im laufenden Betrieb vorbereiten.

Will man unter Linux einzelne Partitionen ansprechen, geht dies nicht nur über Angaben wie "/dev/sda1", sondern auch über die Identifier der jeweiligen Partitionen, die sogenannten UUIDs. Jede Partition hat so eine UUID und im weiteren Vorgehen werden diese benötigt. Daher kann man sich schon mal eine Textdatei mit einer Übersicht der UUIDs erstellen. Es gilt zu beachten, dass es für die chiffrierte Partition sogar zwei UUIDs gibt, nämlich eine für die verschlüsselten Daten (/dev/sda1) und eine für das entschlüsselte Dateisystem (/dev/mapper/ssd).

Der Befehl blkid listet alle UUIDs auf.
Eine UUID sieht ungefähr so aus: a9749d9d-83fd-4bea-a11f-a5105a7cc4c3.

Schritt 3 (2): GRUB Bootmenü-Eintrag (mit Dracut Initramfs) erstellen

Wenn man die UUIDs schon mal parat hat, kann man auch gleich das Dracut-Initramfs erstellen und das GRUB-Boot-Menü anpassen.

Für den ersten Punkt muss man nur das Kommando dracut ausführen (hierdurch wird auf der Boot-Partition ein zum aktuellen Kernel passendes Initramfs-Image erstellt).

In GRUBs menu.lst-Datei (liegt unter /boot/grub/), dupliziert man einfach den bisherigen Linux-Boot-Eintrag und erweitert die Kopie um die benötigten, zusätzlichen Angaben.

Mein alter Boot-Eintrag sah so aus:

title Gentoo Linux
root (hd0,1)
kernel /boot/vmlinuz root=/dev/sda7 video=1600x900


Im neuen Eintrag ist nun das Initramfs mit enthalten. Dabei wird mithilfe der UUIDs angegeben, was die zu entschlüsselnde Partition ist und wie sie dann entschlüsselt heißt.

title Gentoo Linux encrypted
root(hd1,0)
kernel /boot/vmlinuz root=UUID=a9749d9d-83fd-4bea-a11f-a5105a7cc4c3 ro KEYMAP=de LANG=de_DE.UTF-8 video=1600x900 rd.luks=1 rd.lvm=0 rd.md=0 rd.luks.options=--allow-discards rd.luks.uuid=c21ffa78-a184-41a2-ca4c-a47346110e81
initrd /boot/initramfs


Hinter der Angabe "root=" steht die UUID des entschlüsselten (BtrFS) Dateisystems. Die Angabe "rd.luks.uuid=" verweist auf die verschlüsselte Partition (also in meinem Fall /dev/sdb1).

Die Dracut-Parameter sind hier beschrieben. Wer kein SSD benutzt, lässt auch hier wieder das "allow-discards" weg. In diesem Beispiel wird Dracut außerdem noch mitgeteilt, dass die Module LVM und MD-RAID nicht benötigt werden. Man kann sich diese Angaben auch sparen, dann braucht Dracut einen Moment länger beim Starten.

Die Dateien /boot/vmlinuz und /boot/initramfs sind auf meinem System Symlinks zum aktuellen Kernel (z.B. vmlinuz-3.10.10), bzw. zum Dracut-Initramfs-Image (z.B. initramfs-3.10.10.img). Den letztgenannten Link habe ich per Hand angelegt, der andere kommt zustande, wenn man die Kernel-Sources mit der "symlink"-USE-Flag installiert hat. Wer keine Symlinks verwendet, muss die Einträge natürlich entsprechend anpassen.

Schritt 3 (3): DM-Crypt Swap Partition

Wer ebenfalls möchte, dass sich DM-Crypt beim Booten um das Erstellen einer verschlüsselten Swap-Partition kümmert, muss den Dienst zum Runlevel "boot" hinzufügen. Gleiches gilt für den "swap"-Service, der bei den meisten wahrscheinlich schon eingetragen ist.

# rc-update add dmcrypt boot
# rc-update add swap boot


Danach fügt man den folgenden Eintrag zur DM-Crypt-Konfigurationsdatei /etc/conf.d/dmcrypt hinzu:

swap=cryptswap
source='/dev/sdb2'
key='/dev/urandom'
options='--allow-discards'

Dieser Eintrag sorgt dafür, dass der DM-Crypt-Service bei jedem Linux-Start ein verschlüsseltes Swap-Dateisystem (mit einem zufällig gewählten Passwort) auf der Partition /dev/sdb2 anlegt. Wer eine herkömmliche Festplatte verwendet, kann sich die Zeilen "key" und "options" sparen.

ACHTUNG: Wer diese Variante benutzt, muss auf Hibernate (Suspend-to-disk) verzichten (der normale Stand-by-Modus funktioniert aber problemfrei).

Wer den Hibernate-Modus benutzen will, sollte eine feste, verschlüsselte Swap-Partition anlegen und die DM-Crypt-Konfigurationsdatei so anpassen, dass diese beim Hochfahren eingebunden wird (lest dazu die Erläuterungen in der Datei selbst). Ein Ansatz hierfür wäre, die Swap-Partition mit einem anderen Passwort zu verschlüsseln, als die Root-Partition und dieses Passwort explizit in der DM-Crypt-Konfiguration anzugeben (da diese im Root-Dateisystem verschlüsselt ist, stellt das kein allzu großes Sicherheitsproblem dar).

Schritt 3 (4): Neue fstab-Datei vorbereiten

Natürlich müssen auch Änderungen in der Datei /etc/fstab vorgenommen werden. Auch hier kann man wieder die UUIDs nutzen, um die jeweiligen Partitionen anzugeben. Dies hat auch den Vorteil, dass man keine Anpassungen vornehmen muss, wenn sich mal etwas an der Partitionstabelle ändert. Nur bei der dynamisch angelegten Swap-Partition geht dies nicht, denn ihre UUID ändert sich jedes Mal beim Booten. Nach der oben vorgegebenen DM-Crypt-Konfiguration kann man aber immer über das Mapping /dev/mapper/cryptswap auf sie zugreifen.

Da man noch im alten, laufenden System unterwegs ist und dieses nicht unbootbar machen will, erstellt man sich eine Kopie der fstab-Datei, welche man nachfolgend bearbeitet (cp /etc/fstab /etc/fstab-verschluesselt). Die neue fstab-Datei sieht dann ungefähr so aus:

UUID="acb1bdb9-dfc2-4e01-ab2a-e103eba4011b"/bootext2defaults,noatime0 2
UUID="4387372d-d289-4eb5-9fcf-a747b99b8623"/btrfsdefaults,noatime0 0
/dev/mapper/cryptswapnoneswapsw0 0
proc/procprocnodev,nosuid,noexec0 0
shm/dev/shmtmpfsnodev,nosuid,noexec0 0
tmp/tmptmpfsrw0 0

Bei der Angabe des Wurzel-Dateisystems wird natürlich auch hier die entschlüsselte BtrFS-Partition angegeben.

Schritt 4: Kopieren der Daten mit einer Live-CD/DVD

Wenn alle Vorbereitungen getroffen sind, ist es an der Zeit, das Linux nun auch endlich mal auf die neue Festplatte zu kopieren. Dazu lädt man sich eine geeignete Linux-Live-CD/DVD herunter und bootet diese (ich habe mich dabei für das aktuelle Fedora entschieden, weil da eine recht neue Cryptsetup-Version mitgeliefert wird, die schon den Parameter "allow-discards" unterstützt).

Hat man das Live-Linux gebootet, bindet man das alte Root-Dateisystem und die neue, verschlüsselte BtrFS-Partition ein. Das Kopieren der Daten übernimmt cp.

# cryptsetup --allow-discards luksOpen /dev/sdb1 root
# mkdir /mnt/root
# mount /dev/mapper/root /mnt/root

# mkdir /mnt/gentoo
# mount /dev/sda7 /mnt/gentoo

# cd /mnt/
# cp -ax gentoo/* root/


Hatte ich schon mal erwähnt, dass man die "allow-discards"-Option nur bei SSDs benutzt? ;-)

Wenn die Dateien fertig kopiert sind, verschiebt man im neuen Dateisystem noch die vorbereitete fstab-Datei an den richtigen Platz.

# mv /mnt/root/etc/fstab-verschluesselt /mnt/root/etc/fstab


Gratulation, an sich sollte es das gewesen sein und das System müsste sich nun über den neuen Bootmenü-Eintrag starten lassen.

Falls das System nicht starten will, sollte zumindest noch das Linux auf der alten Festplatte funktionieren (auch wenn da jetzt vielleicht DM-Crypt beim Starten rumheult). Dies ist für die Fehlerbehebung sehr hilfreich, denn das Booten dauert nicht so lange, wie bei der Live-CD/DVD.

Noch ein Hinweis für Leute, die Dracut ohne grafischen Firlefanz installiert haben (ohne Bootsplash): Falls ihr den Eindruck habt, der Rechner würde beim Booten einfach hängen bleiben, gebt euer Passwort ein und drückt Enter. Ich dachte am Anfang auch, es würde noch nicht funktionieren, bis ich dann feststellte, dass die Dracut-Passwort-Eingabeaufforderung irgendwo zwischen anderen Dracut- und Kernel-Ausgaben mit versteckt war und längst auf das Kennwort wartete. (Ich betrachte das mal als Feature - so sieht ein Angreifer nicht so schnell, dass überhaupt ein Passwort eingegeben werden muss.)

Schritt 5: Aufräumen

Wenn alles funktioniert, kann man wieder aufräumen. Der alte GRUB-Bootmenü-Eintrag kann aus der "menu.lst"-Datei entfernt werden. Die alten Linux-Partitionen mit den unverschlüsselten Daten sollte man überschreiben und löschen. Danach können sie für etwas anderes verwendet werden, z.B. für eine neue, ebenfalls verschlüsselte Daten-Partition.

Pflegeanleitung

Läuft das System einmal, ist nicht mehr allzu viel zu tun. Wenn man einen neuen Kernel installiert, sollte man auch ein dazu passendes Initramfs-Image erstellen. Dies erreicht man, indem man wieder den Befehl dracut aufruft. Falls Dracut (warum auch immer) nicht mitbekommen hat, dass es einen neuen Kernel gibt, kann man es explizit auf die neue Version hinweisen:

# dracut --kver 3.10.10

Ende Gelände

So, der Artikel ist doch länger geworden, als ich ursprünglich dachte. Ich hoffe diese Infos bringen irgendjemanden beim Versuch das eigene System sicherer zu machen weiter. Bezogen auf Gentoo muss ich sagen, dass dieses Thema bisher eher mäßig dokumentiert ist. Daher habe ich mich auch entschieden, diesen Eintrag zu verfassen. Für Rückfragen bin ich jederzeit zu haben.



P.S.: Ja, auch wenn es sich komisch anhört, es heißt das SSD (Solid-State-Drive) und nicht die SSD (es sei denn man schreibt noch -Festplatte dahinter).
Danke P., für das SSD und wertvolle Tipps.

Geschnatter

5 Kommentare, selbst mitschnattern << < Seite 1/1 > >>
dakira, am 10.09.2013 um 14:20 Uhr
Hi. Super Artikel bis auf den Teil mit shred. Das fällt eher in der Bereich der Esoterik. Wurde eine Festplatte 1x überschrieben (mit nullen reicht) ist nichts mehr wiederherzustellen [1].

Bei SSD sieht es freilich anders aus. Da macht man mit shred einfach nur die Lebensdauer kürzer. Die Daten werden auf aktuellen SSDs auf Firmware-Ebene verschlüsselt gespeichert. Um eine SSD zu "shreddern" machst du einfach ein secure_erase [2], was dem Wegwerfen des Schlüssels gleichkommt. Tools wie shred oder dd sollte man auf SSDs zum Schreiben *niemals* verwenden.

[1] http://ct.de/-198816
[2] http://wiki.ubuntuusers.de/SSD/Secure-Erase
Antwort: Danke für die Anmerkung. Ich habe die Links gelesen und den Artikel überarbeitet.
mwillpom, am 02.01.2014 um 23:00 Uhr
Hi,
das ist ein super howto,
Ich habe vor einiger Zeit ein UEFI mit verschlüsselung gemacht, und jetzt wollte ich eine mit grub machen, und bin hierdrauf gestoßen.
Perfekt zum dranfesthangeln, wenn man's schonmal gemacht hat.
Danke!!! Das hat mir viel arbeit erspart.
mwillpom, am 02.01.2014 um 23:10 Uhr
Vllt sollte man noch Anmerken, dass man in der make.conf den eintrag

DRACUT_MODULES="crypt"

ergänzen sollte, damit dracut auch mit einem verschlüsselten rootfs arbeiten/starten kann.
alihup, am 06.09.2014 um 09:00 Uhr
Ich glaube der Befehl
# cryptsetup --allow-discards /dev/sdb1 ssd
sollte
# cryptsetup --allow-discards luksOpen /dev/sdb1 ssd
lauten
Antwort: Stimmt, da fehlte ein luksOpen. Danke für den Hinweis!
holgersson, am 25.05.2015 um 10:34 Uhr
rd.luks.allow-discards klappt nicht -
es muss rd.luks.options:discard heißen;
s. Bugreport/Eintrag 40 von L. Poettering

https://bugzilla.redhat.com/show_bug.cgi?id=890533#c40
Antwort: Danke für den Hinweis. Ich habe das bei mir schon vor längerer Zeit in das hier abgeändert:
rd.luks.options=--allow-discards

Habe es jetzt oben aktualisiert.