Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kirbah/e8691bdbdadf08a6b710138879614e0b to your computer and use it in GitHub Desktop.
Save kirbah/e8691bdbdadf08a6b710138879614e0b to your computer and use it in GitHub Desktop.
Dual booting Windows 11 and Ubuntu 22.04 LTS with LUKS and TPM2 encryption

Dual booting Windows 11 and Ubuntu 22.04 LTS with LUKS and TPM2 encryption

Make sure to think about data backup before you proceed with the below guide.

Tested on HP Elitebook 840 G6 in April 2024.

Bootable USB disk preparation

There are various options for creating a bootable USB drive.

USB Flash Drive

  • Pros:
    • Small form factor
    • Potentially low cost
  • Cons:
    • Slow I/O, particularly write speeds (5-10 MB/s)
    • Faster models can be expensive
    • Limited lifespan

Popular models: Samsung BAR Plus 128GB and Kingston DataTraveler Max (USB-C) 256GB

M.2 SSD + External Enclosure

  • Pros:
    • Fast I/O (200 - 500 MB/s)
    • Second-hand SSDs are affordable
    • Longer lifespan compared to USB drives, with SMART monitoring
  • Cons:
    • External enclosure cost may increase overall expenditure compared to a simple USB drive.

Several hints to choose good enclosure:

  • Enclosure with USB type C will be faster
  • Often you need a screwdriver to change the SSD. Tool free enclosures are better and usually costs the same
  • Realtek RTL9210B is good and reliable chipset for enclosure

Recommended external enclosure: Sabrent EC-SNVE

Any inexpensive M.2 SSD would suffice to create bootable USB disk

Bootable USB disk creation

Numerous programs can create a bootable USB from an ISO file:

A significant issue with these tools is that each time a new ISO is required, the USB must be reformatted. An alternative solution is Ventoy:

  • USB is formatted only once
  • New ISOs can be simply copied to the disk
  • The required ISO is selected during boot time
  • Additionally, it may be helpful to create an extra small reserved space partition to easily mount it and store something from the live boot systems.

Steps to create bootable installation USB stick

  • Download Ventoy
  • Create bootable USB drive
  • Download Winsows 11 / Ubuntu and other ISOs
  • Copy ISO to the Ventoy USB disk
  • Now you can reboot, select USB as boot device and choose what ISO to boot

Install Windows 11

Key steps of the installation process:

  1. Disabling secure boot may be helpful.
  2. Boot from the USB disk.
  3. During installation, select Custom installation.
  4. Create one partition:
    • Keep some free space to install Ubuntu later.
    • Windows will propose creating two extra partitions for EFI and recovery. There's no need to overcomplicate your life by creating partitions manually.
  5. Once installation is completed, it's good to install all updates.
  6. Initially, Bitlocker is disabled, and it's advisable to enable it after Linux installation. Otherwise, a recovery key for Bitlocker will be required.

Install Ubuntu

The current guide doesn't encrypt the boot disk. It is possible to encrypt both / (root) and /boot partitions. Following guide has steps to encrypt everything except EFI, but there are limitations:

  • Grub2 supports only LUKS1 with PBKDF2 encryption vs Argon2 and other features of LUKS2.
  • There is a 5-10 seconds decryption delay after entering the password.
  • The password is requested before the Grub menu is displayed, so it is asked even if you are going to boot into Windows. As a workaround, it is possible to select another bootloader via BIOS boot menu. But when Windows is loaded via a different flow than previously, Bitlocker will request the key.

Install Ubuntu 22.04 alongside Windows 11

A separate /boot partition is needed, and it should not be encrypted. Root, users' /home, and other partitions can be encrypted.

  1. Boot from the USB disk.

  2. Select Try or Install Ubuntu in Grub.

  3. Select Try Ubuntu. Do not run the installation immediately. It is required to prepare the encrypted disk first.

  4. Use GParted or Disks to create partitions:

    • /boot - 768 MB size ext4
    • / - root partition with LUKS encryption. Set a simple password first. Once all setup is done and everything is working, you will set a strong password. Add LVM or plain ext4 inside the LUKS.
    • swap can be stored as a file in the encrypted root partition.
  5. Review what you have created.

    lsblk -f
    
    lsblk disk partitions example
    nvme0n1                                                                                             
    ├─nvme0n1p1
    │          vfat   FAT32                         8607-661C                                           
    ├─nvme0n1p2
    │                                                                                                   
    ├─nvme0n1p3         -- windows
    │          BitLoc 2                                                                                 
    ├─nvme0n1p4         -- windows recovery
    │          ntfs                                 A6EC4E8EEC4E5927                                    
    ├─nvme0n1p5
    │          ext4   1.0   /boot                   58cd424f-63fa-402a-85aa-d26db9485937                
    └─nvme0n1p6
              crypto 2                             aae8e0e4-786b-4ac3-b69a-10b2874dc49e                
      └─luks-aae8e0e4-786b-4ac3-b69a-10b2874dc49e
              ext4   1.0   rootfs                  c49fbe2b-6d73-400e-9962-ca5a8138ad42                
    
  6. Connect to WiFi.

  7. Run the Ubuntu installation and select:

    • Normal installation
    • Install updates during installation
    • Install 3rd-party drivers
  8. Select the "custom installation process".

  9. All partitions were previously created; it is required to choose them:

    • Select /boot partition with mount point /boot.
    • Select /dev/mapper/luks-aae8e0e4-786b-4ac3-b69a-10b2874dc49e for the root partition and specify / as the mount point.
    • Double-check the device for bootloader installation.
  10. Proceed with the installation. Do not reboot at the end.

  11. Mount the root & boot partitions and chroot into it:

    sudo mount /dev/mapper/luks-aae8e0e4-786b-4ac3-b69a-10b2874dc49e /mnt
    sudo mount /dev/nvme0n1p5 /mnt/boot
    sudo mount --bind /dev /mnt/dev
    sudo chroot /mnt
    mount -t proc proc /proc
    mount -t sysfs sys /sys
    mount -t devpts devpts /dev/pts
  12. Find the UUID of the LUKS partition via lsblk -f or sudo blkid /dev/nvme0n1p6.

  13. Create /etc/crypttab. Provide the UUID of the LUKS partition.

    sudo nano /etc/crypttab

    Content of the /etc/crypttab:

    # <target name> <source device> <key file> <options>
    # options used:
    #     luks    - specifies that this is a LUKS encrypted device
    #     discard - allows SSD TRIM command, WARNING: potential security risk (more: "man crypttab")
    rootfs   UUID=aae8e0e4-786b-4ac3-b69a-10b2874dc49e   none   luks,discard
    
  14. Verify the proper mapping between /etc/crypttab and /etc/fstab and update /dev/mapper/rootfs if needed:

    nano /etc/fstab
    /etc/fstab example
    # /etc/fstab: static file system information.
    #
    # Use 'blkid' to print the universally unique identifier for a
    # device; this may be used with UUID= as a more robust way to name devices
    # that works even if disks are added and removed. See fstab(5).
    #
    # <file system> <mount point>   <type>  <options>       <dump>  <pass>
    /dev/mapper/rootfs    /               ext4    errors=remount-ro 0       1
    # /boot was on /dev/nvme0n1p5 during installation
    UUID=f9365fe8-7b8a-41c4-9111-a8e250f73eca /boot           ext4    defaults        0       2
    # /boot/efi was on /dev/nvme0n1p1 during installation
    UUID=8607-661C  /boot/efi       vfat    umask=0077      0       1
    
  15. Update initramfs. Make sure there are no errors otherwise your setup may fail to boot. In case of errors review the configuration files. You might have some typo.

    sudo update-initramfs -k all -c
    
  16. Reboot if you had no errors on previous step.

Finish Encryption Setup for Ubuntu Partition

  1. Check which keyslots are in use:
    sudo systemd-cryptenroll /dev/nvme0n1p6
    
  2. Add extra passwords if needed:
    sudo systemd-cryptenroll /dev/nvme0n1p6 --password
    
  3. Create a recovery key:
    sudo systemd-cryptenroll --recovery-key /dev/nvme0n1p6
    
  4. Test passwords and recovery keys:
    sudo cryptsetup --verbose open --test-passphrase /dev/nvme0n1p6
    
  5. Reboot and verify that the new key was enrolled.
  6. Remove all unnecessary passwords:
    systemd-cryptenroll /dev/nvme0n1p6 --wipe-slot=<slot number>
    

TPM2 Security Issues

TPM2 may introduce additional security issues. See the links below:

TPM2 Support in Ubuntu

The main challenge with auto-decrypting via TPM password is that Ubuntu 22.04 uses an older dracut version, 054-1. This version doesn't have tpm2-tss module. To implement a simple workaround solution, a few additional modules files should be utilized from a more recent dracut build.

  1. Install the required packages:

    sudo apt install tpm2-tools tss2 dracut libcurl4 libjson-c5 libtss2-fapi1 libtss2-tcti-cmd0 libtss2-tcti-device0 libtss2-tcti-mssim0 libtss2-tcti-swtpm0
  2. Ensure TPM2 is available:

    systemd-cryptenroll --tpm2-device=list
    • Sample output when everything is okay:
      PATH        DEVICE     DRIVER 
      /dev/tpmrm0 IFX0785:00 tpm_tis
      
    • Sample output in case of missing TPM2 or errors:
      TPM2 support is not installed.
      
  3. Enroll in both the TPM and the LUKS volume:

    sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7+11+14 /dev/nvme0n1p6
  4. Add TPM2 modules from a recent dracut build.

    • Download dracut-059 release and unzip or find the required module files on dracut github
    • Below folders should be copied and added into the local folder /usr/lib/dracut/modules.d/
    01systemd-sysusers
    01systemd-udevd
    91tpm2-tss
    
  5. Add the tpm2-tss module dependency into dracut:

    echo "add_dracutmodules+=\" tpm2-tss \"" | sudo tee /etc/dracut.conf.d/tpm2.conf
    add_dracutmodules+=" tpm2-tss "
  6. Add tpm2-device=auto into /etc/crypttab according to the example:

    rootfs   UUID=aae8e0e4-786b-4ac3-b69a-10b2874dc49e   none   tpm2-device=auto,luks,discard
    
  7. Build the initramfs image using dracut:

    sudo dracut -f
    • Ensure there are no errors:
      dracut: dracut module 'tpm2-tss' cannot be found or installed.
      
  8. Check the resulting images. In the example below, image 26 is old and unchanged when image 27 is built with dracut. It should be safe to boot with the older kernel in case of any issues with the TPM2 setup.

    ls -la /boot
    
    /boot images example
    drwx------  4 root root      1024 Jan  1  1970 efi
    drwxr-xr-x  5 root root      4096 Apr 13 19:43 grub
    lrwxrwxrwx  1 root root        27 Apr 13 18:41 initrd.img -> initrd.img-6.5.0-27-generic
    -rw-r--r--  1 root root 129857748 Apr  2 19:49 initrd.img-6.5.0-26-generic
    -rw-r--r--  1 root root         0 Apr 13 19:06 initrd.img-6.5.0-26-generic.new
    -rw-r--r--  1 root root  23802175 Apr 13 21:32 initrd.img-6.5.0-27-generic
    lrwxrwxrwx  1 root root        27 Apr 13 18:39 initrd.img.old -> initrd.img-6.5.0-26-generic
    

TPM2 Setup Troubleshooting

  1. If you encounter issues during reboot, you may attempt to boot using an older kernel:

    • Once booted, you can remove dracut:
    sudo apt remove dracut
    
    • Rebuild the initramfs:
    sudo update-initramfs -k all -c
    
    • Update configurations and try again:
    sudo dracut -f
    
  2. In the worst case, boot from the live USB and mount the encrypted partition:

    sudo cryptsetup open /dev/nvme0n1p6 rootfs
    

    Next, chroot so you can uninstall dracut or attempt to fix your setup:

    sudo mount /dev/mapper/rootfs /mnt
    sudo mount /dev/nvme0n1p5 /mnt/boot
    sudo mount --bind /dev /mnt/dev
    sudo chroot /mnt
    mount -t proc proc /proc
    mount -t sysfs sys /sys
    mount -t devpts devpts /dev/pts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment