Friday 3 February 2023

8 - Ubuntu with LUKS: Backup and Restore with Veeam Part 8: Why restoring LUKS, LVM through Veeam recovery UI is a bad idea

Suppose I wanted to do everything through recovery UI as much as possible, except for setting the LUKS container ID, which simply cannot be done through recovery UI. Why does this not work very well?

When I start out fresh, it looks like this.

              CURRENT SYSTEM           │              IN BACKUP
                                       │
     Device       Restore      Size    │  Device       Size    Usage
                                       │
     sda                       127.0G  │  mapper/dm... 123.9G
                                       │  sda          127.0G
                                       │   sda1        1.04G   /boot/efi...
                                       │   sda2        2.00G   /boot (ext4)
                                       │  ubuntu-vg    123.9G
                                       │   ubuntu-lv   61.96G  / (ext4)

I can then map sda to sda just as I did in the previous parts.

     Device       Restore      Size    │  Device       Size    Usage
                                       │
     sda                       127.0G  │  mapper/dm... 123.9G
      sda1        sda1 (/bo... 1.04G   │  sda          127.0G
      sda2        sda2 (/boot) 2.00G   │   sda1        1.04G   /boot/efi...
      free                     123.9G  │   sda2        2.00G   /boot (ext4)
                                       │  ubuntu-vg    123.9G
                                       │   ubuntu-lv   61.96G  / (ext4)

And in the free space on sda, I can create a new partition (here: sda3).

     Device       Restore      Size    │  Device       Size    Usage
                                       │
     sda                       127.0G  │  mapper/dm... 123.9G
      sda1        sda1 (/bo... 1.04G   │  sda          127.0G
      sda2        sda2 (/boot) 2.00G   │   sda1        1.04G   /boot/efi...
      sda3                     123.8G  │   sda2        2.00G   /boot (ext4)
      free                     49.40M  │  ubuntu-vg    123.9G
                                       │   ubuntu-lv   61.96G  / (ext4)


Then I can create a LUKS container in sda3.




It will end up looking like this.

     Device       Restore      Size    │  Device       Size    Usage
                                       │
     sda                       127.0G  │  mapper/dm... 123.9G
      sda1        sda1 (/bo... 1.04G   │  sda          127.0G
      sda2        sda2 (/boot) 2.00G   │   sda1        1.04G   /boot/efi...
      sda3                     123.8G  │   sda2        2.00G   /boot (ext4)
       dm_crypt-0              123.8G  │  ubuntu-vg    123.9G
      free                     49.40M  │   ubuntu-lv   61.96G  / (ext4)



Now I can try to map dm_crypt-0 with mapper/dm_crypt-0. But I am getting an error.


This would have mapped the LVM into the new LUKS container. I can try to map ubuntu-vg into dm_crypt-0. But this does not work either. Possibly because I chose to backup /dev/mapper/dm_crypt-0 as a device instead of /dev/mapper/ubuntu-vg--ubuntu-lv as an LVM.


But it doesn't matter. I can create a new LVM in the new crypt-dm-0 LUKS container.




It will look like this.

     Device       Restore      Size    │  Device       Size    Usage
                                       │
     sda                       127.0G  │  mapper/dm... 123.9G
      sda1        sda1 (/bo... 1.04G   │  sda          127.0G
      sda2        sda2 (/boot) 2.00G   │   sda1        1.04G   /boot/efi...
      sda3                     123.8G  │   sda2        2.00G   /boot (ext4)
       dm-cryp...              123.8G  │  ubuntu-vg    123.9G
      free                     49.40M  │   ubuntu-lv   61.96G  / (ext4)
     ubuntu-vg                 123.8G  │
      free                     123.8G  │



Into the free space in ubuntu-vg, I can map ubuntu-lv


It will look like this.


Now I can start the restore, going from an empty disk to restoring everything in one go, all without leaving recovery UI. This looks too good to be true.

                                RECOVERY SUMMARY
   1. Create GPT partition table on sda (scsi)
   2. Create partition sda1 on sda (scsi)
   3. Create partition sda2 on sda (scsi)
   4. Create partition sda3 on sda (scsi)
   5. Create CryptoLUKS: [dm_crypt-0] on device sda3 (scsi)
   6. Restore sda1 (scsi) to sda1 (scsi)
   7. Restore sda2 (scsi) to sda2 (scsi)
   8. Add mapper/dm_crypt-0 (dm) to ubuntu-vg group
   9. Create ubuntu-lv volume on ubuntu-vg group
   10. Restore ubuntu-vg/ubuntu-lv (dm) to ubuntu-vg/ubuntu-lv (dm)

So far, so good.

     Restore                      100%                     Status: Success


      Time             Action                                   Duration

      16:24:40         Job started at 2023-01-23 16:24:40 UTC
      16:24:42         Starting volume restore
      16:26:54         Waiting for backup infrastructure res... 00:00:02
      16:26:56         Applying changes to disks configuration  00:00:11
      16:27:07         sda1 restored 1 GB at 2.1 GB/s           00:00:01
      16:27:08         sda2 restored 2 GB at 1.2 GB/s           00:00:01
      16:27:09         ubuntu--vg-ubuntu--lv restored 62 GB ... 00:00:41
      16:27:51         Restoring efi                            00:00:00
      16:27:51         Restore EFI volume: /dev/sda1
      16:27:51         Restore EFI boot manager entry: ubuntu
      16:27:51         Processing finished at 2023-01-23 16:...



But in any case, the system will not boot unless I fix the LUKS container UUID.

veeamuser@veeam-recovery-iso:~$ OSdisk='/dev/sda'
veeamuser@veeam-recovery-iso:~$ sudo mount /dev/mapper/ubuntu--vg-ubuntu--lv /mnt
veeamuser@veeam-recovery-iso:~$ cat /mnt/etc/crypttab
dm_crypt-0 UUID=d8073181-5283-44b5-b4dc-6014b2e1a3c2 none luks
veeamuser@veeam-recovery-iso:~$ sudo umount /dev/mapper/ubuntu--vg-ubuntu--lv
veeamuser@veeam-recovery-iso:~$ sudo vgchange -an ubuntu-vg
  0 logical volume(s) in volume group "ubuntu-vg" now active
veeamuser@veeam-recovery-iso:~$ sudo cryptsetup luksUUID --uuid d8073181-5283-44b5-b4dc-6014b2e1a3c2 ${OSdisk}3

WARNING!
========
Do you really want to change UUID of device?

Are you sure? (Type uppercase yes): YES
veeamuser@veeam-recovery-iso:~$ sudo reboot

The restored system boots successfully.


Is everything as it was before the restore? No. the LUKS container sector size is now 512. It was 4096 before.

admin01@testlabubuntu01:~$ sudo cryptsetup luksDump ${OSdisk}3 | grep sector
        sector: 512 [bytes]
admin01@testlabubuntu01:~$

No problem, I can re-encrypt it with 4096 sector size. Or can I?

admin01@testlabubuntu01:~$ sudo cryptsetup reencrypt --sector-size=4096 ${OSdisk}3
Enter passphrase for key slot 0:
Auto-detected active dm device 'dm_crypt-0' for data device /dev/sda3.
Data device is not aligned to requested encryption sector size (4096 bytes).
Failed to initialize LUKS2 reencryption in metadata.
admin01@testlabubuntu01:~$

What happened here? It turns out, the partition created by Veeam during restore does not have its end aligned the way LUKS expects it when 4K sector size is used.

admin01@testlabubuntu01:~$ sudo gdisk -l $OSdisk
...
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2203647   1.0 GiB     EF00
   2         2203648         6397951   2.0 GiB     8300
   3         6397952       266235083   123.9 GiB   8300
admin01@testlabubuntu01:~$

parted reports that the partition is aligned, so where is the problem?

admin01@testlabubuntu01:~$ sudo parted $OSdisk align-check optimal 3
3 aligned
admin01@testlabubuntu01:~$


(END + 1) * 512 Must be divisible by 1024 * 1024

Here, the last sector of /dev/sda3 is 266235083 (see above)
(266235083 + 1) * 512 / (1024 * 1024*) = 129997.599609375
Not divisible.

How to fix this. As I described in the previous parts, after restoring the ESP and boot partitions, exit recovery UI and create the LUKS partition on the shell.

You can do this with parted which is included in Veeam's recovery media. Use --align / -a optimal.

veeamuser@veeam-recovery-iso:~$ sudo parted $OSdisk  print free      
Model: Msft Virtual Disk (scsi)
Disk /dev/sda: 136GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name  Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  1128MB  1127MB  fat32              boot, esp
 2      1128MB  3276MB  2147MB  ext4
        3276MB  136GB   133GB   Free Space

veeamuser@veeam-recovery-iso:~$ sudo parted -a optimal $OSdisk  mkpart 'LUKS' 3276MB 100%
Information: You may need to update /etc/fstab.

veeamuser@veeam-recovery-iso:~$

This will create partitions that are end aligned.

veeamuser@veeam-recovery-iso:~$ sudo gdisk -l $OSdisk                
Number  Start (sector)    End (sector)  Size       Code  Name
...
   3         6397952       266336255   123.9 GiB   8300  LUKS
veeamuser@veeam-recovery-iso:~$ 

Here, the last sector of /dev/sda3 is 266336255
(266336255+ 1) * 512 / (1024 * 1024*) = 130047
Divisible.

gdisk / sgdisk will not align the partition end by default. But you can use it if you do the math yourself.

veeamuser@veeam-recovery-iso:~$ sudo gdisk -l $OSdisk
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2203647   1.0 GiB     EF00
   2         2203648         6397951   2.0 GiB     8300

start_position=$(sudo sgdisk --first-aligned-in-largest /dev/sda $OSdisk)
end_position=$(sudo sgdisk --end-of-largest /dev/sda $OSdisk)
aligned_end_position=$((end_position - ($end_position + 1) % 2048))

veeamuser@veeam-recovery-iso:~$ sudo sgdisk --set-alignment=2048 --new=0:$start_position:$aligned_end_position $OSdisk
The operation has completed successfully.
veeamuser@veeam-recovery-iso:~$ sudo gdisk -l $OSdisk
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         2203647   1.0 GiB     EF00
   2         2203648         6397951   2.0 GiB     8300
   3         6397952       266336255   123.9 GiB   8300
veeamuser@veeam-recovery-iso:~$

The partition created this way with sgdisk has the same end sector as when I created it with parted with --align optimal. Now creating the container with --sector-size=4096 will work.

sudo cryptsetup luksFormat --sector-size=4096  ${OSdisk}3

To sum up: You can't restore the system entirely through the recovery UI because...
  • The system will not boot because the LUKS container UUID is different after the restore.
  • The partition end will not be aligned, and the LUKS container will have the wrong sector size.