Crear un volumen encriptado de crecimiento bajo demanda con LUKS

13

Estoy tratando de crear un sistema de archivos encriptado que crezca según sea necesario con Linux. Estoy familiarizado con LUKS y cryptsetup.

Puedo crear un archivo vacío:

fallocate -l 512M /root/image

Puedo crear un contenedor LUKS en él:

cryptsetup -y luksFormat /root/image

Y luego "abrirlo":

cryptsetup luksOpen /root/image luksvolume

En este punto, solo puedo hacer un sistema de archivos en él:

mkfs.ext4 -j /dev/mapper/luksvolume

Todo está bien y elegante. Sin embargo, no aborda la parte de la pregunta "crecer bajo demanda".

La idea es que copiar un archivo de 2 Gb en el sistema de archivos cifrados "expandirá" la imagen para que sea lo suficientemente grande como para contener el archivo.

¿Es posible hacerlo?

Merc
fuente
¿Por qué no hacer que el sistema de archivos tenga el tamaño correcto en primer lugar y qué problema está tratando de resolver?
Matthew Ife
3
A veces no sabes qué tan grande necesitas que sea un sistema de archivos. El problema es tener un archivo en un sistema de archivos encriptados y poder agregarle personal sin tener que 1) Preocuparse por el espacio que se agota 2) Tener TONELADAS de espacio no utilizado. Además, poder copiar ese archivo cifrado en otro lugar y volver a montarlo.
Merc

Respuestas:

21

¡Si! Parece que es posible. Veamos cómo se puede lograr. Tenga en cuenta que esto no crea un verdadero sistema de archivos de crecimiento bajo demanda, ya que cuando el sistema de archivos alcanza el tamaño máximo del archivo disperso, informará errores de "falta de espacio" si aún se necesita escribir más datos.

Inicialmente, estaba investigando Thin Provisioning , una tecnología bien conocida para ahorrar espacio de almacenamiento en escenarios de virtualización. Desafortunadamente, en casos de uso comunes de Linux, parece estar disponible solo con LVM . Como esto parece un poco fuera del alcance de su pregunta, busqué algo más.

El segundo concepto que investigué es Sparse File . Esto se adapta exactamente a su pregunta y ... mi duda inicial fue: " OK. Puedo crear un archivo disperso. Pero, ¿qué sucede cuando lo inicializo como un contenedor LUKS? ¿Asignará tal inicialización todo el espacio disponible? Si no, ¿Qué sucederá cuando inicialice el sistema de archivos en dicho contenedor? ¿ mkfs.ext4Asignará todo el espacio disponible? ". Como no tenía respuesta, decidí intentarlo. Entonces, veamos qué pasó.

Comencemos desde mi sistema actual, donde solo tengo 3.3G de espacio libre dentro del /repositorysistema de archivos:

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

Creemos un archivo disperso 10G dentro de dicho sistema de archivos, con:

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

y verifiquemos que ... es realmente un archivo escaso:

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

OKAY. Entonces tenemos un archivo 10G , en un sistema de archivos que anteriormente tenía 3.3G de espacio libre. ¿Cuánto espacio libre aún tengo?

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

Todavía 3.3G. Agradable. Sparse-file son realmente ... sparse-file ;-) Vamos un paso adelante, creando un contenedor LUKS dentro de tal archivo 10G y ... veamos si nos quedamos sin espacio:

 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:~#

Así que ahora tengo un secretscontenedor abierto definido en la parte superior de mi archivo disperso 10G almacenado en un sistema de archivos que tiene solo 3.3G de espacio libre.

¿Cuánto espacio libre aún tengo?

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

¡Maravilloso! Todavía 3.3GB. ¡Nuestro contenedor encriptado no requería mayormente espacio!

Verifiquemos si todo está bien o si hay algo extraño con nuestra configuración:

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

Todo parece estar bien, así que comencemos a usar ese contenedor para almacenar algo. Comencemos creando un sistema de archivos EXT4 dentro de él:

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:~#

Parece que funcionó, ya que no había rastro de "fuera del espacio". Vamos a revisar:

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

Uhm ... así que sucedió algo. Hemos perdido algo así como 100 millones de espacio, pero .... es un comportamiento esperado: la creación del sistema de archivos EXT4 DO requiere la escritura de una gran cantidad de metadatos. Por lo tanto, es normal que el proceso de creación haya utilizado algo de espacio.

¿Es un sistema de archivos EXT4 "en funcionamiento"?

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

¡Si! Se ve bien.

Entonces, ahora tenemos un sistema de archivos EXT4 escrito dentro de un contenedor LUKS abierto definido en la parte superior de un archivo disperso 10G almacenado dentro de un sistema de archivos 3.3G.

Veamos si todo funciona correctamente, asignando espacio "a pedido".

Comencemos escribiendo 500 millones de datos ficticios en el FS cifrado

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:~#

¿Hemos tenido éxito en la creación del archivo?

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

Se ve así.

¿Qué pasó con nuestro sistema de archivos real?

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

Uau! "Perdimos" un poco más de 500M. Eso es bueno, por cierto, ya que el espacio físico se asigna realmente a pedido.

Guardemos otro archivo de 2GB:

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:~#

¿Que pasó?

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:~#

Muy agradable. ¿Qué sucede si eliminamos un archivo?

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:~#

Como era de esperar, con el archivo disperso el comportamiento es exactamente como el aprovisionamiento delgado: una vez asignado, el espacio de almacenamiento no se puede reclamar cuando se eliminan los archivos. Pero esto, en general, está bien. Tu no?

Entonces, en este punto, la respuesta a su pregunta debe estar completa. ¿Derecho?


Adición:

Veamos qué sucede cuando el almacenamiento de subrayado se llena:

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:~#

¿Qué? parece que tuvo éxito! ¿Cómo ha sido esto posible? ¡Vamos a revisar!

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:~#

Uhm ... se ve bien. ¿Estamos seguros?

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

nos hemos quedado sin espacio! Sin ningún error!

Incluso si sería bueno investigar lo que realmente sucedió ... Voy a dejar esto a su curiosidad y / o habilidades de solución de problemas de otros miembros de ServerFault ;-)

¡Que te diviertas!


Por cierto: he probado todo lo anterior, aquí:

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
fuente
Noté que tienes que ser root para que esos comandos funcionen. ¿Es ese siempre el caso de los archivos dispersos?
Merc
No lo siento. También deberían funcionar como usuarios normales, dado el permiso de escritura adecuado en la carpeta principal.
Damiano Verzulli
Gracias por esta gran respuesta. Me deja con una pregunta y una preocupación. Preocupación: ¿pretender haber escrito con éxito ese segundo archivo de 2GB cuando realmente no había espacio para él? Problemática ... ¿Qué sucede cuando intentas leerlo de nuevo (con sha1sum o algo así)? Pregunta: ¿Hay formas de hacer una copia de seguridad de un archivo disperso en la red que lo mantiene disperso (es decir, solo copia las partes que se utilizan)?
Thilo
Estuve tentado a investigar más, pero ... desafortunadamente tenía poco tiempo y, de hecho, definitivamente es un espacio válido para otra pregunta de SF diferente. De todos modos, se puede evitar fácilmente al no realizar una reserva excesiva de su almacenamiento general: quiero decir, puede crear archivos dispersos pero ... para tener el espacio máximo total asignable en su disco físico. Tu no? Si, en cambio, está buscando soluciones de "overbooking" ... entonces tal vez debería investigarse algo más (¿LVM?)
Damiano Verzulli
@Thilo También tengo curiosidad por saber qué sucedería si intentaras leer el archivo que silenciosamente se desborda. rsynctiene una --sparseopción que debería crear archivos dispersos en el disco de destino.
localhost