Wie LUKS2 erweitert wird

Wie LUKS2 erweitert wird

Ich habe vor ein paar Jahren eine Anleitung gelesen, in der beschrieben wurde, wie sich LUKS1 nach rechts und in den angrenzenden freien Raum ausdehnen lässt, ohne dass Daten verloren gehen, aber nicht nach links. Heutzutage ist LUKS2 mit vielen neuen Funktionen erschienen. Macht es Unterschiede bei der Ausweitung nach links, ohne dass Daten verloren gehen??

Antwort1

tl;drDas ist noch nicht wirklich möglich. Das Metadatenformat lässt vermuten, dass es machbar sein sollte, aber bisher ist es noch nicht wirklich implementiert. Sie sollten also beim guten alten „alle Daten verschieben“ bleiben oder „neue Partition erstellen und LVM sich darum kümmern lassen“. Dasselbe machen Sie mit LUKS1 und den meisten Dateisystemen.


DerLUKS2-Headerhat ein Konzept vonDatensegmente:

Das Segmentobjekt enthält eine Definition verschlüsselter Bereiche auf der Festplatte, die Benutzerdaten enthalten (in LUKS1 als Benutzerdatennutzlast bezeichnet). Für ein normales LUKS-Gerät ist nur ein Datensegment vorhanden.

Bei der Neuverschlüsselung der Daten wird der Datenbereich intern entsprechend dem neuen und dem alten Schlüssel aufgeteilt, dem Benutzer soll jedoch immer nur ein abstrahierter Bereich präsentiert werden.

MitDatensegmentesollte es möglich sein, den LUKS-Header nach links zu verschieben, weiterhin auf die Originaldaten (erstes Segment) zu verweisen und den freien Speicherplatz (zwischen Header und Datensegment) als neues Datensegment zu verwenden, das logisch an das Ende des Crypt-Geräts angehängt wird. Genauso wie LVM beliebige Gruppen physischer Extents an ein logisches Volume anhängt.

Aber das ist nur eine Theorie.

Bislang gibt es keine praktische Anwendung/kein Tool, das diese Funktion implementiert, und ich habe keine Ahnung, ob es Pläne dazu gibt.


Ich habe versucht, es auf unkonventionelle Weise zum Laufen zu bringen (eine Art Proof of Concept):

# truncate -s 100M foobar.img
# cryptsetup luksFormat --type=luks2 foobar.img
# cryptsetup luksOpen foobar.img foobar
# yes > /dev/mapper/foobar
# sync
# hexdump -C /dev/mapper/foobar
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
05400000

Mit LUKS2 verschlüsseltes Ja-Muster. Wie sieht das Datensegment aus?

# cryptsetup luksDump foobar.img
Data segments:
  0: crypt
    offset: 16777216 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]
# strings -n 100 foobar.img
"segments":{"0":{"type":"crypt","offset":"16777216","iv_tweak":"0","size":"dynamic","encryption":"aes-xts-plain64","sector_size":512}}

Letzteres ist tatsächlich das, wie die Roh-LUKS2-Metadaten aussehen – es ist ein JSON-Format. Das bearbeiten wir später …

Lassen Sie es uns vergrößern – nach links (um 100 M):

# truncate -s 100M barfoo.img
# cat foobar.img >> barfoo.img
# ls -lh *.img
-rw-r--r-- 1 root root 200M Jun  9 20:57 barfoo.img
-rw-r--r-- 1 root root 100M Jun  9 20:53 foobar.img

Barfoo.img besteht also aus 100 M neuem leeren Speicherplatz, gefolgt von 100 M dem ursprünglichen LUKS-Container.

Verschieben Sie den LUKS-Header zum neuen Geräteanfang:

# dd bs=1M count=16 if=foobar.img of=barfoo.img conv=notrunc
# cryptsetup luksOpen barfoo.img barfoo
# hexdump -C -n 16 /dev/mapper/barfoo
00000000  4e a6 39 e7 e0 e8 63 ae  81 72 29 81 5f 1b 08 c2  |N.9...c..r)._...|
00000010

Es kann jetzt geöffnet werden, aber dieDatensegmentzeigt immer noch auf den alten Offset (16MiB), aber natürlich ist es nicht da - wir haben 100M hinzugefügt, also der Offset für dieseDatensegmentsollte jetzt 116 MiB sein.

Bearbeiten Sie es (Offset 16777216 zu Offset 121634816):

# strings -n 100 barfoo.img | head -n 1 > barfoo.json
# nano -w barfoo.json
# dd if=barfoo.json of=barfoo.img bs=1 seek=4096 conv=notrunc
# dd if=barfoo.json of=barfoo.img bs=1 seek=20480 conv=notrunc

Ergebnis:

# cryptsetup luksDump barfoo.img
Device barfoo.img is not a valid LUKS device.

Oh, aber natürlich. LUKS2 hat jetzt auch Metadaten-Prüfsummen. Es will nicht, dass Sie Sachen mit Nano bearbeiten und den Header mit dd verstümmeln. Keine geheimnisvolle Magie für Sie, Sir. Nun, das heißt, bis Sie auch die Prüfsumme patchen ...

# cryptsetup luksDump barfoo.img --debug
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:8552bf514ab70b53e63180e9fdd3bb59db1385e3dca87f792f8197b33b851aa1 (on-disk)
# Checksum:e6f322921feae0193bcbc4cddc23b87b7f192266b4a2ef34847580fd7ca18a3e (in-memory)
# LUKS2 header checksum error (offset 0).

... ersetzen Sie hier grundsätzlich die Prüfsumme auf der Festplatte durch die im Arbeitsspeicher.

# echo e6f322921feae0193bcbc4cddc23b87b7f192266b4a2ef34847580fd7ca18a3e |
  xxd -r -ps - |
  dd of=barfoo.img bs=1 seek=448 conv=notrunc

Ergebnis (jetzt wirklich):

# cryptsetup luksDump barfoo.img
Data segments:
  0: crypt
    offset: 121634816 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]
# hexdump -C /dev/mapper/barfoo
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
05400000

An diesem Punkt haben wir den LUKS-Header erfolgreich 100 M nach links verschoben. Aber die Gerätegröße ist immer noch dieselbe... können wir jetzt ein weiteres Datensegment hinzufügen? Es gibt ein freies 100-M-Segment vom Offset 16 M bis 116 M. Fügen wir es dem JSON hinzu.

# nano -w barfoo.json
man this is unreadable
# jq < barfoo.json > barfoo.pretty
# nano -w barfoo.pretty
...
  "segments": {
    "0": {
      "type": "crypt",
      "offset": "121634816",
      "iv_tweak": "0",
      "size": "88080384",
      "encryption": "aes-xts-plain64",
      "sector_size": 512
    },
    "1": {
      "type": "crypt",
      "offset": "16777216",
      "iv_tweak": "172032",
      "size": "104857600",
      "encryption": "aes-xts-plain64",
      "sector_size": 512
    }
  },
  "digests": {
    "0": {
      "type": "pbkdf2",
      "keyslots": [
        "0"
      ],
      "segments": [
        "0",
        "1"
      ],
...and so on and so forth...

Ergebnis:

# cryptsetup luksDump barfoo.img
Data segments:
  0: crypt
    offset: 121634816 [bytes]
    length: 88080384 [bytes]
    cipher: aes-xts-plain64
    sector: 512 [bytes]

  1: crypt
    offset: 16777216 [bytes]
    length: 104857600 [bytes]
    cipher: aes-xts-plain65
    sector: 512 [bytes]

Leider wurde das Gerät an diesem Punkt einwandfrei geöffnet und hatte die korrekte vergrößerte Größe (JUHU!), aber die Daten waren falsch (NEIN!). Das logische Byte 0 wurde dem physischen Byte 16 MiB statt der erwarteten 116 MiB zugeordnet.

Hey, das ist Segment 1, nicht Segment 0, du Blödmann! Was ist schiefgelaufen?

Ich weiß es nicht. Es ist fast so, als ob Sie keine einfachen Metadatenänderungen vornehmen dürften, um versteckte Funktionen freizuschalten, die noch niemand getestet hat.

Vielleicht liegt es an meinem mangelnden Verständnis, aber selbst wenn ich die Segmente andersherum anordne, werden sie immer in der falschen Reihenfolge geöffnet. Irgendwas sortiert diese nach physischem Offset? Aber warum?

Leider ist dieses besondere Wunderwerk ein Fehlschlag gewesen. Entweder, weil ich etwas falsch gemacht habe, oder weil es einfach noch nicht einsatzbereit ist. Die Funktionalität ist jedoch mehr oder weniger vorhanden – es besteht also noch Hoffnung für die Zukunft.

Beachten Sie, dass es auch dann nicht ratsam wäre, es zu verwenden, wenn es funktionieren würde.

verwandte Informationen