Erstellen eines verschlüsselten Grow-on-Demand-Volumes mit LUKS

11

Ich versuche, unter Linux ein verschlüsseltes, nach Bedarf wachsendes Dateisystem zu erstellen. Ich bin mit LUKS und Cryptsetup vertraut.

Ich kann eine leere Datei erstellen:

fallocate -l 512M /root/image

Ich kann einen LUKS-Container darauf erstellen:

cryptsetup -y luksFormat /root/image

Und dann "öffnen" Sie es:

cryptsetup luksOpen /root/image luksvolume

An dieser Stelle kann ich einfach ein Dateisystem darauf erstellen:

mkfs.ext4 -j /dev/mapper/luksvolume

Das ist alles in Ordnung und gut. Es wird jedoch nicht auf den Teil der Frage "Grow-on-Demand" eingegangen.

Die Idee ist, dass das Kopieren einer 2-GB-Datei in das verschlüsselte Dateisystem das Bild so "erweitert", dass es groß genug ist, um die Datei aufzunehmen.

Ist das überhaupt möglich?

Merc
quelle
Warum sollte das Dateisystem nicht zuerst die richtige Größe haben und welches Problem möchten Sie lösen?
Matthew Ife
3
Manchmal wissen Sie nicht, wie groß ein Dateisystem sein muss. Das Problem besteht darin, dass sich eine Datei in einem verschlüsselten Dateisystem befindet und Mitarbeiter hinzugefügt werden können, ohne dass 1) der Speicherplatz knapp wird 2) Unmengen nicht genutzter Speicherplatz vorhanden sind. Außerdem können Sie diese verschlüsselte Datei an einen anderen Ort kopieren und erneut bereitstellen.
Merc

Antworten:

19

Ja! Es sieht so aus, als wäre es möglich. Lassen Sie uns überprüfen, wie dies erreicht werden kann. Beachten Sie, dass dadurch kein echtes Grow-on-Demand-Dateisystem erstellt wird. Wenn das Dateisystem die maximale Größe der Datei mit geringer Dichte erreicht, werden Fehler gemeldet, wenn nicht genügend Speicherplatz vorhanden ist, wenn noch weitere Daten geschrieben werden müssen.

Zunächst untersuchte ich Thin Provisioning , eine bekannte Technologie, um Speicherplatz in Virtualisierungsszenarien zu sparen. Leider scheint es in gängigen Linux-Anwendungsfällen nur mit LVM verfügbar zu sein . Da dies etwas außerhalb des Rahmens Ihrer Frage zu liegen scheint, habe ich nach etwas anderem gesucht.

Das zweite Konzept, das ich untersucht habe, ist Sparse File . Dies passt genau zu Ihrer Frage und ... mein anfänglicher Zweifel war: " OK. Ich kann eine Sparse-Datei erstellen. Aber was passiert, wenn ich sie als LUKS-Container initialisiere? Wird durch eine solche Initialisierung der gesamte verfügbare Speicherplatz zugewiesen? Wenn nicht, Was passiert, wenn ich das Dateisystem in einem solchen Container initialisiere? Wird ein mkfs.ext4der gesamte verfügbare Speicherplatz zugewiesen? ". Da ich keine Antwort hatte, beschloss ich, es zu versuchen. Also mal sehen, was passiert ist.

Beginnen wir mit meinem aktuellen System, auf dem ich nur 3,3 GB freien Speicherplatz im /repositoryDateisystem habe:

root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  258G    3,3G  99% /repository

Erstellen wir eine 10G- Sparse-Datei in einem solchen Dateisystem mit:

root@iMac-Chiara:~# dd of=/repository/file_container.img bs=1G count=0 seek=10
0+0 record dentro
0+0 record fuori
0 byte (0 B) copiati, 0,000119606 s, 0,0 kB/s

und lassen Sie uns überprüfen, ob ... es sich wirklich um eine spärliche Datei handelt:

root@iMac-Chiara:~# ls -lh /repository/file_container.img 
-rw-r--r-- 1 root root 10G dic 12 19:48 /repository/file_container.img

IN ORDNUNG. Wir haben also eine 10G- Datei in einem Dateisystem, das zuvor 3,3G freien Speicherplatz hatte. Wie viel freien Speicherplatz habe ich noch?

root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  258G    3,3G  99% /repository

Immer noch 3,3G. Nett. Sparse-Dateien sind wirklich ... Sparse-Dateien ;-) Lassen Sie uns einen Schritt weiter gehen, indem wir einen LUKS-Container in einer solchen 10G-Datei erstellen und ... mal sehen, ob uns der Speicherplatz ausgeht:

 root@iMac-Chiara:~# losetup /dev/loop0 /repository/file_container.img
 root@iMac-Chiara:~# cryptsetup -y luksFormat /dev/loop0

 WARNING!
 ========
 Ciò sovrascriverà i dati in /dev/loop0 in modo irreversibile.

 Are you sure? (Type uppercase yes): YES
 Inserire la passphrase LUKS: 
 Verify passphrase: 
 root@iMac-Chiara:~# cryptsetup luksOpen /dev/loop0 secretfs
 Inserire la passphrase per /dev/loop0: 
 root@iMac-Chiara:~#

Jetzt habe ich einen geöffneten secretsContainer über meiner 10G-Sparse-Datei definiert, der in einem Dateisystem mit nur 3,3G freiem Speicherplatz gespeichert ist.

Wie viel freien Speicherplatz habe ich noch?

 root@iMac-Chiara:~# df -h /repository
 File system     Dim. Usati Dispon. Uso% Montato su
 /dev/sda3       275G  258G    3,3G  99% /repository

Wunderbar! Immer noch 3,3 GB. Unser verschlüsselter Container benötigte meist keinen Platz!

Lassen Sie uns überprüfen, ob alles in Ordnung ist oder ob unser Setup etwas Seltsames enthält:

root@iMac-Chiara:~# cryptsetup status secretfs
/dev/mapper/secretfs is active.
  type:    LUKS1
  cipher:  aes-cbc-essiv:sha256
  keysize: 256 bits
  device:  /dev/loop0
  loop:    /repository/file_container.img
  offset:  4096 sectors
  size:    20967424 sectors
  mode:    read/write

Alles scheint in Ordnung zu sein, also lasst uns anfangen, einen solchen Behälter zu verwenden, um etwas aufzubewahren. Beginnen wir mit der Erstellung eines EXT4-Dateisystems:

root@iMac-Chiara:~# mkfs.ext4 /dev/mapper/secretfs 
mke2fs 1.42.5 (29-Jul-2012)
Etichetta del filesystem=
OS type: Linux
Dimensione blocco=4096 (log=2)
Dimensione frammento=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
655360 inodes, 2620928 blocks
131046 blocks (5.00%) reserved for the super user
Primo blocco dati=0
Maximum filesystem blocks=2684354560
80 gruppi di blocchi
32768 blocchi per gruppo, 32768 frammenti per gruppo
8192 inode per gruppo
Backup del superblocco salvati nei blocchi: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: fatto                           
Scrittura delle tavole degli inode: fatto                           
Creating journal (32768 blocks): fatto
Scrittura delle informazioni dei superblocchi e dell'accounting del filesystem: fatto

root@iMac-Chiara:~#

Es sieht so aus, als hätte es funktioniert, da es keine Spur von "out of space" gab. Lass uns das Prüfen:

root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  258G    3,2G  99% /repository

Ähm ... also ist etwas passiert. Wir verloren etwas wie 100M Platz aber .... es ist ein erwartetes Verhalten: die Schaffung des EXT4 Dateisystem DO erfordert das Schreiben von vielen Metadaten. Es ist also normal, dass beim Erstellen etwas Speicherplatz verwendet wurde.

Ist es ein "funktionierendes" EXT4-Dateisystem?

root@iMac-Chiara:~# tune2fs -l /dev/mapper/secretfs
tune2fs 1.42.5 (29-Jul-2012)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          e63321c3-cee7-478d-a6af-cbdcaf1be1f7
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              655360
Block count:              2620928
Reserved block count:     131046
Free blocks:              2541265
Free inodes:              655349
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      639
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Sat Dec 12 19:58:05 2015
Last mount time:          n/a
Last write time:          Sat Dec 12 19:58:05 2015
Mount count:              0
Maximum mount count:      -1
Last checked:             Sat Dec 12 19:58:05 2015
Check interval:           0 (<none>)
Lifetime writes:          131 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      c8b3bf1b-9f05-4267-85d3-2ecfdbaa6dc3
Journal backup:           inode blocks

Ja! Es sieht ok aus.

Jetzt haben wir ein EXT4-Dateisystem in einem geöffneten LUKS-Container geschrieben, der über einer 10G-Sparse-Datei definiert ist, die in einem 3.3G-Dateisystem gespeichert ist.

Mal sehen, ob alles richtig funktioniert, indem wir Speicherplatz "on-demand" zuweisen.

Beginnen wir mit dem Schreiben von 500 Millionen Dummy-Daten in den verschlüsselten FS

root@iMac-Chiara:~# mkdir /mnt/temp
root@iMac-Chiara:~# mount /dev/mapper/secretfs /mnt/temp
root@iMac-Chiara:~# dd if=/dev/zero of=/mnt/temp/random_data.bin bs=1M count=512
512+0 record dentro
512+0 record fuori
536870912 byte (537 MB) copiati, 2,35214 s, 228 MB/s
root@iMac-Chiara:~#

Haben wir die Datei erfolgreich erstellt?

root@iMac-Chiara:~# ls -lh /mnt/temp/random_data.bin 
-rw-r--r-- 1 root root 512M dic 12 20:09 /mnt/temp/random_data.bin

Es sieht so aus.

Was ist mit unserem realen Dateisystem passiert?

root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  259G    2,5G 100% /repository

Uau! Wir haben etwas mehr als 500 Millionen "verloren". Das ist übrigens gut, da der physische Raum wirklich nach Bedarf zugewiesen wird!

Speichern wir eine weitere 2-GB-Datei:

root@iMac-Chiara:~# dd if=/dev/zero of=/mnt/temp/another_random_data.bin bs=1G count=2
2+0 record dentro
2+0 record fuori
2147483648 byte (2,1 GB) copiati, 25,6539 s, 83,7 MB/s
root@iMac-Chiara:~#

Was ist passiert?

root@iMac-Chiara:~# ls -arlh /mnt/temp
totale 2,6G
-rw-r--r-- 1 root root 512M dic 12 20:09 random_data.bin
drwx------ 2 root root  16K dic 12 19:58 lost+found
-rw-r--r-- 1 root root 2,0G dic 12 20:13 another_random_data.bin
drwxr-xr-x 8 root root 4,0K mag 29  2015 ..
drwxr-xr-x 3 root root 4,0K dic 12 20:12 .
root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  261G    484M 100% /repository
root@iMac-Chiara:~#

Wirklich nett. Was passiert, wenn wir eine Datei löschen?

root@iMac-Chiara:~# rm /mnt/temp/random_data.bin 
root@iMac-Chiara:~# sync
root@iMac-Chiara:~# ls -arlh /mnt/temp
totale 2,1G
drwx------ 2 root root  16K dic 12 19:58 lost+found
-rw-r--r-- 1 root root 2,0G dic 12 20:13 another_random_data.bin
drwxr-xr-x 8 root root 4,0K mag 29  2015 ..
drwxr-xr-x 3 root root 4,0K dic 12 20:14 .
root@iMac-Chiara:~# df -h /repository
File system     Dim. Usati Dispon. Uso% Montato su
/dev/sda3       275G  261G    484M 100% /repository
root@iMac-Chiara:~#

Wie erwartet ist das Verhalten bei Sparse-Dateien genau wie bei Thin Provisioning: Einmal zugewiesen, kann Speicherplatz beim Löschen von Dateien nicht mehr beansprucht werden. Aber das ist im Allgemeinen in Ordnung. Nicht wahr?

An diesem Punkt sollte die Antwort auf Ihre Frage vollständig sein. Richtig?


Zusatz:

Mal sehen, was passiert, wenn der unterstrichene Speicher voll wird:

root@iMac-Chiara:~# dd if=/dev/zero of=/mnt/temp/a_third_random_data.bin bs=1G count=2
2+0 record dentro
2+0 record fuori
2147483648 byte (2,1 GB) copiati, 26,7142 s, 80,4 MB/s
root@iMac-Chiara:~#

Was? es sieht so aus, als wäre es gelungen! Wie war das möglich? Lass uns das Prüfen!

root@iMac-Chiara:~# ls -arlh /mnt/temp
totale 4,1G
drwx------ 2 root root  16K dic 12 19:58 lost+found
-rw-r--r-- 1 root root 2,0G dic 12 20:17 a_third_random_data.bin
-rw-r--r-- 1 root root 2,0G dic 12 20:13 another_random_data.bin
drwxr-xr-x 8 root root 4,0K mag 29  2015 ..
drwxr-xr-x 3 root root 4,0K dic 12 20:17 .
root@iMac-Chiara:~#

Ähm ... Es sieht in Ordnung aus. Sind wir sicher

root@iMac-Chiara:~# df /repository
File system    1K-blocchi     Usati Disponib. Uso% Montato su
/dev/sda3       288110208 275070448         0 100% /repository

Wir haben keinen Platz mehr! Ohne Fehler!

Auch wenn es schön wäre zu untersuchen, was wirklich passiert ist ... Ich überlasse dies Ihrer Neugier und / oder Ihren Fähigkeiten zur Fehlerbehebung bei anderen ServerFault-Mitgliedern ;-)

Habe Spaß!


Übrigens: Ich habe all das hier getestet:

root@iMac-Chiara:~# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=13.04
DISTRIB_CODENAME=raring
DISTRIB_DESCRIPTION="Ubuntu 13.04"
root@iMac-Chiara:~# uname -r
3.8.0-31-generic
root@iMac-Chiara:~# dpkg -l cryptsetup-bin
[...]
ii  cryptsetup-bin             2:1.4.3-4ubuntu2   amd64              disk encryption support - command line tools
root@iMac-Chiara:~#
Damiano Verzulli
quelle
Mir ist aufgefallen, dass Sie root sein müssen, damit diese Befehle funktionieren. Ist das bei spärlichen Dateien immer der Fall?
Merc
Nein Entschuldigung. Sie sollten auch als normaler Benutzer arbeiten, sofern sie über die entsprechende Schreibberechtigung für den Hauptordner verfügen.
Damiano Verzulli
Danke für diese tolle Antwort. Lässt mich mit einer Frage und einer Sorge. Sorge: Sie haben vorgetäuscht, diese zweite 2-GB-Datei erfolgreich geschrieben zu haben, als wirklich kein Platz dafür vorhanden war? Problematisch ... Was passiert, wenn Sie versuchen, es zurückzulesen (mit sha1sum oder so)? Frage: Gibt es Möglichkeiten, eine Datei mit geringer Dichte im gesamten Netzwerk zu sichern, um sie spärlich zu halten (dh nur die tatsächlich verwendeten Teile zu kopieren)?
Thilo
Ich war versucht, weiter nachzuforschen, aber ... leider hatte ich wenig Zeit und es ist definitiv ein Platz, der für eine andere SF-Frage gültig ist. Auf jeden Fall kann dies leicht vermieden werden, indem Sie Ihren Gesamtspeicher nicht überbuchen: Ich meine, Sie können Dateien mit geringer Dichte erstellen, aber ... damit der maximal zuweisbare Speicherplatz auf Ihrer physischen Festplatte passt. Nicht wahr? Wenn Sie stattdessen nach "Überbuchungs" -Lösungen suchen ... dann sollte vielleicht etwas anderes untersucht werden (LVM?)
Damiano Verzulli,
@Thilo Ich bin auch neugierig, was passieren würde, wenn Sie versuchen würden, die Datei zu lesen, die lautlos übergelaufen ist. rsynchat eine --sparseOption, die spärliche Dateien auf der Zieldiskette erstellen soll.
localhost