<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>devicemapper &amp;mdash; Cyberdyne Systems</title>
    <link>https://noblogo.org/aytin/tag:devicemapper</link>
    <description>&#34;Fare o non fare. Non c&#39;è provare!&#34;</description>
    <pubDate>Thu, 30 Apr 2026 06:56:35 +0000</pubDate>
    <item>
      <title>Ridimensionare volumi LVM</title>
      <link>https://noblogo.org/aytin/ridimensionare-volumi-lvm</link>
      <description>&lt;![CDATA[lvm&#xA;Supponiamo di avere 3 volumi logici, ad es. vol1, vol2, vol3 e di voler aumentare il secondo a discapito degli altri due.&#xA;&#xA;Un’esigenza analoga, su un filesystem partizionato in 3 parti in maniera canonica, è un mezzo incubo perché il ridimensionamento della partizione centrale prevede un discreto numero di salti mortali per manenere la contiguità e per non rischiare di lasciare buchetti inutilizzabili fra una partizione e l’altra. &#xA;!--more--&#xA;&#xA;1. Cose che è bene ricordare quando si manipolano i volumi logici&#xA;2. Scenario 1: Estensione e riduzione di volumi logici&#xA;   2.1. Step 0: curiosità&#xA;   2.2. Step 1: Smontare i dischi&#xA;   2.3. Step 2: Riduzione del filesystem&#xA;   2.4. Step 3: Ridimensionare i volumi logici&#xA;   2.5. Step 4: Estendere il volume logico&#xA;   2.6. Step 5: Bonus&#xA;3. Scenario 2: Estensione e riduzione di gruppi di volume&#xA;4. Conclusione&#xA;&#xA;Provo a buttare giù due righe su quello che mi verrebbe di fare:&#xA;&#xA;riduco la prima partizione&#xA;riduco la terza partizione&#xA;sposto la terza partizione fino alla fine del disco&#xA;sposto la seconda partizione fino alla fine della prima partizione&#xA;estendo la seconda partizione fino alla fine della prima&#xA;&#xA;Tutto questo tenendo presente che l’unità minima allocabile è il blocco (512 bytes) e che l’operazione che mi fa più paura è il move della partizione. parted non ha un comando “move” diretto. La procedura richiede di calcolare i nuovi settori, spostare i dati e aggiornare la tabella delle partizioni.&#xA;&#xA;Senza una GUI come quella di gparted, bisogna farsi letteralmente i conti con carta e penna prima di agire e c’è il rischio, comunque molto alto, di commettere errori che sarebbero disastrosi.&#xA;&#xA;LVM, al confronto, è una boccata d’ossigeno.&#xA;&#xA;LVM dà la possibilità di ridimensionare volumi in maniera più semplice rispetto al partizionamento più tradizionale perché la dimensione della partizione è disaccoppiata da concetti di contiguità e dalla geometria del disco.&#xA;&#xA;Nel caso del partizionamento tradizionale infatti le partizioni sono dei blocchi di settori consecutivi in cui ogni partizione inizia in un settore finisce in un altro.&#xA;&#xA;Con LVM invece l’approccio è radicalmente diverso. La minima unità allocabile è l’extent (default 4 MiB) che serve per mappare un volume fisico in un volume logico.&#xA;&#xA;Se immaginiamo che il volume fisico possa essere spezzettato in altrettanti extents in una sorta di “paniere”, il volume group, il volume logico non è altro che un insieme di questi extents pescati dal volume group (senza alcuna pretesa d’ordinamento) a cui posso:&#xA;&#xA;aggiungere extents prelevandoli dal volume group&#xA;levare extents riponendoli nel volume group (o assegnandoli ad altri volumi logici).&#xA;&#xA;Queste proprietà conferiscono una grande flessibilità alle operazioni di riduzione ed estensione dei volumi.&#xA;&#xA;1. Cose che è bene ricordare quando si manipolano i volumi logici.&#xA;&#xA;Partizioni&#xA;Quando si riduce o aumenta un filesystem, è bene smontare le partizioni e volumi logici.&#xA;&#xA;Ridurre un volume logico&#xA;Quando si riduce un volume logico, si deve:&#xA;&#xA;fare un check del filesystem&#xA;ridurre il filesystem&#xA;ridurre il volume logico&#xA;&#xA;Estendere un volume logico&#xA;Quando si aumenta un volume logico, al contrario, si deve:&#xA;&#xA;estendere il volume logico&#xA;estendere il filesystem&#xA;fare un check del filesystem&#xA;&#xA;Calcolare lo spazio allocabile&#xA;Un volume logico è composto da un insieme di extents, blocchi grandi di default 4 MiB, che sono la minima unità allocabile. Un volume logico è quindi sempre corrispondente ad un multiplo di 4 MiB, n extents di cui n\-1 allocabili, il rimanente per i metadati. Ad es. un volume logico di 2 GiB è composta da 512 extents di cui 511 allocabili.&#xA;&#xA;La potenza di due&#xA;Si deve tenere sempre presente che, nella matematica del calcolo dello spazio, si considerano le potenze di 2. Non di 10. Quindi un GiB equivale a 1024 MiB, non a 1000. Di conseguenza, se dividessi un GiB in due parti uguali avrei 2 blocchi da 512 MiB non da 500.&#xA;&#xA;Estensione e riduzione&#xA;Nelle istruzioni di estensione (lvextend) e riduzione (lvreduce) possiamo scegliere ciò che va specificato fra 4 modalità:&#xA;&#xA;il numero totale di extents&#xA;il delta in aggiunta o in diminuzione degli extents (a seconde che l’operazione sia rispettivamente di estensione o di riduzione)&#xA;la dimensione totale espressa in KiB-MiB-GiB-TiB&#xA;come prima, il delta in aggiunta o in diminuzione della dimensione espresso in KiB-MiB-GiB-TiB&#xA;&#xA;2. Scenario 1: Estensione e riduzione di volumi logici&#xA;Supponiamo di avere un disco da 2 GiB (2048 MiB) diviso in 3 volumi logici da 550 MiB, 350 MiB e 1148 MiB di e di volerne ridurre due per ampliare il terzo.&#xA;&#xA;Vogliamo ridurre il primo di 150 MiB, il terzo di 330 MiB e aumentare corrispondentemente il secondo volume di 480 MiB.&#xA;&#xA;Prepariamo il laboratorio col solito file appiccicato ad un loop device. Su quello definirò il volume group, il mio “paniere” di extents.&#xA;creazione device&#xA;fallocate -l 2GiB disk1.img&#xA;&#xA;creazione device e volum group&#xA;vgcreate vglab $(losetup -Pf --show disk1.img)&#xA;&#xA;creazione volumi logici&#xA;lvcreate -n lvlab1 vglab -L 550M&#xA;lvcreate -n lvlab2 vglab -L 350M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;formattazione volumi logici&#xA;mkfs.ext4 /dev/vglab/lvlab1&#xA;mkfs.ext4 /dev/vglab/lvlab2&#xA;mkfs.ext4 /dev/vglab/lvlab3&#xA;&#xA;mount dei volumi&#xA;mkdir vol1 vol2 vol3&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab1 vol1&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab2 vol2&#xA;mount -t ext4 -o defaults /dev/vglab/lvlab3 vol3&#xA;2.1. Step 0: curiosità&#xA;Prima di cominciare esaminiamo un po’ di dati, ad es. di quanti extents sono composti i nostri oggetti.&#xA;pvdisplay /dev/loop9&#xA;  --- Physical volume ---&#xA;  PV Name               /dev/loop9&#xA;  VG Name               vglab&#xA;  PV Size               2,00 GiB / not usable 4,00 MiB&#xA;  Allocatable           yes (but full)&#xA;  PE Size               4,00 MiB&#xA;  Total PE              511&#xA;  Free PE               0&#xA;  Allocated PE          511&#xA;  PV UUID               YmLOru-bIdL-iqGb-vJfI-RsTk-yhv7-vSJhkX&#xA;pvdisplay mi dà informazioni sul disco fisico che andrò ad aggiungere nel volume group. Fra queste:&#xA;&#xA;PV Name: il nome del device, /dev/loop9&#xA;VG Name: è il nome del gruppo di volume, vglab, visibile solo perché abbiamo creato il gruppo di volume direttamente sul dispositivo invece che passare prima da pvcreate.&#xA;PV Size: 2 GiB, la dimensione del nostro “disco”&#xA;PE Size: dove PE sta Physical Extent, è di 4 MiB&#xA;Total PE sono i PE totali e sono 511, come previsto.&#xA;&#xA;vgdisplay vglab&#xA;  --- Volume group ---&#xA;  VG Name               vglab&#xA;  System ID&#xA;  Format                lvm2&#xA;  Metadata Areas        1&#xA;  Metadata Sequence No  1&#xA;  VG Access             read/write&#xA;  VG Status             resizable&#xA;  MAX LV                0&#xA;  Cur LV                0&#xA;  Open LV               0&#xA;  Max PV                0&#xA;  Cur PV                1&#xA;  Act PV                1&#xA;  VG Size               &lt;2,00 GiB&#xA;  PE Size               4,00 MiB&#xA;  Total PE              511&#xA;  Alloc PE / Size       0 / 0&#xA;  Free  PE / Size       511 / &lt;2,00 GiB&#xA;  VG UUID               6D89ck-c2Ni-XlMN-5Was-rh5j-vi2t-5juCXt&#xA;vgdisplay mi dà informazioni sul gruppo di volumi. Fra queste, disitnguiamo&#xA;&#xA;VG Name: il nome del volume group, già visto in pvdisplay, vglab&#xA;VG Size: la dimensione del volume group, minore di 2 GiB perché ci sono i metadati da considerari&#xA;PE Size: la dimensione di un extent, 4 MiB&#xA;Total PE / Size: Il numero totale di extent allocabili, che conferma VG Size, pari a 511 invece che 512.&#xA;Alloc PE: il numero totale di extent allocati, momento della creazione del volume group è 0&#xA;Free PE / Size: il numero totale di extent liberi, prima della creazione dei volumi logici è 511&#xA;&#xA;Cosa succede quando creerò i volumi logici? Che cambia il numero di PE liberi e allocati. Siccome userò tutti gli extent disponibili, i valori per Alloc PE e Free PE si invertiranno rispetto a prima.&#xA;&#xA;Infatti dopo la creazione dei volumi logici, vgdisplay mi dirà:&#xA;vgdisplay vglab&#xA;  --- Volume group ---&#xA;  VG Name               vglab&#xA;  ...&#xA;  Alloc PE / Size       511 / &lt;2,00 GiB&#xA;  Free  PE / Size       0 / 0&#xA;  ...  &#xA;511 extents allocati come confermato dai dati desumibili dei 3 volumi logici&#xA;lvdisplay vglab&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab1&#xA;  LV Name                lvlab1&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                552,00 MiB&#xA;  Current LE             138&#xA;...&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab2&#xA;  LV Name                lvlab2&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                352,00 MiB&#xA;  Current LE             88&#xA;...&#xA; --- Logical volume ---&#xA;  LV Path                /dev/vglab/lvlab3&#xA;  LV Name                lvlab2&#xA;  VG Name                vglab&#xA;...&#xA;  LV Size                1,11 GiB&#xA;  Current LE             285&#xA;...&#xA;Per il primo, il secondo e il terzo volume logico abbiamo rispettivamente:&#xA;&#xA;138, 88, 285 extents corrispondenti a&#xA;552 MiB, 352 MiB e 1140 MiB (1,11 GiB)&#xA;per un totale di 2044 MiB, al netto dei metadati.&#xA;&#xA;Possiamo notare subito che le dimensioni non corrispondono a quanto indicato in lvcreate.&#xA;lvcreate -n lvlab1 vglab -L 550M&#xA;lvcreate -n lvlab2 vglab -L 350M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questo succede perché vengono sempre approssimate all’extent più vicino. Ecco perché il primo e il secondo volume sono diventati di 552 (138 extents) e 352 MiB (88 extents).&#xA;&#xA;Sempre ricordando la particolarità dei multipli di 4 MiB legati a LVM, anche la riduzione di 150 MiB e di 330 MiB dei due volumi saranno approssimate sempre all’extent più vicino (152 MiB=38 extents e 332=83 extents). Questo dettaglio si rivelerà fondamentale quando dovremo ridimensionare il filesystem.&#xA;&#xA;Con questa rinnovata consapevolezza cominciamo a ridimensionare.&#xA;2.2. Step 1: Smontare i dischi&#xA;umount /dev/vglab/lvlab1&#xA;umount /dev/vglab/lvlab2&#xA;umount /dev/vglab/lvlab3&#xA;2.3. Step 2: Riduzione del filesystem&#xA;Se dovessi ridimensionare solo il filesystem, sarebbe sufficiente considerare dimensioni che siano potenze di 2 e non di 10.&#xA;&#xA;Ma sapendo che sotto c’è un LVM, sappiamo che per mantenere l’allineamento fra filesystem e volumi logici, oltre che potenze di due le dimensioni devono essere anche multipli di 4MiB.&#xA;&#xA;Ecco perché anche nel resize reale del filesystem non dovrò levare 150 MiB e 330 MiB ma 148 MiB (37 PE) e 328 (82 PE) (è buona norma approssimare per difetto all’extent più vicino per maggior prudenza) per un totale effettivo di 476 MiB (119 PE)&#xA;&#xA;Il filesystem del primo volume sarà dunque di 552 MiB - 148 MiB = 404 MiB. Il filesystem del terzo volume sarà di 1140 MiB - 328 MiB = 812 MiB.&#xA;check dei filesystem&#xA;e2fsck -f /dev/vglab/lvlab1&#xA;e2fsck -f /dev/vglab/lvlab2&#xA;e2fsck -f /dev/vglab/lvlab3&#xA;&#xA;Riduco il primo filesystem di 148 MiB&#xA;resize2fs /dev/vglab/lvlab1 404M&#xA;&#xA;Riduco il terzo filesystem di 328 MiB&#xA;resize2fs /dev/vglab/lvlab3 812M&#xA;2.4. Step 3: Ridimensionare i volumi logici&#xA;La riduzione del volume logico può essere fatta in 4 modi come sappiamo, ad es. sul primo volume:&#xA;il numero totale di extents, 138 PE - 37 PE = 101 PE&#xA;lvreduce -l 101 /dev/vglab/lvlab1 #oppure&#xA;&#xA;il numero di exrtents da sottrarre, 38 PE&#xA;lvreduce -l -37 /dev/vglab/lvlab1 #oppure&#xA;&#xA;la dimensione totale da ottenere, 404 MiB&#xA;lvreduce -L 404M /dev/vglab/lvlab1 #oppure&#xA;&#xA;il numero di MiB da sottrarre, 148 MiB&#xA;lvreduce -L -148M /dev/vglab/lvlab1 #oppure&#xA;Per maggior chiarezza userò il size assoluto in modo da farlo corrispondere a resize2fs&#xA;Riduco il primo volume logico di 148 Mib&#xA;lvreduce -L 404M /dev/vglab/lvlab1&#xA;&#xA;Riduco il terzo volume logico di 328 Mib&#xA;lvreduce -L 812M /dev/vglab/lvlab3&#xA;Verifichiamo quanti siano i PE residui&#xA;vgdisplay vglab | grep &#34;Free  PE&#34;&#xA; Free  PE / Size       119 / 476,00 MiB&#xA;119 extents, come previsto.&#xA;2.5. Step 4: Estendere il volume logico&#xA;Dopo aver ridotto il primo e il terzo volume, non ci rimane che estendere il secondo in base alla scaletta indicata prima:&#xA;&#xA;si estende il secondo volume logico&#xA;si estende il filesystem&#xA;si esegue il check fnale del filesystem&#xA;&#xA;L’estensione del volume, come ormai ben sappiamo, non sarà di 480 MiB ma di 476 MiB (37 PE + 82 PE = 119 PE) per via degli arrotondamenti effettuati nella riduzione degli altri volumi logici.&#xA;specifico gli extent che so essere residui&#xA;lvextend -l +119 /dev/vglab/lvlab2&#xA;o, equivalentemente&#xA;lvextend -L +476M /dev/vglab/lvlab2&#xA;&#xA;estendo il filesystem&#xA;resize2fs /dev/vglab/lvlab2 828M&#xA;&#xA;check filesystem&#xA;e2fsck -f /dev/vglab/lvlab2&#xA;2.6. Step 5: Bonus&#xA;Come premio per essere arrivato in fondo, posso rivelare come fare in un colpo solo tutte le operazioni descritte sopra.&#xA;&#xA;È vero che c&#39;è poco da considerare, giusto tenere a mente che su LVM ogni oggetto è multiplo di 4 MiB e che bisogna ridimensionare filesystem e volumi logici in ugual modo per non generare pericolose anomalie, ma tutte le operazioni che ho descritto nei passi 2-4 possono essere fatte con un unico comando che provvederà ad eseguire nell&#39;ordine corretto e con le giuste approssimazioni:&#xA;&#xA;il check del filesystem&#xA;il ridimensionamento del filesystem&#xA;il ridimensionamento dei volumi logici&#xA;&#xA;Dunque, tutto il pippone atomico precedente può essere condensato in un unico, solido comando:&#xA;Riduce il primo volume logico e il filesystem&#xA;lvreduce -r -L -150M /dev/vglab/lvlab1&#xA;&#xA;Riduce il terzo volume logico e il filesystem&#xA;lvreduce -r -L -330M /dev/vglab/lvlab3&#xA;&#xA;Estende il secondo volume logico e il filesystem&#xA;lvextend -r -l +119 /dev/vglab/lvlab2&#xA;Ora spieghiamo il perché soprattutto dell&#39;extend, che è interessante.&#xA;&#xA;Diciamo che è tutto molto guidato e le eventuali correzioni da apportare, senza spaccarsi troppo il cervello, sono suggerite con estrema chiarezza, basta leggere.&#xA;lvreduce -r -L -150M /dev/vglab/lvlab1&#xA; Rounding size to boundary between physical extents: 148.00 MiB.&#xA;  File system ext4 found on vglab/lvlab1.&#xA;  File system size (552.00 MiB) is larger than the requested size (404.00 MiB).&#xA;  File system reduce is required using resize2fs.&#xA;...&#xA;  Size of logical volume vglab/lvlab1 changed from 552.00 MiB (138 extents) to 404.00 MiB (101 extents).&#xA;  Logical volume vglab/lvlab1 successfully resized.&#xA;Ci dice innanzitutto che:&#xA;&#xA;c&#39;è stato un arrotondamento a 148 MiB (37 extents);&#xA;il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;&#xA;infine si ridimensiona il volume logico da 552 MiB (138 extents) a 404 MiB (101 extents).&#xA;&#xA;Anche il secondo lvreduce ha un risultato analogo&#xA;lvreduce -r -L -330M /dev/vglab/lvlab3&#xA;  Rounding size to boundary between physical extents: 328.00 MiB.&#xA;  File system ext4 found on vglab/lvlab3.&#xA;  File system size (1.11 GiB) is larger than the requested size (812.00 MiB).&#xA;  File system reduce is required using resize2fs.&#xA;...&#xA;  Size of logical volume vglab/lvlab3 changed from 1.11 GiB (285 extents) to 812.00 MiB (203 extents).&#xA;  Logical volume vglab/lvlab3 successfully resized.&#xA;&#xA;anche qui abbiamo un arrotondamento a 328 MiB (82 extents);&#xA;il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;&#xA;infine si ridimensiona il volume logico da 1140 MiB (285 extents) a 812 MiB (203 extents).&#xA;&#xA;È facilissimo desumere che la massima dimensione dell&#39;estensione sia 148 MiB + 328 MiB = 476 MiB (119 extents), basta fare una somma.&#xA;&#xA;Ma supponiamo di essere particolarmente distratti e proviamo ad estendere considerando le quantità iniziali: 150 MiB + 330 MiB = 480 MiB&#xA;lvextend -r -L +480M /dev/vglab/lvlab2&#xA;  File system ext4 found on vglab/lvlab2.&#xA;  File system fsck will be run before extend.&#xA;  Insufficient free space: 120 extents needed, but only 119 available&#xA;Nonostante la mia distrazione, come si può vedere, non si producono danni perché l&#39;ouput è categorico: &#34;non faccio nulla. Se vuoi, puoi aumentare al max di 476 MiB (119 extents)&#34;.&#xA;Non ci sono danni e anzi c&#39;è pure il suggerimento risolutivo.&#xA;&#xA;Ed ecco spiegato il mio extend di prima.&#xA;3. Scenario 2: Estensione e riduzione di gruppi di volume&#xA;Esaminiamo le possibilità di aggiungere o rimuovere dispositivi ad un volume group esistente.&#xA;&#xA;Ricreiamo il laboratorio partendo da 3 dischi, poi aggiungeremo due nuovi dischi e ne rimuoveremo altrettanti, il tutto senza intaccare l&#39;integrità dei dati.&#xA;&#xA;creazione di 5 device&#xA;for i in {1..9}: do fallocate -l 1GiB disk${i}.img; done&#xA;&#xA;creazione del gruppo di volumi con 3 device&#xA;vgcreate vglab \&#xA;  $(losetup -Pf --show disk1.img) \&#xA;  $(losetup -Pf --show disk2.img) \&#xA;  $(losetup -Pf --show disk3.img)&#xA;&#xA;crezione di 3 volumi logici&#xA;lvcreate -n lvlab1 vglab -l 300&#xA;lvcreate -n lvlab2 vglab -l 250&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;formattazione dei 3 dispositivi&#xA;mkfs.ext4 /dev/vglab/lvlab1&#xA;mkfs.ext4 /dev/vglab/lvlab2&#xA;mkfs.ext4 /dev/vglab/lvlab3&#xA;Ecco come sono distribuiti i volumi logici all&#39;interno dei dischi fisici&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;Il gruppo di volumi è composto da 3 volumi fisici tutti attivi&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                3&#xA;  Act PV                3&#xA;Andiamo ad estendere il nostro gurppo di volumi con altri due device&#xA;vgextend vglab $(losetup -Pf --show disk4.img) $(losetup -Pf --show disk5.img)&#xA;I nuovi dischi sono visibili in fondo, come si può vedere anche da  vgdisplay che mostra i 5 dischi tutti attivi. &#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvmchan&#xA;  loop12             LVM2member     1G      loop&#xA;  loop13             LVM2member     1G      loop&#xA;&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                5&#xA;  Act PV                5&#xA;Potremo usare i nuovi dischi per estendere i volumi logici esistenti ma li impiegheremo invece per rimpiazzare i primi due dischi. &#xA;&#xA;pvmove distribuisce tutti gli extents del disco fra tutti i volumi fisici che hanno spazio a sufficienza. Se non dovesse essercene, restituirà un messaggio d&#39;errore.&#xA;pvmove /dev/loop9&#xA;  /dev/loop9: Moved: 3,14%&#xA;  /dev/loop9: Moved: 100,00%&#xA;Alla fine dell&#39;operazione il disco s&#39;è liberato di tutti i suoi extents e può essere rimosso&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9              LVM2member     1G      loop&#xA;  loop10             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop12             LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop13             LVM2member     1G      loop&#xA;Prima si estrae il volume fisico dal gruppo di volumi e poi si rimuove il volume fisico e così può essere scollegato.&#xA;vgreduce vglab /dev/loop9&#xA;pvremove /dev/loop9&#xA;Verifichiamo che il volume fisico non sia più presente.&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                4&#xA;  Act PV                4&#xA;Procediamo allo stesso modo col secondo disco.&#xA;pvmove /dev/loop10&#xA;  /dev/loop10: Moved: 9,80%&#xA;  /dev/loop10: Moved: 17,65%&#xA;  /dev/loop10: Moved: 100,00%&#xA;&#xA;vgreduce vglab /dev/loop10&#xA;  Removed &#34;/dev/loop10&#34; from volume group &#34;vglab&#34;&#xA;&#xA;pvremove /dev/loop10&#xA;  Labels on physical volume &#34;/dev/loop10&#34; successfully wiped.&#xA;In conclusione possiamo vedere il gruppo di volumi con solo 3 dischi, gli altri due completamente disimpegnati col gruppo di volumi ricostituitosi attorno ai 3 dischi rimanenti. E tutto spostando semplicemente gli extents dove c&#39;era disponibilità in maniera totalmente trasparente per il filesystem.&#xA;vgdisplay vglab |grep PV&#xA;  Max PV                0&#xA;  Cur PV                3&#xA;  Act PV                3&#xA;&#xA;lsblk -o NAME,FSTYPE,SIZE,TYPE&#xA;  NAME               FSTYPE        SIZE      TYPE&#xA;  loop9                              1G      loop&#xA;  loop10                             1G      loop&#xA;  loop11             LVM2member     1G      loop&#xA;  ├─vglab-lvlab2               1000M      lvm&#xA;  └─vglab-lvlab3                860M      lvm&#xA;  loop12             LVM2member     1G      loop&#xA;  └─vglab-lvlab1                1,2G      lvm&#xA;  loop13             LVM2member     1G      loop&#xA;  ├─vglab-lvlab1                1,2G      lvm&#xA;  └─vglab-lvlab_3                860M      lvm&#xA;4. Conclusione&#xA;Ho solo sfiorato la complessità e le capacità offerte da LVM.&#xA;&#xA;L&#39;estensione e la riduzione di volumi logici e di gruppi di volumi sono scenari di base. Tuttavia sono sufficienti per mostrare come sia semplice, con i volumi logici, compiere operazioni che con un filesystem partizionato in maniera classica sarebbero complicatissime.&#xA;&#xA;#lvm #volumegroup #logicalvolume #filesystem #devicemapper]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/31410d826-759a86/YynFD6sqFGzb/E2tgEVkaEtWT6Ucn0rqMrtk9qnJlr5p9nLl9m5pu.jpg" alt="lvm">
Supponiamo di avere 3 volumi logici, ad es. vol1, vol2, vol3 e di voler aumentare il secondo a discapito degli altri due.</p>

<p>Un’esigenza analoga, su un filesystem partizionato in 3 parti in maniera canonica, è un mezzo incubo perché il ridimensionamento della partizione centrale prevede un discreto numero di salti mortali per manenere la contiguità e per non rischiare di lasciare buchetti inutilizzabili fra una partizione e l’altra.
</p>
<ul><li><a href="#1-cose-che-%C3%A8-bene-ricordare-quando-si-manipolano-i-volumi-logici" rel="nofollow">1. Cose che è bene ricordare quando si manipolano i volumi logici</a></li>
<li><a href="#2-scenario-1-estensione-e-riduzione-di-volumi-logici" rel="nofollow">2. Scenario 1: Estensione e riduzione di volumi logici</a>
<ul><li><a href="#2-1-step-0-curiosit%C3%A0" rel="nofollow">2.1. Step 0: curiosità</a></li>
<li><a href="#2-2-step-1-smontare-i-dischi" rel="nofollow">2.2. Step 1: Smontare i dischi</a></li>
<li><a href="#2-3-step-2-riduzione-del-filesystem" rel="nofollow">2.3. Step 2: Riduzione del filesystem</a></li>
<li><a href="#2-4-step-3-ridimensionare-i-volumi-logici" rel="nofollow">2.4. Step 3: Ridimensionare i volumi logici</a></li>
<li><a href="#2-5-step-4-estendere-il-volume-logico" rel="nofollow">2.5. Step 4: Estendere il volume logico</a></li>
<li><a href="#2-6-step-5-bonus" rel="nofollow">2.6. Step 5: Bonus</a></li></ul></li>
<li><a href="#3-scenario-2-estensione-e-riduzione-di-gruppi-di-volume" rel="nofollow">3. Scenario 2: Estensione e riduzione di gruppi di volume</a></li>
<li><a href="#4-conclusione" rel="nofollow">4. Conclusione</a></li></ul>

<p>Provo a buttare giù due righe su quello che mi verrebbe di fare:</p>
<ol><li>riduco la prima partizione</li>
<li>riduco la terza partizione</li>
<li>sposto la terza partizione fino alla fine del disco</li>
<li>sposto la seconda partizione fino alla fine della prima partizione</li>
<li>estendo la seconda partizione fino alla fine della prima</li></ol>

<p>Tutto questo tenendo presente che l’unità minima allocabile è il blocco (512 bytes) e che l’operazione che mi fa più paura è il move della partizione. <code>parted</code> non ha un comando “move” diretto. La procedura richiede di calcolare i nuovi settori, spostare i dati e aggiornare la tabella delle partizioni.</p>

<p>Senza una GUI come quella di <strong>gparted</strong>, bisogna farsi letteralmente i conti con carta e penna prima di agire e c’è il rischio, comunque molto alto, di commettere errori che sarebbero disastrosi.</p>

<p>LVM, al confronto, è una boccata d’ossigeno.</p>

<p>LVM dà la possibilità di ridimensionare volumi in maniera più semplice rispetto al partizionamento più tradizionale perché la dimensione della partizione è disaccoppiata da concetti di contiguità e dalla geometria del disco.</p>

<p>Nel caso del partizionamento tradizionale infatti le partizioni sono dei blocchi di settori consecutivi in cui ogni partizione inizia in un settore finisce in un altro.</p>

<p>Con LVM invece l’approccio è radicalmente diverso. La minima unità allocabile è l’<strong>extent</strong> (default 4 MiB) che serve per mappare un volume fisico in un volume logico.</p>

<p>Se immaginiamo che il volume fisico possa essere spezzettato in altrettanti extents in una sorta di “paniere”, il <strong>volume group</strong>, il volume logico non è altro che un insieme di questi extents pescati dal volume group (senza alcuna pretesa d’ordinamento) a cui posso:</p>
<ul><li>aggiungere extents prelevandoli dal volume group</li>
<li>levare extents riponendoli nel volume group (o assegnandoli ad altri volumi logici).</li></ul>

<p>Queste proprietà conferiscono una grande flessibilità alle operazioni di riduzione ed estensione dei volumi.</p>

<h2 id="1-cose-che-è-bene-ricordare-quando-si-manipolano-i-volumi-logici">1. Cose che è bene ricordare quando si manipolano i volumi logici.</h2>

<p><strong>Partizioni</strong>
Quando si riduce o aumenta un filesystem, è bene smontare le partizioni e volumi logici.</p>

<p><strong>Ridurre un volume logico</strong>
Quando si riduce un volume logico, si deve:</p>
<ol><li>fare un check del filesystem</li>
<li>ridurre il filesystem</li>
<li>ridurre il volume logico</li></ol>

<p><strong>Estendere un volume logico</strong>
Quando si aumenta un volume logico, al contrario, si deve:</p>
<ol><li>estendere il volume logico</li>
<li>estendere il filesystem</li>
<li>fare un check del filesystem</li></ol>

<p><strong>Calcolare lo spazio allocabile</strong>
Un volume logico è composto da un <strong>insieme di extents</strong>, blocchi grandi di default 4 MiB, che sono la minima unità allocabile. Un volume logico è quindi <strong>sempre</strong> corrispondente ad un multiplo di 4 MiB, <em>n</em> extents di cui <em>n</em>-1 allocabili, il rimanente per i metadati. Ad es. un volume logico di 2 GiB è composta da 512 extents di cui <strong>511 allocabili</strong>.</p>

<p><strong>La potenza di due</strong>
Si deve tenere <strong>sempre</strong> presente che, nella matematica del calcolo dello spazio, si considerano le potenze di 2. Non di 10. Quindi un GiB equivale a 1024 MiB, non a 1000. Di conseguenza, se dividessi un GiB in due parti uguali avrei 2 blocchi da 512 MiB non da 500.</p>

<p><strong>Estensione e riduzione</strong>
Nelle istruzioni di estensione (<strong>lvextend</strong>) e riduzione (<strong>lvreduce</strong>) possiamo scegliere ciò che va specificato fra 4 modalità:</p>
<ol><li>il <strong>numero totale</strong> di extents</li>
<li>il <strong>delta</strong> in aggiunta o in diminuzione degli extents (a seconde che l’operazione sia rispettivamente di estensione o di riduzione)</li>
<li>la dimensione totale espressa in KiB-MiB-GiB-TiB</li>
<li>come prima, il delta in aggiunta o in diminuzione della dimensione espresso in KiB-MiB-GiB-TiB</li></ol>

<h2 id="2-scenario-1-estensione-e-riduzione-di-volumi-logici">2. Scenario 1: Estensione e riduzione di volumi logici</h2>

<p>Supponiamo di avere un disco da 2 GiB (2048 MiB) diviso in 3 volumi logici da <strong>550 MiB</strong>, <strong>350 MiB</strong> e <strong>1148 MiB</strong> di e di volerne ridurre due per ampliare il terzo.</p>

<p>Vogliamo ridurre il primo di <strong>150 MiB</strong>, il terzo di <strong>330 MiB</strong> e aumentare corrispondentemente il secondo volume di <strong>480 MiB</strong>.</p>

<p>Prepariamo il laboratorio col solito file appiccicato ad un loop device. Su quello definirò il volume group, il mio “paniere” di extents.</p>

<pre><code class="language-bash"># creazione device
fallocate -l 2GiB disk_1.img

# creazione device e volum group
vgcreate vg_lab $(losetup -Pf --show disk_1.img)

# creazione volumi logici
lvcreate -n lv_lab_1 vg_lab -L 550M
lvcreate -n lv_lab_2 vg_lab -L 350M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# formattazione volumi logici
mkfs.ext4 /dev/vg_lab/lv_lab_1
mkfs.ext4 /dev/vg_lab/lv_lab_2
mkfs.ext4 /dev/vg_lab/lv_lab_3

# mount dei volumi
mkdir vol_1 vol_2 vol_3
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_1 vol_1
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_2 vol_2
mount -t ext4 -o defaults /dev/vg_lab/lv_lab_3 vol_3
</code></pre>

<h3 id="2-1-step-0-curiosità">2.1. Step 0: curiosità</h3>

<p>Prima di cominciare esaminiamo un po’ di dati, ad es. di quanti extents sono composti i nostri oggetti.</p>

<pre><code class="language-bash">pvdisplay /dev/loop9
  --- Physical volume ---
  PV Name               /dev/loop9
  VG Name               vg_lab
  PV Size               2,00 GiB / not usable 4,00 MiB
  Allocatable           yes (but full)
  PE Size               4,00 MiB
  Total PE              511
  Free PE               0
  Allocated PE          511
  PV UUID               YmLOru-bIdL-iqGb-vJfI-RsTk-yhv7-vSJhkX
</code></pre>

<p><code>pvdisplay</code> mi dà informazioni sul disco fisico che andrò ad aggiungere nel volume group. Fra queste:</p>
<ul><li><strong>PV Name</strong>: il nome del device, <strong>/dev/loop9</strong></li>
<li><strong>VG Name</strong>: è il nome del gruppo di volume, <strong>vg_lab</strong>, visibile solo perché abbiamo creato il gruppo di volume direttamente sul dispositivo invece che passare prima da <strong>pvcreate</strong>.</li>
<li><strong>PV Size</strong>: 2 GiB, la dimensione del nostro “disco”</li>
<li><strong>PE Size</strong>: dove <strong>PE</strong> sta <strong>P</strong>hysical <strong>E</strong>xtent, è di 4 MiB</li>
<li><strong>Total PE</strong> sono i PE totali e sono <strong>511</strong>, come previsto.</li></ul>

<pre><code class="language-bash">vgdisplay vg_lab
  --- Volume group ---
  VG Name               vg_lab
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               &lt;2,00 GiB
  PE Size               4,00 MiB
  Total PE              511
  Alloc PE / Size       0 / 0
  Free  PE / Size       511 / &lt;2,00 GiB
  VG UUID               6D89ck-c2Ni-XlMN-5Was-rh5j-vi2t-5juCXt
</code></pre>

<p><code>vgdisplay</code> mi dà informazioni sul gruppo di volumi. Fra queste, disitnguiamo</p>
<ul><li><strong>VG Name</strong>: il nome del volume group, già visto in <code>pvdisplay</code>, <strong>vg_lab</strong></li>
<li><strong>VG Size</strong>: la dimensione del volume group, minore di 2 GiB perché ci sono i metadati da considerari</li>
<li><strong>PE Size</strong>: la dimensione di un extent, 4 MiB</li>
<li><strong>Total PE / Size</strong>: Il numero totale di extent allocabili, che conferma <strong>VG Size</strong>, pari a <strong>511</strong> invece che <strong>512</strong>.</li>
<li><strong>Alloc PE</strong>: il numero totale di extent allocati, momento della creazione del volume group è <strong>0</strong></li>
<li><strong>Free PE / Size</strong>: il numero totale di extent liberi, prima della creazione dei volumi logici è <strong>511</strong></li></ul>

<p>Cosa succede quando creerò i volumi logici? Che cambia il numero di PE liberi e allocati. Siccome userò tutti gli extent disponibili, i valori per <code>Alloc PE</code> e <code>Free PE</code> si invertiranno rispetto a prima.</p>

<p>Infatti dopo la creazione dei volumi logici, <code>vgdisplay</code> mi dirà:</p>

<pre><code class="language-bash">vgdisplay vg_lab
  --- Volume group ---
  VG Name               vg_lab
  ...
  Alloc PE / Size       511 / &lt;2,00 GiB
  Free  PE / Size       0 / 0
  ...  
</code></pre>

<p><strong>511 extents</strong> allocati come confermato dai dati desumibili dei 3 volumi logici</p>

<pre><code class="language-bash">lvdisplay vg_lab
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_1
  LV Name                lv_lab_1
  VG Name                vg_lab
...
  LV Size                552,00 MiB
  Current LE             138
...
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_2
  LV Name                lv_lab_2
  VG Name                vg_lab
...
  LV Size                352,00 MiB
  Current LE             88
...
 --- Logical volume ---
  LV Path                /dev/vg_lab/lv_lab_3
  LV Name                lv_lab_2
  VG Name                vg_lab
...
  LV Size                1,11 GiB
  Current LE             285
...
</code></pre>

<p>Per il primo, il secondo e il terzo volume logico abbiamo rispettivamente:</p>
<ul><li><strong>138, 88, 285 extents</strong> corrispondenti a</li>
<li><strong>552 MiB, 352 MiB e 1140 MiB (1,11 GiB)</strong></li>
<li>per un totale di <strong>2044 MiB</strong>, al netto dei metadati.</li></ul>

<p>Possiamo notare subito che le dimensioni non corrispondono a quanto indicato in <code>lvcreate</code>.</p>

<pre><code class="language-bash">lvcreate -n lv_lab_1 vg_lab -L 550M
lvcreate -n lv_lab_2 vg_lab -L 350M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questo succede perché vengono <strong>sempre</strong> approssimate all’extent più vicino. Ecco perché il primo e il secondo volume sono diventati di <strong>552</strong> (138 extents) e <strong>352 MiB</strong> (88 extents).</p>

<p>Sempre ricordando la particolarità dei multipli di 4 MiB legati a LVM, anche la riduzione di 150 MiB e di 330 MiB dei due volumi saranno approssimate sempre all’extent più vicino (<strong>152 MiB=38 extents</strong> e <strong>332=83 extents</strong>). Questo dettaglio si rivelerà fondamentale quando dovremo ridimensionare il filesystem.</p>

<p>Con questa rinnovata consapevolezza cominciamo a ridimensionare.</p>

<h3 id="2-2-step-1-smontare-i-dischi">2.2. Step 1: Smontare i dischi</h3>

<pre><code class="language-bash">umount /dev/vg_lab/lv_lab_1
umount /dev/vg_lab/lv_lab_2
umount /dev/vg_lab/lv_lab_3
</code></pre>

<h3 id="2-3-step-2-riduzione-del-filesystem">2.3. Step 2: Riduzione del filesystem</h3>

<p>Se dovessi ridimensionare solo il filesystem, sarebbe sufficiente considerare dimensioni che siano potenze di 2 e non di 10.</p>

<p>Ma sapendo che sotto c’è un LVM, sappiamo che per mantenere l’allineamento fra filesystem e volumi logici, oltre che potenze di due le dimensioni devono essere anche multipli di 4MiB.</p>

<p>Ecco perché <strong>anche</strong> nel resize reale del filesystem non dovrò levare <strong>150 MiB</strong> e <strong>330 MiB</strong> ma <strong>148 MiB (37 PE)</strong> e <strong>328 (82 PE)</strong> (è buona norma approssimare per difetto all’extent più vicino per maggior prudenza) per un totale effettivo di <strong>476 MiB (119 PE)</strong></p>

<p>Il filesystem del primo volume sarà dunque di <em>552 MiB – 148 MiB = 404 MiB</em>. Il filesystem del terzo volume sarà di <em>1140 MiB – 328 MiB = 812 MiB</em>.</p>

<pre><code class="language-bash"># check dei filesystem
e2fsck -f /dev/vg_lab/lv_lab_1
e2fsck -f /dev/vg_lab/lv_lab_2
e2fsck -f /dev/vg_lab/lv_lab_3

# Riduco il primo filesystem di 148 MiB
resize2fs /dev/vg_lab/lv_lab_1 404M

# Riduco il terzo filesystem di 328 MiB
resize2fs /dev/vg_lab/lv_lab_3 812M
</code></pre>

<h3 id="2-4-step-3-ridimensionare-i-volumi-logici">2.4. Step 3: Ridimensionare i volumi logici</h3>

<p>La riduzione del volume logico può essere fatta in 4 modi come sappiamo, ad es. sul primo volume:</p>

<pre><code class="language-bash"># il numero totale di extents, 138 PE - 37 PE = 101 PE
lvreduce -l 101 /dev/vg_lab/lv_lab_1 #oppure

# il numero di exrtents da sottrarre, 38 PE
lvreduce -l -37 /dev/vg_lab/lv_lab_1 #oppure

# la dimensione totale da ottenere, 404 MiB
lvreduce -L 404M /dev/vg_lab/lv_lab_1 #oppure

# il numero di MiB da sottrarre, 148 MiB
lvreduce -L -148M /dev/vg_lab/lv_lab_1 #oppure
</code></pre>

<p>Per maggior chiarezza userò il size assoluto in modo da farlo corrispondere a <code>resize2fs</code></p>

<pre><code class="language-bash"># Riduco il primo volume logico di 148 Mib
lvreduce -L 404M /dev/vg_lab/lv_lab_1

# Riduco il terzo volume logico di 328 Mib
lvreduce -L 812M /dev/vg_lab/lv_lab_3
</code></pre>

<p>Verifichiamo quanti siano i PE residui</p>

<pre><code class="language-bash">vgdisplay vg_lab | grep &#34;Free  PE&#34;
 Free  PE / Size       119 / 476,00 MiB
</code></pre>

<p>119 extents, come previsto.</p>

<h3 id="2-5-step-4-estendere-il-volume-logico">2.5. Step 4: Estendere il volume logico</h3>

<p>Dopo aver ridotto il primo e il terzo volume, non ci rimane che estendere il secondo in base alla scaletta indicata prima:</p>
<ol><li>si estende il secondo volume logico</li>
<li>si estende il filesystem</li>
<li>si esegue il check fnale del filesystem</li></ol>

<p>L’estensione del volume, come ormai ben sappiamo, non sarà di <strong>480 MiB</strong> ma di <strong>476 MiB (37 PE + 82 PE = 119 PE)</strong> per via degli arrotondamenti effettuati nella riduzione degli altri volumi logici.</p>

<pre><code class="language-bash"># specifico gli extent che so essere residui
lvextend -l +119 /dev/vg_lab/lv_lab_2
# o, equivalentemente
# lvextend -L +476M /dev/vg_lab/lv_lab_2

# estendo il filesystem
resize2fs /dev/vg_lab/lv_lab_2 828M

# check filesystem
e2fsck -f /dev/vg_lab/lv_lab_2
</code></pre>

<h3 id="2-6-step-5-bonus">2.6. Step 5: Bonus</h3>

<p>Come premio per essere arrivato in fondo, posso rivelare come fare in un colpo solo tutte le operazioni descritte sopra.</p>

<p>È vero che c&#39;è poco da considerare, giusto tenere a mente che su LVM ogni oggetto è multiplo di 4 MiB e che bisogna ridimensionare filesystem e volumi logici in ugual modo per non generare pericolose anomalie, ma tutte le operazioni che ho descritto nei passi 2-4 possono essere fatte con un unico comando che provvederà ad eseguire nell&#39;ordine corretto e con le giuste approssimazioni:</p>
<ul><li>il check del filesystem</li>
<li>il ridimensionamento del filesystem</li>
<li>il ridimensionamento dei volumi logici</li></ul>

<p>Dunque, tutto il pippone atomico precedente può essere condensato in un unico, solido comando:</p>

<pre><code class="language-bash"># Riduce il primo volume logico e il filesystem
lvreduce -r -L -150M /dev/vg_lab/lv_lab_1

# Riduce il terzo volume logico e il filesystem
lvreduce -r -L -330M /dev/vg_lab/lv_lab_3

# Estende il secondo volume logico e il filesystem
lvextend -r -l +119 /dev/vg_lab/lv_lab_2
</code></pre>

<p>Ora spieghiamo il perché soprattutto dell&#39;extend, che è interessante.</p>

<p>Diciamo che è tutto molto guidato e le eventuali correzioni da apportare, senza spaccarsi troppo il cervello, sono suggerite con estrema chiarezza, basta leggere.</p>

<pre><code class="language-bash">lvreduce -r -L -150M /dev/vg_lab/lv_lab_1
 Rounding size to boundary between physical extents: 148.00 MiB.
  File system ext4 found on vg_lab/lv_lab_1.
  File system size (552.00 MiB) is larger than the requested size (404.00 MiB).
  File system reduce is required using resize2fs.
...
  Size of logical volume vg_lab/lv_lab_1 changed from 552.00 MiB (138 extents) to 404.00 MiB (101 extents).
  Logical volume vg_lab/lv_lab_1 successfully resized.
</code></pre>

<p>Ci dice innanzitutto che:</p>
<ul><li>c&#39;è stato un arrotondamento a <strong>148 MiB (37 extents)</strong>;</li>
<li>il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;</li>
<li>infine si ridimensiona il volume logico da <strong>552 MiB (138 extents)</strong> a <strong>404 MiB (101 extents)</strong>.</li></ul>

<p>Anche il secondo <code>lvreduce</code> ha un risultato analogo</p>

<pre><code class="language-bash">lvreduce -r -L -330M /dev/vg_lab/lv_lab_3
  Rounding size to boundary between physical extents: 328.00 MiB.
  File system ext4 found on vg_lab/lv_lab_3.
  File system size (1.11 GiB) is larger than the requested size (812.00 MiB).
  File system reduce is required using resize2fs.
...
  Size of logical volume vg_lab/lv_lab_3 changed from 1.11 GiB (285 extents) to 812.00 MiB (203 extents).
  Logical volume vg_lab/lv_lab_3 successfully resized.
</code></pre>
<ul><li>anche qui abbiamo un arrotondamento a <strong>328 MiB (82 extents)</strong>;</li>
<li>il filesystem è più grande del volume richiesto pertanto va subito ridimensionato;</li>
<li>infine si ridimensiona il volume logico da <strong>1140 MiB (285 extents)</strong> a <strong>812 MiB (203 extents)</strong>.</li></ul>

<p>È facilissimo desumere che la massima dimensione dell&#39;estensione sia <strong>148 MiB + 328 MiB = 476 MiB (119 extents)</strong>, basta fare una somma.</p>

<p>Ma supponiamo di essere particolarmente distratti e proviamo ad estendere considerando le quantità iniziali: 150 MiB + 330 MiB = <strong>480 MiB</strong></p>

<pre><code class="language-bash">lvextend -r -L +480M /dev/vg_lab/lv_lab_2
  File system ext4 found on vg_lab/lv_lab_2.
  File system fsck will be run before extend.
  Insufficient free space: 120 extents needed, but only 119 available
</code></pre>

<p>Nonostante la mia distrazione, come si può vedere, non si producono danni perché l&#39;ouput è categorico: “non faccio nulla. Se vuoi, puoi aumentare al max di 476 MiB (119 extents)”.
Non ci sono danni e anzi c&#39;è pure il suggerimento risolutivo.</p>

<p>Ed ecco spiegato il mio extend di prima.</p>

<h2 id="3-scenario-2-estensione-e-riduzione-di-gruppi-di-volume">3. Scenario 2: Estensione e riduzione di gruppi di volume</h2>

<p>Esaminiamo le possibilità di aggiungere o rimuovere dispositivi ad un volume group esistente.</p>

<p>Ricreiamo il laboratorio partendo da 3 dischi, poi aggiungeremo due nuovi dischi e ne rimuoveremo altrettanti, il tutto senza intaccare l&#39;integrità dei dati.</p>

<pre><code class="language-bash"># creazione di 5 device
for i in {1..9}: do fallocate -l 1GiB disk_${i}.img; done

# creazione del gruppo di volumi con 3 device
vgcreate vg_lab \
  $(losetup -Pf --show disk_1.img) \
  $(losetup -Pf --show disk_2.img) \
  $(losetup -Pf --show disk_3.img)

# crezione di 3 volumi logici
lvcreate -n lv_lab_1 vg_lab -l 300
lvcreate -n lv_lab_2 vg_lab -l 250
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# formattazione dei 3 dispositivi
mkfs.ext4 /dev/vg_lab/lv_lab_1
mkfs.ext4 /dev/vg_lab/lv_lab_2
mkfs.ext4 /dev/vg_lab/lv_lab_3
</code></pre>

<p>Ecco come sono distribuiti i volumi logici all&#39;interno dei dischi fisici</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
</code></pre>

<p>Il gruppo di volumi è composto da 3 volumi fisici tutti attivi</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                3
  Act PV                3
</code></pre>

<p>Andiamo ad estendere il nostro gurppo di volumi con altri due device</p>

<pre><code class="language-bash">vgextend vg_lab $(losetup -Pf --show disk_4.img) $(losetup -Pf --show disk_5.img)
</code></pre>

<p>I nuovi dischi sono visibili in fondo, come si può vedere anche da  <code>vgdisplay</code> che mostra i 5 dischi tutti attivi.</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvmchan
  loop12             LVM2_member     1G      loop
  loop13             LVM2_member     1G      loop

vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                5
  Act PV                5
</code></pre>

<p>Potremo usare i nuovi dischi per estendere i volumi logici esistenti ma li impiegheremo invece per rimpiazzare i primi due dischi.</p>

<p><code>pvmove</code> distribuisce tutti gli extents del disco fra tutti i volumi fisici che hanno spazio a sufficienza. Se non dovesse essercene, restituirà un messaggio d&#39;errore.</p>

<pre><code class="language-bash">pvmove /dev/loop9
  /dev/loop9: Moved: 3,14%
  /dev/loop9: Moved: 100,00%
</code></pre>

<p>Alla fine dell&#39;operazione il disco s&#39;è liberato di tutti i suoi extents e può essere rimosso</p>

<pre><code class="language-bash">lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9              LVM2_member     1G      loop
  loop10             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop12             LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop13             LVM2_member     1G      loop
</code></pre>

<p>Prima si estrae il volume fisico dal gruppo di volumi e poi si rimuove il volume fisico e così può essere scollegato.</p>

<pre><code class="language-bash">vgreduce vg_lab /dev/loop9
pvremove /dev/loop9
</code></pre>

<p>Verifichiamo che il volume fisico non sia più presente.</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                4
  Act PV                4
</code></pre>

<p>Procediamo allo stesso modo col secondo disco.</p>

<pre><code class="language-bash">pvmove /dev/loop10
  /dev/loop10: Moved: 9,80%
  /dev/loop10: Moved: 17,65%
  /dev/loop10: Moved: 100,00%

vgreduce vg_lab /dev/loop10
  Removed &#34;/dev/loop10&#34; from volume group &#34;vg_lab&#34;

pvremove /dev/loop10
  Labels on physical volume &#34;/dev/loop10&#34; successfully wiped.
</code></pre>

<p>In conclusione possiamo vedere il gruppo di volumi con solo 3 dischi, gli altri due completamente disimpegnati col gruppo di volumi ricostituitosi attorno ai 3 dischi rimanenti. E tutto spostando semplicemente gli extents dove c&#39;era disponibilità in maniera totalmente trasparente per il filesystem.</p>

<pre><code class="language-bash">vgdisplay vg_lab |grep PV
  Max PV                0
  Cur PV                3
  Act PV                3


lsblk -o NAME,FSTYPE,SIZE,TYPE
  NAME               FSTYPE        SIZE      TYPE
  loop9                              1G      loop
  loop10                             1G      loop
  loop11             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_2               1000M      lvm
  └─vg_lab-lv_lab_3                860M      lvm
  loop12             LVM2_member     1G      loop
  └─vg_lab-lv_lab_1                1,2G      lvm
  loop13             LVM2_member     1G      loop
  ├─vg_lab-lv_lab_1                1,2G      lvm
  └─vg_lab-lv_lab_3                860M      lvm
</code></pre>

<h2 id="4-conclusione">4. Conclusione</h2>

<p>Ho solo sfiorato la complessità e le capacità offerte da LVM.</p>

<p>L&#39;estensione e la riduzione di volumi logici e di gruppi di volumi sono scenari di base. Tuttavia sono sufficienti per mostrare come sia semplice, con i volumi logici, compiere operazioni che con un filesystem partizionato in maniera classica sarebbero complicatissime.</p>

<p><a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:volumegroup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">volumegroup</span></a> <a href="/aytin/tag:logicalvolume" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">logicalvolume</span></a> <a href="/aytin/tag:filesystem" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">filesystem</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/ridimensionare-volumi-lvm</guid>
      <pubDate>Mon, 20 Apr 2026 21:13:18 +0000</pubDate>
    </item>
    <item>
      <title>Device Mapper: LUKS + LVM</title>
      <link>https://noblogo.org/aytin/device-mapper-luks-lvm</link>
      <description>&lt;![CDATA[luks-lvm&#xA;(segue da &#34;Cenni sulla creazione di pool di storage con LVM&#34;)&#xA;...anche se è la base per una serie di sviluppi interessanti. &#xA;&#xA;Come ormai sappiamo, device mapper è il framework del kernel Linux col quale mappare dispositivi a blocchi fisici su dispositivi a blocchi logici, che costituisce la base per fornire funzionalità ulteriori quali:&#xA;!--more--&#xA;&#xA;volumi logici&#xA;raid&#xA;cifratura (Full Disk Encryption)&#xA;snapshot di volumi&#xA;&#xA;Scenario 1&#xA;È molto comune per es. cifrare l&#39;intero disco e &#34;affettarlo&#34; con volumi logici in base alle proprie esigenze di partizionamento .&#xA;&#xA;Il doppio vantaggio è dato da:&#xA;&#xA;offuscamento totale dello schema di partizionamento&#xA;estrema versatilità / flessibilità del partizionamento grazie ai volumi logici &#xA;&#xA;Come si agisce?&#xA;&#xA;si cifra il dispositivo fisico&#xA;si crea un gruppo di volumi avente come volume fisico il volume cifrato&#xA;si creano i volumi logici in base allo schema di partizionamento desiderato.&#xA;&#xA;luks-lvm&#xA;Passo 1 - Inizializzazione&#xA;Simulo il mio dispositivo fisico ricorrendo ai loop device.&#xA;&#xA;Il &#34;disco&#34; avrà una grandezza simbolica di 2 GiB, non avrà header detachable. L&#39;algoritmo di hash sarà sha512 e la chiave sarà da 512 bit. Il resto è il default di luks2 (argon2id come pbkdf, per maggiori dettagli vedi cryptsetup --help)&#xA;1. Preparazione disco &#34;fisico&#34;&#xA;fallocate -l 2g cipherdisk.img&#xA;&#xA;2. loop device che simula l&#39;attach del dispositivo&#xA;DEV=$(losetup -Pf --show cipherdisk.img)&#xA;&#xA;3. Inizializzazione cifratura&#xA;cryptsetup luksFormat  \&#xA;    --type luks2 \&#xA;    --hash sha512 \&#xA;    --key-size 512 \&#xA;    $DEV&#xA;Passo 2&#xA;Il passo successivo consiste nell&#39;apertura del dispositivo cifrato e nella definizione dello schema di partizionamento in volumi logici&#xA;1. apertura del disco cifrato&#xA;cryptsetup open \&#xA;    --type luks2 \&#xA;    $DEV cipherdisk&#xA;Nell&#39;apertura, device mapper fa la sua prima magia.&#xA;&#xA;Infatti, se osserviamo lo stato dei dispositivi, vedremo una situazione simile:&#xA;lsblk&#xA;...&#xA;loop9                7:9    Kib0     2G  0 loop  &#xA;└─cipherdisk      252:3    0     2G  0 crypt &#xA;...&#xA;Cio vuol dire che sopra il dispositivo fisico, /dev/loop9 in questo caso, device mapper ha &#34;poggiato&#34; cipherdisk (/dev/mapper/cipherdisk).&#xA;&#xA;Questo sarà il nostro volume fisico per definire gruppi di volume e, conseguentemente, i volumi logici.&#xA;2. creazione gruppo di volumi&#xA;vgcreate vglab /dev/mapper/cipherdisk&#xA;&#xA;3. creazione volumi logici&#xA;lvcreate -n lvlab1 vglab -L 700M&#xA;lvcreate -n lvlab2 vglab -L 600M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;La situazione dei dispositivi è ora questa:&#xA;lsblk&#xA;...&#xA;loop9                7:9    0     2G  0 loop  &#xA;└─cipherdisk      252:3    0     2G  0 crypt&#xA;  ├─vglab-lvlab1 252:4    0   700M  0 lvm&#xA;  ├─vglab-lvlab2 252:5    0   600M  0 lvm&#xA;  └─vglab-lvlab3 252:6    0   728M  0 lvm&#xA;...&#xA;Sopra /dev/loop9 c&#39;è cipherdisk (/dev/mapper/cipherdisk) e sopra di esso, i 3 volumi logici&#xA;&#xA;lvlab1 (/dev/mapper/vglab-lvlab1)&#xA;lvlab2 (/dev/mapper/vglab-lvlab2)&#xA;lvlab3 (/dev/mapper/vglab-lvlab3)&#xA;&#xA;Formatto e monto i volumi logici&#xA;4. formattazione dei 3 volumi logici&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab1&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab2&#xA;mkfs.ext4 /dev/mapper/vglab-lvlab3&#xA;&#xA;5. creo e preparo i punti di mmontaggio&#xA;mkdir disk1 disk2 disk3&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab1 disk1&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab2 disk2&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab3 disk3&#xA;chown $USER disk1 disk2 disk3&#xA;&#xA;6. unmount di tutti i dispositivi&#xA;umount disk1 disk2 disk3&#xA;vgchange -an vglab&#xA;cryptsetup close cipherdisk&#xA;losetup -d $DEV&#xA;Passo 3&#xA;Infine, per completezza, gli script di mount e unmount del dispositivo.&#xA;mount&#xA;1. attach del dispositivo&#xA;DEV=$(losetup -Pf --show cipherdisk.img)&#xA;&#xA;2. Apre il disco cifrato &#xA;cryptsetup open \&#xA;    --type luks2 \&#xA;    $DEV cipherdisk&#xA;&#xA;3. monta il gruppo di volume&#xA;(opzionale. L&#39;apertura del disco cifrato dovrebbe montare &#xA;automaticamente il gruppo di volumi)&#xA;vgchange -ay vglab&#xA;&#xA;4. monta i volumi logici&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab1 disk1&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab2 disk2&#xA;mount -t ext4 -o user,noauto,rw  /dev/mapper/vglab-lvlab3 disk3&#xA;unmount&#xA;1. smonta i 3 dischi&#xA;umount disk1 disk2 disk3&#xA;&#xA;2. smonta il gruppo di volumi&#xA;vgchange -an vglab&#xA;&#xA;3. chiude il disco cifrato&#xA;cryptsetup close cipherdisk&#xA;&#xA;4. &#34;stacca&#34; il dispositivo fisico&#xA;losetup -d $DEV&#xA;&#xA;Questo è ciò che si farebbe normalmente quando si vuole il full disk encryption sul proprio pc. Ma con una piccola eccezione.&#xA;&#xA;In realtà ciò che viene cifrata è una partizione quasi completa del disco, perché almeno una piccola partizione, quella contenente il boot, /BOOT, deve essere in chiaro per consentire:&#xA;&#xA;a UEFI di avviare GRUB che conosce le partizioni,&#xA;GRUB provvederà all&#39;avvio del kernel,&#xA;l&#39;avvio del kernel con initramfs chiederà la password per sbloccare la partizione cifrata.&#xA;&#xA;La cifratura totale (che proprio totale non sarà perché /boot/efi deve rimanere in chiaro) eleva di molto la complessità del setup iniziale.&#xA;&#xA;Affidare a GRUB la gestione della cifratura potrebbe voler dire, oltre alla complessità della configurazione iniziale che dovrà far ricorso a moduli come cryptodisk, che bisognerà rinunciare ad Argon2 perché GRUB ancora non lo supporta pienamente e, a differenza del kernel, non ha sufficiente potenza per farlo lavorare come si deve.&#xA;&#xA;Un buon compromesso potrebbe essere il ricorso ad un dispositivo esterno, es. una pendrive, che contenga tutta la partizione /boot in chiaro, anche  l&#39;header del disco cifrato.&#xA;GRUB dovrà solo sapere dove si trovi il boot, il resto dell&#39;avvio viene affidato come di consueto al kernel.&#xA;Scenario 2&#xA;Rimanendo nell&#39;ambito dell&#39;esplorazione di device mapper e della cifratura di dispositivi esterni non avviabili, immaginiamo qualcosa di più estremo.&#xA;&#xA;Supponiamo di dover custodire un segreto in qualcosa che non sia un semplice vault cifrato.&#xA;&#xA;Per diminuire il rischio di compromettere un unico vault, decido di dividerlo in varie parti, come gli horcrux ma con 0 malignità. Ogni parte sarà cifrata con una sua chiave che affiderò ad una persona diversa, di mia fiducia. Solo io, titolare ultimo del segreto, avrò accesso ai dati e solo la mia chiave (come l&#39;Anello che li domina tutti) aprirà il vault.&#xA;&#xA;Supponiamo di avere 3 dispositivi fisici (che nel laboratoro saranno simulati da loop device come al solito) per altrettanti &#34;custodi&#34;, ognuno dei quali verrà cifrato con la chiave e con dei parametri da consegnare al &#34;custode&#34; specifico.&#xA;&#xA;I 3 dispositivi cifrati costituiranno un gruppo di volumi con un volume logico (dai requisiti posti non c&#39;è necessità di sfruttare la flessibilità di partizionamento dei volumi logici) che verrà cifrato con la mia chiave master.&#xA;&#xA;luks-lvm-luks&#xA;&#x9;&#xA;Ogni dispositivo, volume logico finale compreso, prima della cifratura, verrà inizializzato con del rumore casuale. Questo per impedire ad un&#39;analisi forense di risalire ad un qualunque pattern sul dispositivo raw.&#xA;&#xA;Caratteristiche di ogni cifratura:&#xA;&#xA;dispositivi inizializzati con rumore casuale&#xA;header detachable&#xA;offset custom&#xA;key-file&#xA;default di argon2id (controlla il tuo default con cryptsetup benchmark)&#xA;&#xA;Quando vorrò aprire il vault, sarà necessario che i 3 &#34;custodi&#34; aprano il loro &#34;pezzo&#34; e solo io potrò ricostruire e decifrare il volume con la mia chiave.&#xA;&#xA;L&#39;inzializzazione con rumore casuale dei dispositivo, tralasciando l&#39;uso di dd su /dev/urandom che sappiamo essere CPU-intensive, può essere fatta ricorrendo:&#xA;&#xA;ad openssl rand, come sappiamo da &#34;Come generare una password o un keyfile sicuri (Trilogia Della Password – 1 di 3&#34;&#xA;oppure usando furbescamente cryptsetup, con cui apriamo il dispositivo in modalità plain, senza header, e riempiendolo di zeri (da /dev/zero con dd) che, attraversando il motore di cifratura, verranno scritti sul dispositivo come dati casuali ad alta velocità.&#xA;&#xA;################################&#xA;Emulazione dei device fisici &#xA;################################&#xA;fallocate -l 512M cipherdisk1.img&#xA;fallocate -l 512M cipherdisk2.img&#xA;fallocate -l 512M cipherdisk3.img&#xA;&#xA;###########################&#xA;creazione dei 3 keyfile &#xA;###########################&#xA;keyfile del custode n° 1&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk1.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile del custode n° 2&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk2.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile del custode n° 3&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o cipherdisk3.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;keyfile master&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o master.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;&#xA;##########################&#xA;cifratura dei 3 device &#xA;##########################&#xA;attach dispositivo&#xA;DEV1=$(losetup -Pf --show cipherdisk1.img)&#xA;&#xA;inizializzazione dev1 con rumore casuale&#xA;cryptsetup open --type plain ${DEV1} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header1.img \&#xA;        --offset 32768 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV1}&#xA;&#xA;attach dispositivo&#xA;DEV2=$(losetup -Pf --show cipherdisk2.img)&#xA;&#xA;inizializzazione dev2 con rumore casuale&#xA;cryptsetup open --type plain ${DEV2} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header2.img \&#xA;        --offset 36864 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV2}&#xA;&#xA;attach dispositivo&#xA;DEV3=$(losetup -Pf --show cipherdisk3.img)&#xA;&#xA;inizializzazione dev3 con rumore casuale&#xA;cryptsetup open --type plain ${DEV3} container --key-file /dev/urandom&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;cifratura dispositivo n° 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header3.img \&#xA;        --offset 40960 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        ${DEV3}&#xA;&#xA;##############################&#xA;Creazione gruppo di volumi &#xA;##############################&#xA;&#34;apro&#34; il volume 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header1.img \&#xA;         --key-file - \&#xA;         ${DEV1} cipherdisk1&#xA;&#xA;&#34;apro&#34; il volume 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header2.img \&#xA;         --key-file - \&#xA;         ${DEV2} cipherdisk2&#xA;&#xA;&#34;apro&#34; il volume 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header3.img \&#xA;         --key-file - \&#xA;         ${DEV3} cipherdisk3&#xA;&#xA;Creo il mio gruppo di volumi con i 3 volumi &#34;fisici&#34;:&#xA;1. /dev/mapper/cipherdisk1&#xA;2. /dev/mapper/cipherdisk2&#xA;3. /dev/mapper/cipherdisk3&#xA;vgcreate vgmaster /dev/mapper/cipherdisk1  /dev/mapper/cipherdisk2  /dev/mapper/cipherdisk3&#xA;&#xA;creazione dell&#39;unico volume logico&#xA;lvcreate -n lvmaster vgmaster -l 100%FREE&#xA;&#xA;################################&#xA;cifratura e mount del master &#xA;################################&#xA;cifratura dispositivo master&#xA;dd if=/dev/urandom of=/dev/mapper/vgmaster-lvmaster bs=1M count=32 status=progress&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup luksFormat  \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header headermaster.img \&#xA;&#x9;&#x9;--offset 65536 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        /dev/mapper/vgmaster-lvmaster&#xA;&#xA;apriamo il dispositivo master&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header headermaster.img \&#xA;         --key-file - \&#xA;         /dev/mapper/vgmaster-lvmaster cipherdiskmaster&#xA;&#xA;e finalmente lo formattiamo&#xA;mkfs.ext4 /dev/mapper/cipherdiskmaster&#xA;&#xA;Test: montiamo il disco&#xA;mkdir -p /run/media/master/diskmaster&#xA;chown -R ${USER}:${USER} /run/media/master/diskmaster&#xA;mount -t auto /dev/mapper/cipherdiskmaster /run/media/master/diskmaster&#xA;&#xA;Infine chiudiamo tutto&#xA;umount /run/media/master/diskmaster&#xA;cryptsetup close cipherdiskmaster&#xA;vgchange -an vgmaster&#xA;cryptsetup close cipherdisk1&#xA;cryptsetup close cipherdisk2&#xA;cryptsetup close cipherdisk3&#xA;losetup -d ${DEV1} ${DEV2} ${DEV3}&#xA;Dopo aver appurato che tutto funzioni, consegno ad ogni &#34;custode&#34; dispositivo, keyfile e header.&#xA;&#xA;Se un attaccante dovesse entrare in possesso di uno o più dispositivi, troverebbe solo un mucchio di dati incomprensibili.&#xA;&#xA;Posto che riuscisse a decifrare il dispositivo, troverebbe un pezzo di un gruppo di volumi, cifrato e inutilizzabile.&#xA;&#xA;Il master a questo punto non dovrà fare altro che aprire e chiudere il vault, dopo aver riunito tutti i pezzi, come segue:&#xA;&#xA;Apertura del vault&#xA;Attach dei dispositivi&#xA;DEV1=$(losetup -Pf --show cipherdisk1.img)&#xA;DEV2=$(losetup -Pf --show cipherdisk2.img)&#xA;DEV3=$(losetup -Pf --show cipherdisk3.img)&#xA;&#xA;&#34;apro&#34; il volume 1&#xA;gpg -d cipherdisk1.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header1.img \&#xA;         --key-file - \&#xA;         ${DEV1} cipherdisk1&#xA;&#xA;&#34;apro&#34; il volume 2&#xA;gpg -d cipherdisk2.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header2.img \&#xA;         --key-file - \&#xA;         ${DEV2} cipherdisk2&#xA;&#xA;&#34;apro&#34; il volume 3&#xA;gpg -d cipherdisk3.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header header3.img \&#xA;         --key-file - \&#xA;         ${DEV3} cipherdisk3&#xA;&#xA;(facoltativo) apre il gruppo di volumi&#xA;vgchange -ay vgmaster&#xA;&#xA;&#34;apre&#34; il master volume&#xA;gpg -d master.key.gpg | \&#xA;    cryptsetup open \&#xA;         --type luks2 \&#xA;         --header headermaster.img \&#xA;         --key-file - \&#xA;         /dev/mapper/vgmaster-lvmaster cipherdiskmaster&#xA;&#xA;Monta il volume&#xA;mount -t auto /dev/mapper/cipherdiskmaster /run/media/master/diskmaster&#xA;Chiusura del vault&#xA;smonta il volume cifrato&#xA;umount /run/media/master/diskmaster&#xA;&#xA;chiusura del vault master&#xA;cryptsetup close cipherdiskmaster&#xA;&#xA;chiusura del gruppo di volumi&#xA;vgchange -an vgmaster&#xA;&#xA;chiusura dei singoli vault cifrati&#xA;cryptsetup close cipherdisk1&#xA;cryptsetup close cipherdisk2&#xA;cryptsetup close cipherdisk3&#xA;&#xA;deattach dei dispositivi&#xA;losetup -d ${DEV1} ${DEV2} ${DEV3}&#xA;&#xA;#cryptsetup #devicemapper #dmcrypt #gpg #loseup #luks #lvm #loopdevice #storage]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/JqVu1t3agiao/CSE9exMSdTVlv9adGCHXwSbkxvn9EPD0SPJNIsQo.jpg" alt="luks-lvm">
<em>(segue da <a href="https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm/" rel="nofollow">“<strong>Cenni sulla creazione di pool di storage con LVM</strong>“</a>)</em>
...anche se è la base per una serie di sviluppi interessanti.</p>

<p>Come ormai sappiamo, <strong>device mapper</strong> è il framework del kernel Linux col quale mappare dispositivi a blocchi fisici su dispositivi a blocchi logici, che costituisce la base per fornire funzionalità ulteriori quali:
</p>
<ul><li>volumi logici</li>
<li>raid</li>
<li>cifratura (<strong>F</strong>ull <strong>D</strong>isk <strong>E</strong>ncryption)</li>
<li>snapshot di volumi</li></ul>

<h2 id="scenario-1">Scenario 1</h2>

<p>È molto comune per es. cifrare l&#39;intero disco e “affettarlo” con volumi logici in base alle proprie esigenze di partizionamento .</p>

<p>Il doppio vantaggio è dato da:</p>
<ol><li>offuscamento totale dello schema di partizionamento</li>
<li>estrema versatilità / flessibilità del partizionamento grazie ai volumi logici</li></ol>

<p>Come si agisce?</p>
<ol><li>si cifra il dispositivo fisico</li>
<li>si crea un gruppo di volumi avente come volume fisico il volume cifrato</li>
<li>si creano i volumi logici in base allo <strong>schema di partizionamento</strong> desiderato.</li></ol>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/e9tSS2DIxi6F/Bc8zWpFAR2KxQSK92F6I3Z6ocbA5E67bT3ziz1Ke.jpg" alt="luks-lvm"></p>

<h3 id="passo-1-inizializzazione">Passo 1 – Inizializzazione</h3>

<p>Simulo il mio dispositivo fisico ricorrendo ai <strong>loop device</strong>.</p>

<p>Il “disco” avrà una grandezza simbolica di 2 GiB, non avrà header detachable. L&#39;algoritmo di hash sarà sha512 e la chiave sarà da 512 bit. Il resto è il default di luks2 (argon2id come pbkdf, per maggiori dettagli vedi <code>cryptsetup --help</code>)</p>

<pre><code class="language-bash"># 1. Preparazione disco &#34;fisico&#34;
fallocate -l 2g cipher_disk.img

# 2. loop device che simula l&#39;attach del dispositivo
DEV=$(losetup -Pf --show cipher_disk.img)

# 3. Inizializzazione cifratura
cryptsetup luksFormat  \
    --type luks2 \
    --hash sha512 \
    --key-size 512 \
    $DEV
</code></pre>

<h3 id="passo-2">Passo 2</h3>

<p>Il passo successivo consiste nell&#39;apertura del dispositivo cifrato e nella definizione dello schema di partizionamento in volumi logici</p>

<pre><code class="language-bash"># 1. apertura del disco cifrato
cryptsetup open \
    --type luks2 \
    $DEV cipher_disk
</code></pre>

<p>Nell&#39;apertura, device mapper fa la sua prima magia.</p>

<p>Infatti, se osserviamo lo stato dei dispositivi, vedremo una situazione simile:</p>

<pre><code>lsblk
...
loop9                7:9    Kib0     2G  0 loop  
└─cipher_disk      252:3    0     2G  0 crypt 
...
</code></pre>

<p>Cio vuol dire che sopra il dispositivo fisico, <code>/dev/loop9</code>in questo caso, device mapper ha “poggiato” <strong>cipher_disk</strong> (<code>/dev/mapper/cipher_disk</code>).</p>

<p>Questo sarà il nostro volume fisico per definire gruppi di volume e, conseguentemente, i volumi logici.</p>

<pre><code class="language-bash"># 2. creazione gruppo di volumi
vgcreate vg_lab /dev/mapper/cipher_disk

# 3. creazione volumi logici
lvcreate -n lv_lab_1 vg_lab -L 700M
lvcreate -n lv_lab_2 vg_lab -L 600M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>La situazione dei dispositivi è ora questa:</p>

<pre><code>lsblk
...
loop9                7:9    0     2G  0 loop  
└─cipher_disk      252:3    0     2G  0 crypt
  ├─vg_lab-lv_lab_1 252:4    0   700M  0 lvm
  ├─vg_lab-lv_lab_2 252:5    0   600M  0 lvm
  └─vg_lab-lv_lab_3 252:6    0   728M  0 lvm
...
</code></pre>

<p>Sopra <code>/dev/loop9</code> c&#39;è <code>cipher_disk</code> (<code>/dev/mapper/cipher_disk</code>) e sopra di esso, i 3 volumi logici</p>
<ul><li><code>lv_lab_1</code> (<code>/dev/mapper/vg_lab-lv_lab_1</code>)</li>
<li><code>lv_lab_2</code> (<code>/dev/mapper/vg_lab-lv_lab_2</code>)</li>
<li><code>lv_lab_3</code> (<code>/dev/mapper/vg_lab-lv_lab_3</code>)</li></ul>

<p>Formatto e monto i volumi logici</p>

<pre><code class="language-bash"># 4. formattazione dei 3 volumi logici
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_1
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_2
mkfs.ext4 /dev/mapper/vg_lab-lv_lab_3

# 5. creo e preparo i punti di mmontaggio
mkdir disk_1 disk_2 disk_3
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_1 disk_1
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_2 disk_2
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_3 disk_3
chown $USER disk_1 disk_2 disk_3

# 6. unmount di tutti i dispositivi
umount disk_1 disk_2 disk_3
vgchange -an vg_lab
cryptsetup close cipher_disk
losetup -d $DEV
</code></pre>

<h3 id="passo-3">Passo 3</h3>

<p>Infine, per completezza, gli script di mount e unmount del dispositivo.
<strong>mount</strong></p>

<pre><code class="language-bash"># 1. attach del dispositivo
DEV=$(losetup -Pf --show cipher_disk.img)

# 2. Apre il disco cifrato 
cryptsetup open \
    --type luks2 \
    $DEV cipher_disk

# 3. monta il gruppo di volume
# (opzionale. L&#39;apertura del disco cifrato dovrebbe montare 
# automaticamente il gruppo di volumi)
vgchange -ay vg_lab

# 4. monta i volumi logici
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_1 disk_1
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_2 disk_2
mount -t ext4 -o user,noauto,rw  /dev/mapper/vg_lab-lv_lab_3 disk_3
</code></pre>

<p><strong>unmount</strong></p>

<pre><code class="language-bash"># 1. smonta i 3 dischi
umount disk_1 disk_2 disk_3

# 2. smonta il gruppo di volumi
vgchange -an vg_lab

# 3. chiude il disco cifrato
cryptsetup close cipher_disk

# 4. &#34;stacca&#34; il dispositivo fisico
losetup -d $DEV
</code></pre>

<p>Questo è ciò che si farebbe normalmente quando si vuole il full disk encryption sul proprio pc. Ma con una piccola eccezione.</p>

<p>In realtà ciò che viene cifrata è una partizione quasi completa del disco, perché almeno una piccola partizione, quella contenente il boot, <code>/BOOT</code>, deve essere in chiaro per consentire:</p>
<ul><li>a UEFI di avviare GRUB che conosce le partizioni,</li>
<li>GRUB provvederà all&#39;avvio del kernel,</li>
<li>l&#39;avvio del kernel con initramfs chiederà la password per sbloccare la partizione cifrata.</li></ul>

<p>La cifratura totale (che proprio totale non sarà perché <code>/boot/efi</code> deve rimanere in chiaro) eleva di molto la complessità del setup iniziale.</p>

<p>Affidare a GRUB la gestione della cifratura potrebbe voler dire, oltre alla complessità della configurazione iniziale che dovrà far ricorso a moduli come <code>cryptodisk</code>, che bisognerà rinunciare ad Argon2 perché GRUB ancora non lo supporta pienamente e, a differenza del kernel, non ha sufficiente potenza per farlo lavorare come si deve.</p>

<p>Un buon compromesso potrebbe essere il ricorso ad un dispositivo esterno, es. una pendrive, che contenga tutta la partizione <code>/boot</code> in chiaro, anche  l&#39;header del disco cifrato.
GRUB dovrà solo sapere dove si trovi il boot, il resto dell&#39;avvio viene affidato come di consueto al kernel.</p>

<h2 id="scenario-2">Scenario 2</h2>

<p>Rimanendo nell&#39;ambito dell&#39;esplorazione di device mapper e della cifratura di dispositivi esterni non avviabili, immaginiamo qualcosa di più estremo.</p>

<p>Supponiamo di dover custodire un segreto in qualcosa che non sia un semplice vault cifrato.</p>

<p>Per diminuire il rischio di compromettere un unico vault, decido di dividerlo in varie parti, come gli horcrux ma con 0 malignità. Ogni parte sarà cifrata con una sua chiave che affiderò ad una persona diversa, di mia fiducia. Solo io, titolare ultimo del segreto, avrò accesso ai dati e solo la mia chiave (come l&#39;Anello che li domina tutti) aprirà il vault.</p>

<p>Supponiamo di avere 3 dispositivi fisici (che nel laboratoro saranno simulati da loop device come al solito) per altrettanti “custodi”, ognuno dei quali verrà cifrato con la chiave e con dei parametri da consegnare al “custode” specifico.</p>

<p>I 3 dispositivi cifrati costituiranno un gruppo di volumi con un volume logico (dai requisiti posti non c&#39;è necessità di sfruttare la flessibilità di partizionamento dei volumi logici) che verrà cifrato con la mia chiave master.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/fbedcc803-0ec729/pnRafhfUlqts/Wl6xNlvrbnZJIjRVRbAIM0fmo6KZAnYoy1Wga0C2.jpg" alt="luks-lvm-luks"></p>

<p>Ogni dispositivo, volume logico finale compreso, prima della cifratura, verrà inizializzato con del rumore casuale. Questo per impedire ad un&#39;analisi forense di risalire ad un qualunque pattern sul dispositivo raw.</p>

<p>Caratteristiche di ogni cifratura:</p>
<ul><li>dispositivi inizializzati con rumore casuale</li>
<li>header detachable</li>
<li>offset custom</li>
<li>key-file</li>
<li>default di argon2id (controlla il tuo default con <code>cryptsetup benchmark</code>)</li></ul>

<p>Quando vorrò aprire il vault, sarà necessario che i 3 “custodi” aprano il loro “pezzo” e solo io potrò ricostruire e decifrare il volume con la mia chiave.</p>

<p>L&#39;inzializzazione con rumore casuale dei dispositivo, tralasciando l&#39;uso di <code>dd</code> su <code>/dev/urandom</code> che sappiamo essere CPU-intensive, può essere fatta ricorrendo:</p>
<ul><li>ad <code>openssl rand</code>, come sappiamo da <em><a href="https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di/" rel="nofollow">“<strong>Come generare una password o un keyfile sicuri (Trilogia Della Password – 1 di 3</strong>“</a></em></li>
<li>oppure usando furbescamente <strong>cryptsetup</strong>, con cui apriamo il dispositivo in modalità plain, senza header, e riempiendolo di zeri (da <code>/dev/zero</code> con <code>dd</code>) che, attraversando il motore di cifratura, verranno scritti sul dispositivo come dati casuali ad alta velocità.</li></ul>

<pre><code class="language-bash">################################
# Emulazione dei device fisici #
################################
fallocate -l 512M cipher_disk_1.img
fallocate -l 512M cipher_disk_2.img
fallocate -l 512M cipher_disk_3.img



###########################
# creazione dei 3 keyfile #
###########################
# keyfile del custode n° 1
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_1.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile del custode n° 2
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_2.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile del custode n° 3
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o cipher_disk_3.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -

# keyfile master
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o master.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -



##########################
# cifratura dei 3 device #
##########################
# attach dispositivo
DEV_1=$(losetup -Pf --show cipher_disk_1.img)

# inizializzazione dev_1 con rumore casuale
cryptsetup open --type plain ${DEV_1} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_1.img \
        --offset 32768 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_1}

# attach dispositivo
DEV_2=$(losetup -Pf --show cipher_disk_2.img)

# inizializzazione dev_2 con rumore casuale
cryptsetup open --type plain ${DEV_2} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_2.img \
        --offset 36864 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_2}

# attach dispositivo
DEV_3=$(losetup -Pf --show cipher_disk_3.img)

# inizializzazione dev_3 con rumore casuale
cryptsetup open --type plain ${DEV_3} container --key-file /dev/urandom
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# cifratura dispositivo n° 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_3.img \
        --offset 40960 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        ${DEV_3}



##############################
# Creazione gruppo di volumi #
##############################
# &#34;apro&#34; il volume 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_1.img \
         --key-file - \
         ${DEV_1} cipher_disk_1

# &#34;apro&#34; il volume 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_2.img \
         --key-file - \
         ${DEV_2} cipher_disk_2

# &#34;apro&#34; il volume 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_3.img \
         --key-file - \
         ${DEV_3} cipher_disk_3

# Creo il mio gruppo di volumi con i 3 volumi &#34;fisici&#34;:
# 1. /dev/mapper/cipher_disk_1
# 2. /dev/mapper/cipher_disk_2
# 3. /dev/mapper/cipher_disk_3
vgcreate vg_master /dev/mapper/cipher_disk_1  /dev/mapper/cipher_disk_2  /dev/mapper/cipher_disk_3

# creazione dell&#39;unico volume logico
lvcreate -n lv_master vg_master -l 100%FREE



################################
# cifratura e mount del master #
################################
# cifratura dispositivo master
dd if=/dev/urandom of=/dev/mapper/vg_master-lv_master bs=1M count=32 status=progress
gpg -d master.key.gpg | \
    cryptsetup luksFormat  \
        --type luks2 \
        --key-file - \
        --header header_master.img \
		--offset 65536 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        /dev/mapper/vg_master-lv_master

# apriamo il dispositivo master
gpg -d master.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_master.img \
         --key-file - \
         /dev/mapper/vg_master-lv_master cipher_disk_master

# e finalmente lo formattiamo
mkfs.ext4 /dev/mapper/cipher_disk_master

# Test: montiamo il disco
mkdir -p /run/media/master/disk_master
chown -R ${USER}:${USER} /run/media/master/disk_master
mount -t auto /dev/mapper/cipher_disk_master /run/media/master/disk_master

# Infine chiudiamo tutto
umount /run/media/master/disk_master
cryptsetup close cipher_disk_master
vgchange -an vg_master
cryptsetup close cipher_disk_1
cryptsetup close cipher_disk_2
cryptsetup close cipher_disk_3
losetup -d ${DEV_1} ${DEV_2} ${DEV_3}
</code></pre>

<p>Dopo aver appurato che tutto funzioni, consegno ad ogni “custode” dispositivo, keyfile e header.</p>

<p>Se un attaccante dovesse entrare in possesso di uno o più dispositivi, troverebbe solo un mucchio di dati incomprensibili.</p>

<p>Posto che riuscisse a decifrare il dispositivo, troverebbe un pezzo di un gruppo di volumi, cifrato e inutilizzabile.</p>

<p>Il master a questo punto non dovrà fare altro che aprire e chiudere il vault, dopo aver riunito tutti i pezzi, come segue:</p>

<p><strong>Apertura del vault</strong></p>

<pre><code class="language-bash"># Attach dei dispositivi
DEV_1=$(losetup -Pf --show cipher_disk_1.img)
DEV_2=$(losetup -Pf --show cipher_disk_2.img)
DEV_3=$(losetup -Pf --show cipher_disk_3.img)

# &#34;apro&#34; il volume 1
gpg -d cipher_disk_1.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_1.img \
         --key-file - \
         ${DEV_1} cipher_disk_1

# &#34;apro&#34; il volume 2
gpg -d cipher_disk_2.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_2.img \
         --key-file - \
         ${DEV_2} cipher_disk_2

# &#34;apro&#34; il volume 3
gpg -d cipher_disk_3.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_3.img \
         --key-file - \
         ${DEV_3} cipher_disk_3

# (facoltativo) apre il gruppo di volumi
vgchange -ay vg_master

# &#34;apre&#34; il master volume
gpg -d master.key.gpg | \
    cryptsetup open \
         --type luks2 \
         --header header_master.img \
         --key-file - \
         /dev/mapper/vg_master-lv_master cipher_disk_master

# Monta il volume
mount -t auto /dev/mapper/cipher_disk_master /run/media/master/disk_master
</code></pre>

<p><strong>Chiusura del vault</strong></p>

<pre><code class="language-bash"># smonta il volume cifrato
umount /run/media/master/disk_master

# chiusura del vault master
cryptsetup close cipher_disk_master

# chiusura del gruppo di volumi
vgchange -an vg_master

# chiusura dei singoli vault cifrati
cryptsetup close cipher_disk_1
cryptsetup close cipher_disk_2
cryptsetup close cipher_disk_3

# deattach dei dispositivi
losetup -d ${DEV_1} ${DEV_2} ${DEV_3}
</code></pre>

<p><a href="/aytin/tag:cryptsetup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptsetup</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:dmcrypt" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dmcrypt</span></a> <a href="/aytin/tag:gpg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gpg</span></a> <a href="/aytin/tag:loseup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loseup</span></a> <a href="/aytin/tag:luks" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">luks</span></a> <a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a> <a href="/aytin/tag:storage" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">storage</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/device-mapper-luks-lvm</guid>
      <pubDate>Mon, 23 Feb 2026 10:58:17 +0000</pubDate>
    </item>
    <item>
      <title>Cenni sulla creazione di pool di storage con LVM</title>
      <link>https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm</link>
      <description>&lt;![CDATA[lvm&#xA;&#xA;Premessa&#xA;Supponiamo di voler aggregare dei dispositivi in un unico storage. Potrebbero essere 3 hd nella propria workstation. O un pool di pendrive.&#xA;&#xA;Ognuno di essi avrà dimensioni differenti e se le usassi singolarmente, quasi certamente la loro dimensione condizionerebbe il loro utilizzo.&#xA;&#xA;Visto che la volta scorsa ho accennato a device mapper, vale la pena spendere due parole sui volumi logici e sulla loro utilità.&#xA;!--more--&#xA;Il fatto di poter aggregare dispositivi fisici diversi in un unico (o più) volume virtuale che si può affettare a piacimento, è un&#39;innegabile flessibilità. Inoltre, ogni operazione di estensione o riduzione sarà eseguita sui volumi logici che rappresentano l&#39;astrazione dei dispositivi fisici sottostanti.&#xA;&#xA;Si deve tenere conto però che aggregare dispositivi di natura molto  differente (ad es. dischi ssd e dischi a rotazione) può comportare un&#39;imprevedibilità non trascurabile in termini di prestazioni.&#xA;&#xA;Tutto ciò avviene attraverso dei tool disponibili nella userland grazie ai quali:&#xA;&#xA;si fa il mapping fra dispositivi fisici e volumi fisici&#xA;si aggregano i   volumi fisici in gruppi di volumi&#xA;si &#34;affettano&#34; i gruppi di volume in volumi logici&#xA;&#xA;Oltre a poter rimuovere/aggiungere/ridimensionare volumi fisici, gruppi di volume e volumi logici.&#xA;Prova sul campo&#xA;Nel nostro laboratorio supporremo di avere 3 dischi di dimensioni differenti che vogliamo usare come un unico volume da partizionare in base ad una necessità che non sia legata alla dimensione del dispositivo fisico.&#xA;&#xA;Per simulare tutto ciò, farò uso di file associati dinamicamente a dei loop device attraverso losetup&#xA;Emulazione - Fase 1 di 2&#xA;Si inizia con la creazione di 3 file container di dimensioni differenti che emuleranno i &#34;device fisici&#34;&#xA;fallocate -l 800M disco1.img&#xA;fallocate -l 500M disco2.img&#xA;fallocate -l 300M disco3.img&#xA;Emulazione - Fase 2 di 2&#xA;I block device, solitamente originati  nel momento in cui avviene la connessione fisica all&#39;host, in questo caso saranno ottenuti associando  i file container ai loop device con losetup&#xA;losetup -Pf --show disco1.img&#xA;  /dev/loop12&#xA;losetup -Pf --show disco2.img&#xA;  /dev/loop13&#xA;losetup -Pf --show disco3.img&#xA;  /dev/loop14&#xA;Tutto ciò che è stato fatto finora, serve solo ai fini dell&#39;emulazione. Con dispositivi fisici si può cominciare direttamente dal passo 1&#xA;Passo 1&#xA;Prendiamo nota dell&#39;ip dei loop device( 12,13,14 in questo esempio) e cominciamo a creare i physical volume.&#xA;pvcreate /dev/loop12&#xA;pvcreate /dev/loop13&#xA;pvcreate /dev/loop14 &#xA;Passo 2&#xA;Dopo aver mappato i volumi fisici con i dispositivi, si farà l&#39;aggregazione in un unico volume group. &#xA;vgcreate vglab /dev/loop12 /dev/loop13 /dev/loop14&#xA;Passo 3&#xA;Infine, la creazione dei logical volume.&#xA;I volumi logici saranno di 100 MiB, 700 MiB, 788 MiB. Non ne fanno parte i 12 MiB dell&#39;header LVM (4 MiB per ogni disco fisico):&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questa definizione va bene per la didattica.&#xA;&#xA;Dilingentemente abbiamo fatto ogni singolo passaggio come bravi scolaretti, ma siccome siamo bravi e c&#39;è un modo più compatto per eseguire alcuni passaggi, vale la pena scoprire quali.&#xA;&#xA;Tralasciando la fase di inizializzazione, mi riferisco ai primi 3 passi, che possono collassare in un unico passaggio perché la creazione di un volume group nel passo 3, noto il dispositivo a blocchi del passo 1, può creare implicitamente i physical volume del passo 2. &#xA;&#xA;In realtà i passi 1 e 2 possono collassare in unico passaggio perché la creazione di un volume group crea contestualmente anche i physical volume.&#xA;&#xA;E quindi, emulazione a parte, sintetizzando:&#xA;Passo 1bis (passi 1, 2, 3 e 4):&#xA;vgcreate vglab /dev/loop12 /dev/loop13 /dev/loop14 &#xA;&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;Questo è il minimo indispensabile per creare dei volumi logici.&#xA;&#xA;Dopo aver creato i volumi logici, bisognerà utilizzarli.&#xA;&#xA;I volumi logici sono volumi a cui device mapper fa corrispondere dei block device virtuali sui quali si creeranno dei file system con la formattazione (un exfat e due ext4), come avviene con qualunque altro volume fisico attraverso il corrispondente block device, e si creeranno i punti di montaggio. &#xA;creazione punti di mount&#xA;mkdir  disco1 disco2 disco3&#xA;&#xA;formattazione volumi logici&#xA;mkfs.exfat -L &#34;Disco 1&#34; /dev/mapper/vglab-lvlab1 &#xA;mkfs.ext4 -L &#34;Disco 2&#34; /dev/mapper/vglab-lvlab2&#xA;mkfs.ext4 -L &#34;Disco 3&#34; /dev/mapper/vglab-lvlab3&#xA;lvm&#xA;&#xA;Mount LVM&#xA;Ogni volta che dovremo usare i volumi logici faremo così:&#xA;vgchange -ay vglab&#xA;mount -t exfat -o defaults /dev/mapper/vglab-lvlab1 disco1&#xA;mount -t ext4 -o defaults /dev/mapper/vglab-lvlab2 disco2&#xA;mount -t ext4 -o defaults /dev/mapper/vglab-lvlab3 disco3&#xA;Umount LVM&#xA;Per smontarli invece basterà:&#xA;umount disco1 disco2 disco3&#xA;vgchange -an vglab&#xA;Tutto quello che s&#39;è visto finora, risponde all&#39;esigenza iniziale: come posso aggregare più volumi in unico volume?&#xA;&#xA;Ma riprendendiamo il passo 1bis, per vedere qualcosa di completamente inutile (all&#39;apparenza) ma non per questo meno interessante.&#xA;&#xA;Passo 1bis&#xA;Fin qua nulla di nuovo.&#xA;vgcreate vglab $(losetup -Pf --show disco1.img) $(losetup -Pf --show disco2.img) $(losetup -Pf --show disco3.img) &#xA;&#xA;lvcreate -n lvlab1 vglab -L 100M&#xA;lvcreate -n lvlab2 vglab -L 700M&#xA;lvcreate -n lvlab3 vglab -l 100%FREE&#xA;&#xA;Passo 2&#xA;vgcreate vglab2 $(losetup -Pf --show /dev/vglab/lvlab3)&#xA;lvcreate -n lvlab4 vglab2 -l 100%FREE&#xA;La particolarità del passo 2, completamente inutile, ha il solo scopo di mostrare come device mapper mi permetta di stratificare i volumi virtuali attraverso i corrispondenti dispositivi a blocchi virtuali per creare delle vere e proprie matrioske di volumi virtuali.&#xA;&#xA;nested lvm&#xA;&#xA;In questo caso,  /dev/mapper/vglab-lv\lab\3 diventa un dispositivo a blocchi su un loop device ed è un attimo che quel dispositivo a blocchi diventi a sua volte un gruppo di volumi su cui creare un ulteriore  volume logico.&#xA;&#xA;Un discreto nonsense anche se... (to be continued)_&#xA;&#xA;#lvm #devicemapper #logicalvolume #volumegroup #loopdevice]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/9yUu94KMzjel/9mhHuMxvnEmlvApYNEa2mIFVsU2393xMvfrpyNqp.png" alt="lvm"></p>

<h2 id="premessa">Premessa</h2>

<p>Supponiamo di voler aggregare dei dispositivi in un unico storage. Potrebbero essere 3 hd nella propria workstation. O un pool di pendrive.</p>

<p>Ognuno di essi avrà dimensioni differenti e se le usassi singolarmente, quasi certamente la loro dimensione condizionerebbe il loro utilizzo.</p>

<p>Visto che <a href="https://noblogo.org/aytin/come-creare-un-file-container" rel="nofollow">la volta scorsa</a> ho accennato a <strong>device mapper</strong>, vale la pena spendere due parole sui volumi logici e sulla loro utilità.

Il fatto di poter aggregare dispositivi fisici diversi in un unico (o più) volume virtuale che si può affettare a piacimento, è un&#39;innegabile flessibilità. Inoltre, ogni operazione di estensione o riduzione sarà eseguita sui <strong>volumi logici</strong> che rappresentano l&#39;astrazione dei dispositivi fisici sottostanti.</p>

<p>Si deve tenere conto però che aggregare dispositivi di natura molto  differente (ad es. dischi ssd e dischi a rotazione) può comportare un&#39;imprevedibilità non trascurabile in termini di prestazioni.</p>

<p>Tutto ciò avviene attraverso dei tool disponibili nella userland grazie ai quali:</p>
<ol><li>si fa il mapping fra dispositivi fisici e <strong>volumi fisici</strong></li>
<li>si aggregano i   volumi fisici in <strong>gruppi di volumi</strong></li>
<li>si “affettano” i gruppi di volume in <strong>volumi logici</strong></li></ol>

<p>Oltre a poter rimuovere/aggiungere/ridimensionare volumi fisici, gruppi di volume e volumi logici.</p>

<h2 id="prova-sul-campo">Prova sul campo</h2>

<p>Nel nostro laboratorio supporremo di avere 3 dischi di dimensioni differenti che vogliamo usare come un unico volume da partizionare in base ad una necessità che non sia legata alla dimensione del dispositivo fisico.</p>

<p>Per simulare tutto ciò, farò uso di file associati dinamicamente a dei loop device attraverso <code>losetup</code></p>

<h3 id="emulazione-fase-1-di-2">Emulazione – Fase 1 di 2</h3>

<p>Si inizia con la creazione di 3 file container di dimensioni differenti che emuleranno i “device fisici”</p>

<pre><code class="language-bash">fallocate -l 800M disco1.img
fallocate -l 500M disco2.img
fallocate -l 300M disco3.img
</code></pre>

<h3 id="emulazione-fase-2-di-2">Emulazione – Fase 2 di 2</h3>

<p>I block device, solitamente originati  nel momento in cui avviene la connessione fisica all&#39;host, in questo caso saranno ottenuti associando  i file container ai loop device con <code>losetup</code></p>

<pre><code class="language-bash">losetup -Pf --show disco1.img
  /dev/loop12
losetup -Pf --show disco2.img
  /dev/loop13
losetup -Pf --show disco3.img
  /dev/loop14
</code></pre>

<p>Tutto ciò che è stato fatto finora, serve solo ai fini dell&#39;emulazione. Con dispositivi fisici si può cominciare direttamente dal <strong>passo 1</strong></p>

<h3 id="passo-1">Passo 1</h3>

<p>Prendiamo nota dell&#39;ip dei loop device( 12,13,14 in questo esempio) e cominciamo a creare i <strong>physical volume</strong>.</p>

<pre><code class="language-bash">pvcreate /dev/loop12
pvcreate /dev/loop13
pvcreate /dev/loop14 
</code></pre>

<h3 id="passo-2">Passo 2</h3>

<p>Dopo aver mappato i volumi fisici con i dispositivi, si farà l&#39;aggregazione in un unico <strong>volume group</strong>.</p>

<pre><code class="language-bash">vgcreate vg_lab /dev/loop12 /dev/loop13 /dev/loop14
</code></pre>

<h3 id="passo-3">Passo 3</h3>

<p>Infine, la creazione dei <strong>logical volume</strong>.
I volumi logici saranno di 100 MiB, 700 MiB, 788 MiB. Non ne fanno parte i 12 MiB dell&#39;header LVM (4 MiB per ogni disco fisico):</p>

<pre><code class="language-bash">lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questa definizione va bene per la didattica.</p>

<p>Dilingentemente abbiamo fatto ogni singolo passaggio come bravi scolaretti, ma siccome siamo bravi e c&#39;è un modo più compatto per eseguire alcuni passaggi, vale la pena scoprire quali.</p>

<p>Tralasciando la fase di inizializzazione, mi riferisco ai primi 3 passi, che possono collassare in un unico passaggio perché la creazione di un volume group nel passo 3, noto il dispositivo a blocchi del passo 1, può creare implicitamente i physical volume del passo 2.</p>

<p>In realtà i passi 1 e 2 possono collassare in unico passaggio perché la creazione di un volume group crea contestualmente anche i physical volume.</p>

<p>E quindi, emulazione a parte, sintetizzando:</p>

<h3 id="passo-1bis-passi-1-2-3-e-4">Passo 1bis (passi 1, 2, 3 e 4):</h3>

<pre><code class="language-bash">vgcreate vg_lab /dev/loop12 /dev/loop13 /dev/loop14 

lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE
</code></pre>

<p>Questo è il minimo indispensabile per creare dei volumi logici.</p>

<p>Dopo aver creato i volumi logici, bisognerà utilizzarli.</p>

<p>I volumi logici sono volumi a cui device mapper fa corrispondere dei block device virtuali sui quali si creeranno dei file system con la formattazione (un exfat e due ext4), come avviene con qualunque altro volume fisico attraverso il corrispondente block device, e si creeranno i punti di montaggio.</p>

<pre><code class="language-bash"># creazione punti di mount
mkdir  disco1 disco2 disco3

# formattazione volumi logici
mkfs.exfat -L &#34;Disco 1&#34; /dev/mapper/vg_lab-lv_lab_1 
mkfs.ext4 -L &#34;Disco 2&#34; /dev/mapper/vg_lab-lv_lab_2
mkfs.ext4 -L &#34;Disco 3&#34; /dev/mapper/vg_lab-lv_lab_3
</code></pre>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/9FVjnpWgalop/O43bT2aJFAkN4O5rvjsryOLd3eTsCM9wJeAVvRxx.png" alt="lvm"></p>

<p><strong>Mount LVM</strong>
Ogni volta che dovremo usare i volumi logici faremo così:</p>

<pre><code class="language-bash">vgchange -ay vg_lab
mount -t exfat -o defaults /dev/mapper/vg_lab-lv_lab_1 disco1
mount -t ext4 -o defaults /dev/mapper/vg_lab-lv_lab_2 disco2
mount -t ext4 -o defaults /dev/mapper/vg_lab-lv_lab_3 disco3
</code></pre>

<p><strong>Umount LVM</strong>
Per smontarli invece basterà:</p>

<pre><code class="language-bash">umount disco1 disco2 disco3
vgchange -an vg_lab
</code></pre>

<p>Tutto quello che s&#39;è visto finora, risponde all&#39;esigenza iniziale: come posso aggregare più volumi in unico volume?</p>

<p>Ma riprendendiamo il passo 1bis, per vedere qualcosa di completamente inutile (all&#39;apparenza) ma non per questo meno interessante.</p>

<pre><code class="language-bash"># Passo 1bis
# Fin qua nulla di nuovo.
vgcreate vg_lab $(losetup -Pf --show disco1.img) $(losetup -Pf --show disco2.img) $(losetup -Pf --show disco3.img) 

lvcreate -n lv_lab_1 vg_lab -L 100M
lvcreate -n lv_lab_2 vg_lab -L 700M
lvcreate -n lv_lab_3 vg_lab -l 100%FREE

# Passo 2
vgcreate vg_lab_2 $(losetup -Pf --show /dev/vg_lab/lv_lab_3)
lvcreate -n lv_lab_4 vg_lab_2 -l 100%FREE
</code></pre>

<p>La particolarità del passo 2, completamente inutile, ha il solo scopo di mostrare come device mapper mi permetta di stratificare i volumi virtuali attraverso i corrispondenti dispositivi a blocchi virtuali per creare delle vere e proprie matrioske di volumi virtuali.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/489827599091373610/7321b8e85-c3df53/c05WUg43a3VK/cZHXiaUMAn51naNCasIoy3hSc61iyLOqsCT45eTG.png" alt="nested lvm"></p>

<p>In questo caso,  /dev/mapper/vg_lab-lv_lab_3 diventa un <strong>dispositivo a blocchi su un loop device</strong> ed è un attimo che quel dispositivo a blocchi diventi a sua volte <strong>un gruppo di volumi su cui creare un ulteriore  volume logico</strong>.</p>

<p>Un discreto nonsense anche se... <em>(to be continued)</em></p>

<p><a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:logicalvolume" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">logicalvolume</span></a> <a href="/aytin/tag:volumegroup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">volumegroup</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/cenni-sulla-creazione-di-pool-di-storage-con-lvm</guid>
      <pubDate>Tue, 14 May 2024 16:34:11 +0000</pubDate>
    </item>
    <item>
      <title>Come creare un file container cifrato</title>
      <link>https://noblogo.org/aytin/come-creare-un-file-container</link>
      <description>&lt;![CDATA[cartella con lucchetto&#xA;smallia href=&#34;https://www.freepik.com/free-photo/yellow-folder-with-security-key954598.htm#query=file%20lock&amp;position=1&amp;fromview=keyword&amp;track=ais&amp;uuid=7a92782d-c3bf-42db-ac2c-6c63c46f9edd&#34;Image by d3images/a/i on Freepik/small&#xA;&#xA;Introduzione a cryptsetup + LUKS&#xA;Supponiamo di voler creare una piccola cassaforte digitale come faremmo con Veracrypt. Ma senza Veracrypt.&#xA;&#xA;Ciò sarà possibile grazie a dm-crypt.&#xA;dm-crypt è un modulo del kernel che usa il framework device mapper per fornire funzionalità trasparenti di crittografia per dispositivi a blocchi usando le crypto api del kernel. L’uso di device mapper consente, tra l’altro, di &#34;poggiare&#34; dm-crypt sopra ogni possibile mapping dei dispositivi e quindi può cifrare partizioni, volumi raid o volumi logici.&#xA;!--more--&#xA;Introduzione a cryptsetup + LUKS&#xA;  Inizializzazione&#xA;  Apertura&#xA;  Chiusura&#xA;Come creare il file vault&#xA;Header detachable e keyfile&#xA;Partizionare un &#34;volume&#34; cifrato&#xA;&#xA;\EDIT 02/03/2026\]: Riscrittura del par. 3 - &#34;Header detachable e keyfile&#34;, alla luce degli approfondimenti fatti con &#34;[Device Mapper: Luks + LVM&#34; e la &#34;Trilogia delle password - Vol. 1,2 e 3&#34;&#xA;&#xA;Poi, essendo a tutti gli effetti anche un dispositivo a blocchi (virtuale), può essere utilizzabile a sua volta come volume nel file system, come swap o come disco fisico per lvm.&#xA;&#xA;La configurazione della cifratura avviene di solito (non è l’unico modo ma è lo standard de facto) con l’utility cryptsetup + LUKS&#xA;&#xA;Come avviene di base la cifratura di un dispositivo?&#xA;&#xA;Le operazioni principali di cryptsetup (con estensioni LUKS) sono:&#xA;&#xA;luksFormat: stabilisce le modalità di cifratura (consigliato il default)&#xA;luksOpen: (deprecato. Si usa open \-\-type luks2) attiva la cifratura sul device associandolo (grazie a device mapper) ad un dispositivo a blocchi virtuale&#xA;luksClose (deprecato. Si usa close \-\-type luks2): disattiva la cifratura&#xA;&#xA;Inizializzazione&#xA;&#xA;attacco il dispositivo fisico, viene creata la entry per /dev/\id\dispositivo\a\blocchi\fisico\&#xA;cifratura del dispositivo a blocchi /dev/\id\dispositivo\a\blocchi\fisico\ con LUKS (cryptsetup luksFormat)&#xA;al di sopra del dispositivo a blocchi fisico, viene creato un dispositivo a blocchi virtuale, che troverò sotto /dev/mapper/\nome\fittizio\, che eroga le funzionalità di cifratura (cryptsetup open) al dispositivo a blocchi fisico sottostante.&#xA;Infine, partiziono e/o formatto nella maniera canonica il dispositivo a blocchi virtuale (cifrato) /dev/mapper/\nome\fittizio\.&#xA;&#xA;Apertura&#xA;&#xA;attacco il dispositivo, viene creata la entry per /dev/\id\dispositivo\a\blocchi\fisico\&#xA;attivo il dispositivo a blocchi virtuale che eroga le funzionalità di cifratura (cryptsetup open) e che creerà l’occorrenza sotto /dev/mapper/\nome\fittizio\&#xA;faccio il mount del dispositivo a blocchi virtuale /dev/mapper/ su un punto di montaggio che è una cartella che creerò per l’occasione&#xA;&#xA;Chiusura&#xA;&#xA;faccio l’unmount del punto di montaggio&#xA;chiudo il dispositivo a blocchi virtuale (cryptsetup close) /dev/mapper/\nome\fittizio\&#xA;stacco il dispositivo fisico&#xA;&#xA;Fermo restando che questi restano i passaggi generali per qualunque dispositivo fisico, per creare un file container cifrato come farebbe Veracrypt, basta che cryptsetup formatti un file invece che un dispositivo a blocchi e automaticamente assocerà il file al primo loop device disponibile.&#xA;È veramente semplicesmalla id=&#34;linknota1&#34; title=&#34;vai alla nota 1&#34; href=&#34;#nota1&#34;supstrong [1] /strong/sup/a/small.&#xA;&#xA;Come creare il file vault&#xA;Divido le operazioni in 3 fasi:&#xA;&#xA;Init: fase di inizializzazione del &#34;dispositivo&#34; (il file). Andrà fatta solo la prima volta.&#xA;Open e Close: sono le operazioni che farò ogniqualvolta dovrò usare il container.&#xA;&#xA;Gli oggetti su cui andrà a lavorare sono:&#xA;&#xA;discocifrato.img: il file container cifrato.&#xA;discocifrato: il nome con cui discocifrato.img (o meglio, la sua rappresentazione come loop device visibile con losetup) viene mappato da device mapper.&#xA;disco\in\chiaro: il punto di montaggio.&#xA;&#xA;Init&#xA;creazione di una cartella che sarà il nostro punto di mount&#xA;mkdir discoinchiaro&#xA; &#xA;creazione di un file vuoto di 2 GiB&#xA;sudo fallocate -l 2g discocifrato.img&#xA; &#xA;preparazione cifratura LUKS &#xA;sudo cryptsetup luksFormat \&#xA;     --type luks2 \&#xA;     --hash=sha512 \&#xA;     --key-size=512 \&#xA;     discocifrato.img&#xA; &#xA;creazione dispositivo a blocchi virtuale che eroga le funzionalità di cifratura&#xA;sudo cryptsetup open \&#xA;     --type luks2 \&#xA;     discocifrato.img discocifrato&#xA; &#xA;formattazione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato&#xA;Open&#xA;creazione dispositivo a blocchi virtuale&#xA;sudo cryptsetup open \&#xA;     --type luks2 &#xA;     discocifrato.img discocifrato&#xA; &#xA;monta il dispositivo nel punto di montaggio&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato discoinchiaro&#xA;Close&#xA;smonta il dispositivo&#xA;sudo umount discoinchiaro&#xA; &#xA;chiudo il dispositivo a blocchi virtuale staccandolo dai loop device&#xA;sudo cryptsetup close discocifrato&#xA;Header detachable e keyfile&#xA;Alziamo il livello di paranoia aggiungendo una complessità ulteriore. Creeremo il file vault nel seguente modo:&#xA;&#xA;il vault sarà inizializzato con rumore casuale&#xA;header detachable&#xA;offset custom&#xA;keyfile invece che password&#xA;default di argon2id (controlla il tuo default con cryptsetup benchmark)&#xA;&#xA;L’apertura del volume cifrato sarà così vincolata alla disponibiltà sia del keyfile che dell’header, senza il quale il volume cifrato sarebbe comunque inservibile.&#xA;&#xA;La presenza di rumore casuale su tutto il vault nella fase di inizializzazione impedirà qualunque tentativo di risalire alla tipologia di informazioni memorizzate, l&#39;assenza di zeri impedirà di capire quanti sono i dati (cifrati) memorizzati.&#xA;&#xA;L&#39;offset custom aggiunge un ulteriore tassello perchè nasconde il punto in cui inizia il payload.&#xA;&#xA;Un keyfile di dati binari casuali è infinitamente più robusto di una password  e può esser conservato separatamente insieme all&#39;header. La cifratura simmetrica del keyfile aggiunge ulteriore protezione, fatta magari usando una passphrase ottenuta col metodo Diceware.&#xA;&#xA;Infine la cifratura di default di luks2, argon2id, che è notoriamente sia CPU bound che GPU bound.&#xA;&#xA;Creo il keyfile protetto da una cifratura simmetrica di gpgsmalla id=&#34;linknota2&#34; title=&#34;vai alla nota 2&#34; href=&#34;#nota2&#34;supstrong [2] /strong/sup/small/a:&#xA;Creazione di un keyfile di 4KiB basata sulla pseudocasualità di /dev/urandom&#xA;creazione del keyfile&#xA;dd if=/dev/urandom bs=1024 count=4 | \&#xA;    gpg --yes -o discocifrato.key.gpg -c \&#xA;        --s2k-mode 3 \&#xA;        --s2k-count 32505856 \&#xA;        --s2k-cipher-algo aes256 \&#xA;        --s2k-digest-algo sha512 \&#xA;        --force-mdc -&#xA;Inizializzo il vault con dati casuali e poi lo formatto creando l&#39;header detachable del volume cifrato fornendo il keyfile invece della passphrase classica:&#xA;inizializzazione vault con dati casuali&#xA;Apro il vault in modalità &#39;plain&#39; senza header&#xA;sudo cryptsetup open \&#xA;    --type plain \&#xA;    --key-file /dev/urandom \&#xA;    --cipher aes-xts-plain64 \&#xA;    --key-size 512 \ &#xA;    discocifrato.img container&#xA;&#xA;scrivo degli zeri a cui, attraverso il motore di cifratura,&#xA;corrisponderanno dati casuali sul vault.&#xA;dd if=/dev/zero of=/dev/mapper/container status=progress&#xA;cryptsetup close container&#xA;&#xA;Formattazione vault&#xA;gpg -d discocifrato.key.gpg | \&#xA;    sudo cryptsetup luksFormat \&#xA;        --type luks2 \&#xA;        --key-file - \&#xA;        --header header.img \&#xA;        --offset 32768 \&#xA;        --hash sha512 \&#xA;        --key-size 512 \&#xA;        --cipher aes-xts-plain64 \&#xA;        discocifrato.img&#xA;Ed è così che l’apertura del volume cifrato è ora vincolata al possesso dell’header e del keyfile:&#xA;attivazione dispositivo a blocchi virtuale passando header e keyfile protetto da gpg&#xA;gpg -d discocifrato.key.gpg | \&#xA;    sudo cryptsetup open \&#xA;        --type luks2 \&#xA;&#x9;--header header.img \&#xA;&#x9;--key-file - \&#xA;&#x9;discocifrato.img discocifrato&#xA;Provando ad aprire container cifrato senza fornire l’header (non tanto il keyfile che è una passphrase evoluta) succede questo:&#xA;sudo cryptsetup open \&#xA;    --type luks2 \&#xA;    discocifrato.img discocifrato&#xA;Il dispositivo discocifrato.img non è un dispositivo LUKS valido.&#xA;Infine, un&#39;annotazione doverosa.&#xA;&#xA;Visto che il livello di paranoia abbiamo detto essere elevato, sarebbe consigliabile prestare una certa attenzione alla scelta dei nomi.&#xA;&#xA;Quelli usati finora avevano uno scopo &#34;didattico&#34;, che chiarisse il loro scopo  con un nome parlante.&#xA;&#xA;i nomi dei file relativi a header e keyfile sarebbe bene non fossero qualcosa del tpo &#34;header.img&#34; o &#34;discocifratokey.gpg&#34; che rivelano troppo esplicitamente la presenza di un disco cifrato o addirittura dello stesso LUKS. Meglio usare nomi più decontestualizzati, che so... &#34;sys-module-virtio.bin&#34; per l&#39;header e &#34;boot-vmlinuz-06.blob&#34; per il keyfile e via dicendo.&#xA;Partizionare un &#34;volume&#34; cifrato&#xA;Per concludere, visto che prima ho accennato al fatto che dm-crypt, grazie al sottosistema device mapper, fa in modo che i dispositivi a blocchi (virtuali) mascherino i dispositivo a blocchi sottostanti (un file montato su un loop device, nel nostro caso), i dispositivi a blocchi mappati possono anche essere partizionati invece che sempicemente formattati. O potrebbe essere volumi fisici di un gruppo di volumi LVM, and so on…&#xA;&#xA;Difficilmente avremo bisogno di partizionare un file container cifrato, è solo l’occasione per speculare un po’ su quello che potrebbe succedere su un device fisico.&#xA;Init&#xA;mkdir discoinchiaro&#xA;sudo fallocate -l 2g discocifrato.img&#xA;sudo cryptsetup luksFormat --hash=sha512 --key-size=512 discocifrato.img&#xA;sudo cryptsetup open --type luks2 discocifrato.img discocifrato&#xA; &#xA;Creo 1 partizione primaria da 600 MiB, una estesa da 1400 MiB&#xA;contenente 2 partizioni logiche da 600 MiB e 829 MiB (mancano i&#xA;16 MiB dell&#39;intestazione luks e i 3 MiB delle intestazioni delle&#xA;partizioni primarie ed estese per un totale di 2GiB tondi tondi)&#xA;sudo fdisk /dev/mapper/discocifrato&#xA;n,,,,+600M,n,e,,,,n,,+600M,n,,,w&#xA; &#xA;il partizionamento potrebbe richiedere l&#39;esecuzione di partprobe&#xA;affinché il kernel carichi la tabella delle partizioni aggiornata&#xA;sudo partprobe /dev/mapper/discocifrato&#xA;&#xA;stato delle partizioni&#xA;sudo fdisk -l /dev/mapper/discocifrato&#xA;Disk /dev/mapper/discocifrato: 1,98 GiB, 2130706432 bytes, 520192 sectors&#xA;Units: sectors of 1 * 4096 = 4096 bytes&#xA;Sector size (logical/physical): 4096 bytes / 4096 bytes&#xA;I/O size (minimum/optimal): 4096 bytes / 4096 bytes&#xA;Disklabel type: dos&#xA;Disk identifier: 0x6d65a06f&#xA;&#xA;Device                     Boot  Start    End Sectors  Size Id Type&#xA;/dev/mapper/discocifrato1         256 153855  153600  600M 83 Linux&#xA;/dev/mapper/discocifrato2      153856 520191  366336  1,4G  5 Extended&#xA;/dev/mapper/discocifrato5      154112 307711  153600  600M 83 Linux&#xA;/dev/mapper/discocifrato6      307968 520191  212224  829M 83 Linux&#xA;&#xA;procedo con la formattazione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato1 #formatto la partizione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato5 #formatto la partizione&#xA;sudo mkfs.ext4 /dev/mapper/discocifrato6 #formatto la partizione&#xA;Rispetto all’init di prima, invece che formattare subito il device &#34;fisico&#34;, l’ho partizionato. Esattamente come avrei fatto con un dispositivo realmente fisico.&#xA;Open&#xA;sudo cryptsetup open --type luks2 discocifrato.img discocifrato&#xA; &#xA;di nuovo, potrebbe essere necessario a meno di non riavviare&#xA;sudo partprobe /dev/mapper/discocifrato&#xA; &#xA;mount delle partizioni&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato1 discoinchiaro1&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato5 discoinchiaro2&#xA;sudo mount -t ext4 -o defaults /dev/mapper/discocifrato6 discoinchiaro3&#xA;Close&#xA;sudo umount discoinchiaro1&#xA;sudo umount discoinchiaro2&#xA;sudo umount discoinchiaro3&#xA;sudo cryptsetup close discocifrato1&#xA;sudo cryptsetup close discocifrato2&#xA;sudo cryptsetup close discocifrato5&#xA;sudo cryptsetup close discocifrato6&#xA;sudo cryptsetup close discocifrato&#xA;&#xA;Note:&#xA;small&#xA;&#xA;cryptsetup --open luks2 e cryptsetup --close luks2, a id=&#34;nota1&#34;/aquando applicate direttamente al file container, includono implicitamente la parte di accoppiamento al loop device.&#xA;    In altre parole,&#xA;    &#xA;        cryptsetup open --type luks2 discocifrato.img discocifrato&#xA;        equivale a &#xA;        cryptsetup open --type luks2 $(losetup -Pf --show discocifrato.img) discocifrato&#xA;        e&#xA;        cryptsetup close --type luks2 discocifrato&#xA;        equivale aa href=&#34;#linknota1&#34; title=&#34;torna su&#34;supb [↵] /b/sup/a&#xA;        cryptsetup close --type luks2 discocifrato&#xA;    losetup -D&#xA;    a id=&#34;nota2&#34;/aSe si incorre in questo errore usando gpg:&#xA;&#xA;        gpg: cancelled by user&#xA;    gpg: error creating passphrase: Operation cancelled&#xA;    gpg: symmetric encryption of &#39;[stdin]&#39; failed: Operation cancelled&#xA;        vuol dire che la variabile d’ambiente GPGTTY non ha lo stesso valore del comando tty. Per ovviare basta settare correttamente la variabile:&#xA;        GPGTTY=$(tty)&#xA;    export GPGTTY&#xA;        come suggerito dalla documentazione GnuPG a href=&#34;#linknota2&#34; title=&#34;torna su&#34;supb [↵] /b/sup/a&#xA;&#xA;/small&#xA;&#xA;#cryptsetup #devicemapper #dmcrypt #gpg #loseup #luks #lvm #loopdevice #storage]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://cyberdynesystem.files.wordpress.com/2024/05/yellow-folder-with-security-key.png" alt="cartella con lucchetto">
<small><i><a href="https://www.freepik.com/free-photo/yellow-folder-with-security-key_954598.htm#query=file%20lock&amp;position=1&amp;from_view=keyword&amp;track=ais&amp;uuid=7a92782d-c3bf-42db-ac2c-6c63c46f9edd" rel="nofollow">Image by d3images</a></i> on Freepik</small></p>

<h2 id="introduzione-a-cryptsetup-luks">Introduzione a cryptsetup + LUKS</h2>

<p>Supponiamo di voler creare una piccola cassaforte digitale come faremmo con Veracrypt. Ma senza Veracrypt.</p>

<p>Ciò sarà possibile grazie a <strong>dm-crypt</strong>.
dm-crypt è un modulo del kernel che usa il framework <strong>device mapper</strong> per fornire funzionalità trasparenti di crittografia per dispositivi a blocchi usando le crypto api del kernel. L’uso di device mapper consente, tra l’altro, di “poggiare” dm-crypt sopra ogni possibile mapping dei dispositivi e quindi può cifrare partizioni, volumi raid o volumi logici.

1. <a href="#introduzione-a-cryptsetup-luks" rel="nofollow">Introduzione a cryptsetup + LUKS</a>
  2. <a href="#inizializzazione" rel="nofollow">Inizializzazione</a>
  2. <a href="#apertura" rel="nofollow">Apertura</a>
  2. <a href="#chiusura" rel="nofollow">Chiusura</a>
1. <a href="#come-creare-il-file-vault" rel="nofollow">Come creare il file vault</a>
1. <a href="#header-detachable-e-keyfile" rel="nofollow">Header detachable e keyfile</a>
1. <a href="#partizionare-un-volume-cifrato" rel="nofollow">Partizionare un “volume” cifrato</a></p>

<p><strong>[EDIT 02/03/2026]: Riscrittura del par. 3 – “Header detachable e keyfile”, alla luce degli approfondimenti fatti con “<a href="https://noblogo.org/aytin/device-mapper-luks-lvm" rel="nofollow">Device Mapper: Luks + LVM</a>” e la “Trilogia delle password – Vol. <a href="https://noblogo.org/aytin/come-generare-una-password-o-un-keyfile-sicuri-trilogia-della-password-1-di" rel="nofollow">1</a>,<a href="https://noblogo.org/aytin/come-valutare-la-resistenza-di-una-password-trilogia-della-password-2-di-3" rel="nofollow">2</a> e <a href="https://noblogo.org/aytin/archiviare-le-password-in-sicurezza-con-kdf-password-hashing-trilogia-della" rel="nofollow">3</a>“</strong></p>

<p>Poi, essendo a tutti gli effetti anche un dispositivo a blocchi (virtuale), può essere utilizzabile a sua volta come volume nel file system, come swap o come disco fisico per lvm.</p>

<p>La configurazione della cifratura avviene di solito (non è l’unico modo ma è lo standard de facto) con l’utility <strong>cryptsetup + LUKS</strong></p>

<p>Come avviene di base la cifratura di un dispositivo?</p>

<p>Le operazioni principali di cryptsetup (con estensioni LUKS) sono:</p>
<ul><li><strong>luksFormat</strong>: stabilisce le modalità di cifratura (consigliato il default)</li>
<li><strong>luksOpen</strong>: (deprecato. Si usa <strong>open --type luks2</strong>) attiva la cifratura sul device associandolo (grazie a device mapper) ad un dispositivo a blocchi virtuale</li>
<li><strong>luksClose</strong> (deprecato. Si usa <strong>close --type luks2</strong>): disattiva la cifratura</li></ul>

<h3 id="inizializzazione">Inizializzazione</h3>
<ul><li>attacco il dispositivo fisico, viene creata la entry per <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em></li>
<li>cifratura del dispositivo a blocchi <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em> con LUKS (<strong>cryptsetup luksFormat</strong>)</li>
<li>al di sopra del dispositivo a blocchi fisico, viene creato un dispositivo a blocchi virtuale, che troverò sotto <em>/dev/mapper/&lt;nome_fittizio&gt;</em>, che eroga le funzionalità di cifratura (<strong>cryptsetup open</strong>) al dispositivo a blocchi fisico sottostante.</li>
<li>Infine, partiziono e/o formatto nella maniera canonica il dispositivo a blocchi virtuale (cifrato) <em>/dev/mapper/&lt;nome_fittizio&gt;</em>.</li></ul>

<h3 id="apertura">Apertura</h3>
<ul><li>attacco il dispositivo, viene creata la entry per <em>/dev/&lt;id_dispositivo_a_blocchi_fisico&gt;</em></li>
<li>attivo il dispositivo a blocchi virtuale che eroga le funzionalità di cifratura (<strong>cryptsetup open</strong>) e che creerà l’occorrenza sotto <em>/dev/mapper/&lt;nome_fittizio&gt;</em></li>
<li>faccio il mount del dispositivo a blocchi virtuale <em>/dev/mapper/</em> su un punto di montaggio che è una cartella che creerò per l’occasione</li></ul>

<h3 id="chiusura">Chiusura</h3>
<ul><li>faccio l’unmount del punto di montaggio</li>
<li>chiudo il dispositivo a blocchi virtuale (<strong>cryptsetup close</strong>) <em>/dev/mapper/&lt;nome_fittizio&gt;</em></li>
<li>stacco il dispositivo fisico</li></ul>

<p>Fermo restando che questi restano i passaggi generali per qualunque dispositivo fisico, per creare un <strong>file container cifrato</strong> come farebbe Veracrypt, basta che cryptsetup <strong>formatti un file</strong> invece che un dispositivo a blocchi e automaticamente assocerà il file al primo loop device disponibile.
È veramente semplice<small><a id="link_nota_1" title="vai alla nota 1" href="#nota_1" rel="nofollow"><sup><strong> [1] </strong></sup></a></small>.</p>

<h2 id="come-creare-il-file-vault">Come creare il file vault</h2>

<p>Divido le operazioni in 3 fasi:</p>
<ul><li><strong>Init</strong>: fase di inizializzazione del “dispositivo” (il file). Andrà fatta solo la prima volta.</li>
<li><strong>Open</strong> e <strong>Close</strong>: sono le operazioni che farò ogniqualvolta dovrò usare il container.</li></ul>

<p>Gli oggetti su cui andrà a lavorare sono:</p>
<ul><li><strong>disco_cifrato.img</strong>: il file container cifrato.</li>
<li><strong>disco_cifrato</strong>: il nome con cui disco_cifrato.img (o meglio, la sua rappresentazione come loop device visibile con <strong>losetup</strong>) viene mappato da device mapper.</li>
<li><strong>disco_in_chiaro</strong>: il punto di montaggio.</li></ul>

<pre><code class="language-bash">## Init
# creazione di una cartella che sarà il nostro punto di mount
mkdir disco_in_chiaro
 
# creazione di un file vuoto di 2 GiB
sudo fallocate -l 2g disco_cifrato.img
 
# preparazione cifratura LUKS 
sudo cryptsetup luksFormat \
     --type luks2 \
     --hash=sha512 \
     --key-size=512 \
     disco_cifrato.img
 
# creazione dispositivo a blocchi virtuale che eroga le funzionalità di cifratura
sudo cryptsetup open \
     --type luks2 \
     disco_cifrato.img disco_cifrato
 
# formattazione
sudo mkfs.ext4 /dev/mapper/disco_cifrato
</code></pre>

<pre><code class="language-bash">## Open
# creazione dispositivo a blocchi virtuale
sudo cryptsetup open \
     --type luks2 
     disco_cifrato.img disco_cifrato
 
# monta il dispositivo nel punto di montaggio
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato disco_in_chiaro
</code></pre>

<pre><code class="language-bash">## Close
# smonta il dispositivo
sudo umount disco_in_chiaro
 
# chiudo il dispositivo a blocchi virtuale staccandolo dai loop device
sudo cryptsetup close disco_cifrato
</code></pre>

<h2 id="header-detachable-e-keyfile">Header detachable e keyfile</h2>

<p>Alziamo il livello di paranoia aggiungendo una complessità ulteriore. Creeremo il file vault nel seguente modo:</p>
<ol><li>il vault sarà inizializzato con rumore casuale</li>
<li>header detachable</li>
<li>offset custom</li>
<li>keyfile invece che password</li>
<li>default di argon2id (controlla il tuo default con cryptsetup benchmark)</li></ol>

<p>L’apertura del volume cifrato sarà così vincolata alla disponibiltà sia del keyfile che dell’header, senza il quale il volume cifrato sarebbe comunque inservibile.</p>

<p>La presenza di rumore casuale su tutto il vault nella fase di inizializzazione impedirà qualunque tentativo di risalire alla tipologia di informazioni memorizzate, l&#39;assenza di zeri impedirà di capire quanti sono i dati (cifrati) memorizzati.</p>

<p>L&#39;offset custom aggiunge un ulteriore tassello perchè nasconde il punto in cui inizia il payload.</p>

<p>Un keyfile di dati binari casuali è infinitamente più robusto di una password  e può esser conservato separatamente insieme all&#39;header. La cifratura simmetrica del keyfile aggiunge ulteriore protezione, fatta magari usando una passphrase ottenuta col <strong><a href="https://noblogo.org/aytin/come-valutare-la-resistenza-di-una-password-trilogia-della-password-2-di-3#metodo-diceware" rel="nofollow">metodo Diceware</a>.</strong></p>

<p>Infine la cifratura di default di luks2, argon2id, che è notoriamente sia CPU bound che GPU bound.</p>

<p>Creo il keyfile protetto da una cifratura simmetrica di gpg<small><a id="link_nota_2" title="vai alla nota 2" href="#nota_2" rel="nofollow"><sup><strong> [2] </strong></sup></small></a>:</p>

<pre><code class="language-bash">## Creazione di un keyfile di 4KiB basata sulla pseudocasualità di /dev/urandom
# creazione del keyfile
dd if=/dev/urandom bs=1024 count=4 | \
    gpg --yes -o disco_cifrato.key.gpg -c \
        --s2k-mode 3 \
        --s2k-count 32505856 \
        --s2k-cipher-algo aes256 \
        --s2k-digest-algo sha512 \
        --force-mdc -
</code></pre>

<p>Inizializzo il vault con dati casuali e poi lo formatto creando l&#39;header detachable del volume cifrato fornendo il keyfile invece della passphrase classica:</p>

<pre><code class="language-bash"># inizializzazione vault con dati casuali
# Apro il vault in modalità &#39;plain&#39; senza header
sudo cryptsetup open \
    --type plain \
    --key-file /dev/urandom \
    --cipher aes-xts-plain64 \
    --key-size 512 \ 
    disco_cifrato.img container

# scrivo degli zeri a cui, attraverso il motore di cifratura,
# corrisponderanno dati casuali sul vault.
dd if=/dev/zero of=/dev/mapper/container status=progress
cryptsetup close container

# Formattazione vault
gpg -d disco_cifrato.key.gpg | \
    sudo cryptsetup luksFormat \
        --type luks2 \
        --key-file - \
        --header header.img \
        --offset 32768 \
        --hash sha512 \
        --key-size 512 \
        --cipher aes-xts-plain64 \
        disco_cifrato.img
</code></pre>

<p>Ed è così che l’apertura del volume cifrato è ora <strong>vincolata al possesso dell’header e del keyfile</strong>:</p>

<pre><code class="language-bash"># attivazione dispositivo a blocchi virtuale passando header e keyfile protetto da gpg
gpg -d disco_cifrato.key.gpg | \
    sudo cryptsetup open \
        --type luks2 \
	--header header.img \
	--key-file - \
	disco_cifrato.img disco_cifrato
</code></pre>

<p>Provando ad aprire container cifrato <strong>senza fornire l’header</strong> (non tanto il keyfile che è una passphrase evoluta) succede questo:</p>

<pre><code class="language-bash">sudo cryptsetup open \
    --type luks2 \
    disco_cifrato.img disco_cifrato
Il dispositivo disco_cifrato.img non è un dispositivo LUKS valido.
</code></pre>

<p>Infine, un&#39;annotazione doverosa.</p>

<p>Visto che il livello di paranoia abbiamo detto essere elevato, sarebbe consigliabile prestare una certa attenzione alla scelta dei nomi.</p>

<p>Quelli usati finora avevano uno scopo “didattico”, che chiarisse il loro scopo  con un nome parlante.</p>

<p>i nomi dei file relativi a header e keyfile sarebbe bene non fossero qualcosa del tpo “header.img” o “discocifrato_key.gpg” che rivelano troppo esplicitamente la presenza di un disco cifrato o addirittura dello stesso LUKS. Meglio usare nomi più decontestualizzati, che so... “<code>sys-module-virtio.bin</code>” per l&#39;header e “<code>boot-vmlinuz-06.blob</code>” per il keyfile e via dicendo.</p>

<h2 id="partizionare-un-volume-cifrato">Partizionare un “volume” cifrato</h2>

<p>Per concludere, visto che prima ho accennato al fatto che dm-crypt, grazie al sottosistema device mapper, fa in modo che i dispositivi a blocchi (virtuali) mascherino i dispositivo a blocchi sottostanti (un file montato su un loop device, nel nostro caso), i dispositivi a blocchi mappati possono anche essere partizionati invece che sempicemente formattati. O potrebbe essere volumi fisici di un gruppo di volumi LVM, and so on…</p>

<p>Difficilmente avremo bisogno di partizionare un file container cifrato, è solo l’occasione per speculare un po’ su quello che potrebbe succedere su un device fisico.</p>

<pre><code class="language-bash">## Init
mkdir disco_in_chiaro
sudo fallocate -l 2g disco_cifrato.img
sudo cryptsetup luksFormat --hash=sha512 --key-size=512 disco_cifrato.img
sudo cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
 
# Creo 1 partizione primaria da 600 MiB, una estesa da 1400 MiB
# contenente 2 partizioni logiche da 600 MiB e 829 MiB (mancano i
# 16 MiB dell&#39;intestazione luks e i 3 MiB delle intestazioni delle
# partizioni primarie ed estese per un totale di 2GiB tondi tondi)
sudo fdisk /dev/mapper/disco_cifrato
n,,,,+600M,n,e,,,,n,,+600M,n,,,w
 
# il partizionamento potrebbe richiedere l&#39;esecuzione di partprobe
# affinché il kernel carichi la tabella delle partizioni aggiornata
sudo partprobe /dev/mapper/disco_cifrato

# stato delle partizioni
sudo fdisk -l /dev/mapper/disco_cifrato
Disk /dev/mapper/disco_cifrato: 1,98 GiB, 2130706432 bytes, 520192 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x6d65a06f

Device                     Boot  Start    End Sectors  Size Id Type
/dev/mapper/disco_cifrato1         256 153855  153600  600M 83 Linux
/dev/mapper/disco_cifrato2      153856 520191  366336  1,4G  5 Extended
/dev/mapper/disco_cifrato5      154112 307711  153600  600M 83 Linux
/dev/mapper/disco_cifrato6      307968 520191  212224  829M 83 Linux

#procedo con la formattazione
sudo mkfs.ext4 /dev/mapper/disco_cifrato1 #formatto la partizione
sudo mkfs.ext4 /dev/mapper/disco_cifrato5 #formatto la partizione
sudo mkfs.ext4 /dev/mapper/disco_cifrato6 #formatto la partizione
</code></pre>

<p>Rispetto all’init di prima, invece che formattare subito il device “fisico”, l’ho partizionato. Esattamente come avrei fatto con un dispositivo realmente fisico.</p>

<pre><code class="language-bash">## Open
sudo cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
 
# di nuovo, potrebbe essere necessario a meno di non riavviare
sudo partprobe /dev/mapper/disco_cifrato
 
# mount delle partizioni
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato1 disco_in_chiaro_1
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato5 disco_in_chiaro_2
sudo mount -t ext4 -o defaults /dev/mapper/disco_cifrato6 disco_in_chiaro_3
</code></pre>

<pre><code class="language-bash">## Close
sudo umount disco_in_chiaro_1
sudo umount disco_in_chiaro_2
sudo umount disco_in_chiaro_3
sudo cryptsetup close disco_cifrato1
sudo cryptsetup close disco_cifrato2
sudo cryptsetup close disco_cifrato5
sudo cryptsetup close disco_cifrato6
sudo cryptsetup close disco_cifrato
</code></pre>

<p><strong>Note:</strong>
<small></p>
<ol><li><p><code>cryptsetup --open luks2</code> e <code>cryptsetup --close luks2</code>, <a id="nota_1"></a>quando applicate direttamente al file container, includono implicitamente la parte di accoppiamento al loop device.
In altre parole,</p>

<pre><code class="language-bash">cryptsetup open --type luks2 disco_cifrato.img disco_cifrato
</code></pre>

<p>equivale a</p>

<pre><code class="language-bash">cryptsetup open --type luks2 $(losetup -Pf --show disco_cifrato.img) disco_cifrato
</code></pre>

<p>e</p>

<pre><code class="language-bash">cryptsetup close --type luks2 disco_cifrato
</code></pre>

<p>equivale a<a href="#link_nota_1" title="torna su" rel="nofollow"><sup><b> [↵] </b></sup></a></p>

<pre><code class="language-bash">cryptsetup close --type luks2 disco_cifrato
losetup -D
</code></pre></li>

<li><p><a id="nota_2"></a>Se si incorre in questo errore usando gpg:</p>

<pre><code class="language-bash">gpg: cancelled by user
gpg: error creating passphrase: Operation cancelled
gpg: symmetric encryption of &#39;[stdin]&#39; failed: Operation cancelled
</code></pre>

<p>vuol dire che la variabile d’ambiente <code>GPG_TTY</code> non ha lo stesso valore del comando tty. Per ovviare basta settare correttamente la variabile:</p>

<pre><code class="language-bash">GPG_TTY=$(tty)
export GPG_TTY
</code></pre>

<p>come suggerito dalla <a href="https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html#Invoking-GPG_002dAGENT" rel="nofollow">documentazione GnuPG</a> <a href="#link_nota_2" title="torna su" rel="nofollow"><sup><b> [↵] </b></sup></a></p></li></ol>

<p></small></p>

<p><a href="/aytin/tag:cryptsetup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">cryptsetup</span></a> <a href="/aytin/tag:devicemapper" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">devicemapper</span></a> <a href="/aytin/tag:dmcrypt" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">dmcrypt</span></a> <a href="/aytin/tag:gpg" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">gpg</span></a> <a href="/aytin/tag:loseup" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loseup</span></a> <a href="/aytin/tag:luks" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">luks</span></a> <a href="/aytin/tag:lvm" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">lvm</span></a> <a href="/aytin/tag:loopdevice" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">loopdevice</span></a> <a href="/aytin/tag:storage" class="hashtag" rel="nofollow"><span>#</span><span class="p-category">storage</span></a></p>
]]></content:encoded>
      <guid>https://noblogo.org/aytin/come-creare-un-file-container</guid>
      <pubDate>Fri, 10 May 2024 21:32:57 +0000</pubDate>
    </item>
  </channel>
</rss>