Schutz der Datenintegrität auf Ext4 und XFS mit dm-integrity und LUKS
Im Gegensatz zu COW-Dateisystemen wie BTRFS und ZFS haben traditionelle Linux-Dateisysteme wie ext4 und XFS keine Möglichkeit, eine langsame Datenverschlechterung (auch als Bitrot bekannt) zu erkennen, da sie keine Datenprüfsummen durchführen. Wenn wir diese Dateisysteme verwenden, können wir jedoch Integritätsinformationen auf Blockebene speichern und überprüfen, indem wir dm-integrity verwenden. In diesem Tutorial lernen wir, wie man dm-integrity-Geräte mit dem Dienstprogramm integritysetup erstellt und wie man LUKS-Container mit cryptsetup erstellt.
In diesem Tutorial lernen Sie:
- So erstellen Sie dm-integrity-Geräte mit Integritätssetup auf einer einzigen Festplatte
- Erstellen von dm-integrity-Geräten in Datenredundanz-Setups (ein RAID1-Array)
- So implementieren Sie dm-integrity-Funktionalitäten beim Erstellen eines LUKS-Containers
Simulieren von Bitrot auf herkömmlichen Linux-Dateisystemen
Wie wir bereits sagten, haben traditionelle Linux-Dateisysteme wie ext4 und XFS keine Möglichkeit, die Datenintegrität zu überprüfen, und sind nicht in der Lage, Datenbeschädigungen zu erkennen. Lassen Sie uns das demonstrieren. Als erstes erstellen wir eine Datei mit dd und weisen 512 MiB Speicherplatz zu:
dd if=/dev/zero of=blkdevice bs=1M count=512Mit dem obigen Befehl haben wir dd angewiesen, 512 Blöcke von je 1 MiB aus dem Pseudogerät /dev/zero zu lesen und sie in die Datei "blkdevice" im aktuellen Arbeitsverzeichnis zu schreiben. Sobald wir die Datei erstellt haben, können wir sie als Blockgerät verwenden und ein Dateisystem darauf aufbauen. Für dieses Beispiel werden wir ext4 verwenden:
mkfs.ext4 blkdevice
Wir können das Dateisystem so mounten, als hätten wir es mit jedem anderen "echten" Blockgerät zu tun:
sudo mount blkdevice /mntAn dieser Stelle schreiben wir zufällige Daten in eine Datei und lassen sie den gesamten verfügbaren Platz ausfüllen:
sudo dd if=/dev/urandom of=/mnt/testfileWir sollten eine Ausgabe erhalten, die der folgenden ähnelt:
dd: writing to '/mnt/testfile': No space left on device
976521+0 records in
976520+0 records out
499978240 bytes (500 MB, 477 MiB) copied, 3.95061 s, 127 MB/sHolen wir uns nun die Prüfsumme der Datei, die wir gerade erstellt haben:
sha256sum /mnt/testfileIn diesem Fall erhalten wir folgendes Ergebnis:
22eba8b04d389cd8f89ce055794823baa85c196e7ef81cc2465fb2a50e0f4f1e /mnt/testfileWir nehmen es zur Kenntnis und mounten das Dateisystem:
sudo umount /mntUm nun die Datenbeschädigung oder Bitrot zu simulieren, können wir zufällige Daten direkt auf das Blockgerät schreiben. Im folgenden Beispiel geben wir an, dass wir einen einzelnen Ausgabeblock (count=1) von 1 MiB (bs=1M) schreiben möchten und dass wir nach einem Offset von 15 Ausgabeblöcken derselben Größe vom Anfang des Zielgeräts (seek=15) an mit dem Schreiben beginnen möchten. Wir tun dies, um sicherzustellen, dass wir den Bereich des Dateisystems abdecken, in dem die "Testdatei" gehostet wird. Schließlich verwenden wir conv=notrunc, um sicherzustellen, dass unser "Blockgerät" nicht abgeschnitten wird:
dd if=/dev/urandom of=blkdevice seek=15 count=1 bs=1M conv=notruncAn dieser Stelle mounten wir das Dateisystem erneut und prüfen, ob sich die Prüfsumme von "testfile" geändert hat:
sudo mount blkdevice /mnt
sha256sum /mnt/testfileHier ist das Ergebnis, das wir erhalten:
fb91581b5ed08eae9f3f8400d27bed0b4ad5a8fb4742f2fbabcc0ed409792160 /mnt/testfileWie erwartet ist die Prüfsumme der Datei nun eine andere. Die Änderung geschah stillschweigend: Traditionelle Dateisysteme verfolgen keine Datenprüfsummen, daher haben sie keine Möglichkeit, den "Bitrot" zu bemerken. Hier kann dm-integrity helfen.
Verwenden von dm-integrity auf einer einzelnen Festplatte
Die Verwendung von dm-integrity auf einer einzelnen Festplatte ist nicht so sinnvoll: Während bei einem Setup mit mehreren Datenkopien, wie z.B. einem RAID1, beschädigte Daten automatisch durch eine intakte Kopie ersetzt werden können, ist dies bei einem Setup mit nur einer Festplatte natürlich unmöglich. In der Lage zu sein, eine Beschädigung zu bemerken, kann jedoch immer noch nützlich sein, vielleicht als Zeichen für einen möglichen Ausfall der Festplatte.
Installieren des Dienstprogramms integritysetup
Um dm-integrity zu verwenden, müssen wir unser Gerät mit dem Dienstprogramm integritysetup formatieren. Um es auf Fedora und anderen Distributionen der Red Hat-Familie zu installieren, können wir Folgendes ausführen:
sudo dnf install integritysetupUnter OpenSuse (Leap/Tumbleweed) können wir den "zypper" verwenden, um das gleichnamige Paket zu installieren:
sudo zypper in integritysetupAuf Debian und Debian-basierten Distributionen wird das Dienstprogramm durch das Paket "cryptsetup-bin" bereitgestellt. Wir können es installieren, indem wir Folgendes ausführen:
sudo apt install cryptsetup-binUnter Archlinux ist das Dienstprogramm integritysetup im Paket "cryptsetup" enthalten, das im "core"-Repository verfügbar ist:
sudo pacman -S cryptsetupErstellen eines dm-integrity-Volumes
Um ein dm-integrity-Volume zu erstellen, verwenden wir das Dienstprogramm "integritysetup", um ein Partitions-/Blockgerät zu formatieren. In Anlehnung an unsere vorherigen Beispiele arbeiten wir mit der vorhandenen Datei "blkdevice" und behandeln sie als Blockgerät. Um es zu formatieren, verwenden wir den folgenden Befehl:
sudo integritysetup format blkdeviceWir werden aufgefordert, zu bestätigen, dass wir den Vorgang ausführen möchten, da alle Daten auf dem Gerät überschrieben werden:
WARNING!
========
This will overwrite data on blkdevice irrevocably.
Are you sure? (Type 'yes' in capital letters): YESNachdem wir das dm-integrity-Volume erstellt haben, müssen wir es öffnen und einen Gerätezuordnungsnamen dafür angeben. Für dieses Tutorial verwenden wir "testdevice":
sudo integritysetup open blkdevice testdeviceAn dieser Stelle können wir ein neues Dateisystem auf dem gemappten Gerät erstellen (/dev/mapper/testdevice):
sudo mkfs.ext4 /dev/mapper/testdeviceLassen Sie uns noch einmal das Dateisystem mounten und die Datei "testfile" erstellen, indem wir sie mit zufälligen Daten füllen:
sudo mount /dev/mapper/testdevice /mnt
sudo dd if=/dev/urandom of=/mnt/testfile
Genau wie zuvor behalten wir die Prüfsumme der Datei im Auge:
sha256sum /mnt/testdevice
3b0d6256f991d4a352ed9181621813ba6b909b5cab0547a9554cac400074c3a5 /mnt/testdeviceEs ist an der Zeit, das Dateisystem auszuhängen, das integritysetup-Gerät zu schließen und die Datenbeschädigung erneut zu simulieren:
sudo umount /mnt
sudo integritysetup close testdevice
dd if=/dev/urandom of=blkdevice seek=15 count=1 bs=1M conv=notruncAn diesem Punkt können wir das Dateisystem erneut mounten und versuchen, die Prüfsumme der Datei zu erhalten:
sudo integritysetup open blkdevice testdevice
sudo mount /dev/mapper/testdevice /mnt
sha256sum /mnt/testfileSobald wir versuchen, die Datei zu lesen, erhalten wir eine Fehlermeldung:
sha256sum: /mnt/testdevice: Input/output errorWas ist passiert? Da wir jetzt dm-integrity verwenden, wurde die Datenbeschädigung entdeckt und das Dateisystem gab einen Eingabe-/Ausgabefehler zurück. Weitere Details zu dem Vorfall finden wir, indem wir einen Blick in die Kernel-Protokolle werfen:
sudo dmesg | tail -5Wir sollten in der Lage sein, etwas Ähnliches zu lesen wie:
[32942.115228] device-mapper: integrity: dm-8: Checksum failed at sector 0x5782
[32942.117906] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758
[32942.119440] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758
[32942.119532] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758
[32942.119614] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758Verwendung von dm-integrity mit Datenredundanz
Wie wir bereits sagten, haben wir mit einem einzigen Festplatten-Setup keine Möglichkeit, Beschädigungen zu beheben, da wir nur eine einzige Kopie der Daten haben. Bei der Verwendung eines Datenredundanz-Setups wie RAID1 ändert sich einiges. Simulieren wir es. Zuerst erstellen wir zwei Dateien: blkdevice1 und blkdevice2. Wir werden sie als Blockgeräte verwenden:
dd if=/dev/zero of=blkdevice1 bs=1M count=512
dd if=/dev/zero of=blkdevice2 bs=1M count=512Auf jedem von ihnen erstellen wir ein dm-integrity-Volume. Unten verwenden wir die Option -q (kurz für --batch-mode), um die Bestätigungsaufforderung zu überspringen:
sudo integritysetup -q format blkdevice1
sudo integritysetup -q format blkdevice2Öffnen wir sie:
sudo integritysetup open blkdevice1 testdevice1
sudo integritysetup open blkdevice2 testdevice2Wir können die Geräte nun mit dem Dienstprogramm mdadm zu einem RAID1 zusammenbauen:
sudo mdadm --create /dev/md0 --level 1 --raid-devices=2 /dev/mapper/testdevice1 /dev/mapper/testdevice2Wir erstellen ein neues Array mit der Option --create und geben den Pfad des Geräts an: /dev/md0. Wir geben den RAID-Level mit der Option --level an, die Anzahl der aktiven Geräte mit --raid-devices und schließlich übergeben wir den Pfad der Blockgeräte, die wir in das Array aufnehmen möchten. Sobald das RAID zusammengebaut ist, können wir ein Dateisystem auf dem resultierenden Gerät erstellen:
sudo mkfs.ext4 /dev/md0Nun mounten wir das Dateisystem, das wir gerade erstellt haben, schreiben eine Datei mit zufälligen Daten und erstellen die Datenbeschädigung auf der ersten der beiden Festplatten, die Teil des Arrays sind:
sudo mount /dev/md0 /mnt
sudo dd if=/dev/urandom of=/mnt/testfile
dd if=/dev/urandom of=blkdevice1 seek=15 count=1 bs=1M conv=notruncWir können jetzt eine Datenbereinigung durchführen: Indem wir "test" in die Datei /sys/block/md0/md/sync_action schreiben, lassen wir das RAID alle Datenblöcke auf allen Geräten lesen:
echo "check" | sudo tee /sys/block/md0/md/sync_actionWie wir bereits gesehen haben, werden Integritätsfehler in den Kernel-Protokollen gemeldet. Hier ist der relevante Teil:
[36735.559800] md: check of RAID array md0
[36735.579268] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b00
[36735.579465] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b80
[36735.579508] device-mapper: integrity: dm-8: Checksum failed at sector 0x5980
[36735.579522] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a00
[36735.579533] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c80
[36735.579544] device-mapper: integrity: dm-8: Checksum failed at sector 0x5900
[36735.579606] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a80
[36735.579617] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c00
[36735.581460] device-mapper: integrity: dm-8: Checksum failed at sector 0x5780
[36735.582377] device-mapper: integrity: dm-8: Checksum failed at sector 0x5e80
[36737.803123] md: md0: check done.Wenn wir an dieser Stelle den data-scrub erneut ausführen und die Kernel-Protokolle überprüfen, sollten wir keine Fehlermeldungen bemerken:
[37245.887325] md: check of RAID array md0
[37248.101670] md: md0: check done.Dank dm-integrity wurde die Datenbeschädigung erkannt und automatisch repariert.
Verwendung von dm-integrity mit LUKS
LUKS (Linux Unified Key Setup) ist der Standard für die Festplattenverschlüsselung unter Linux. Beim Formatieren eines rohen Blockgeräts oder einer Partition als LUKS-Container können wir angeben, dass wir dm-integrity verwenden möchten, ohne integritysetup zu verwenden. Alles, was wir tun müssen, ist, cryptsetup mit der Option --integrity aufzurufen und den Integritätsalgorithmus, den wir verwenden möchten, als Argument zu übergeben:
sudo cryptsetup luksFormat --type luks2 --integrity hmac-sha256 blkdevice1Schlüsse
In diesem Tutorial haben wir gelernt, wie man dm-integrity verwendet, um die Prüfsummenbildung und -verifizierung von Daten auf Blockebene zu ermöglichen, wenn herkömmliche Linux-Dateisysteme verwendet werden. Die Möglichkeit, beschädigte Daten auf einem Speichermedium (Bitrot) zu überprüfen, ist sehr wichtig und besonders nützlich bei der Einrichtung mehrerer Festplatten, bei denen erkannte Datenbeschädigungen automatisch repariert werden können. Die Aktivierung von dm-integrity ist jedoch nicht billig: Sie bewirkt unter anderem Schreibverstärkungen, da sie standardmäßig Sektordaten und Integritäts-Tags in ein Journal schreibt. In diesem Artikel haben wir aus offensichtlichen Gründen nicht alle möglichen Optionen erwähnt, die zur Feinabstimmung der dm-Integrität verwendet werden können. Um mehr darüber zu erfahren, werfen Sie bitte einen Blick auf die integritysetup-Manpage und die entsprechende Dokumentation.
