DEV Community

Achyuta Das
Achyuta Das

Posted on • Edited on

Full Disk Encryption (FDE) with Ubuntu Autoinstall

🔍 Context

As system administrators and security-conscious developers, encrypting data at rest is a fundamental best practice—especially for laptops, servers in untrusted environments, or sensitive workloads. Full Disk Encryption (FDE) ensures that all data on the disk is encrypted, and can only be accessed after providing a unlocking key, thus safeguarding data even if physical access to the disk is obtained.

By leveraging cloud-init's autoinstall YAML, we can fully automate the provisioning process—including LUKS encryption, LVM setup, and embedding a drive unlocking key into the initramfs.

🛠️ Implementation Overview

Here’s a high-level overview of what we will be doing:

  • Use LUKS to encrypt the main data partition.
  • Inside the encrypted container, create a LVM volume group to manage the logical volumes.
  • Generate a random key file early in the installation process, which is used to unlock the encrypted volume.
  • Ensured this key is securely copied into the target system and embedded into the initramfs so the system can boot without manual passphrase entry.

đź§Ş Workflow

  • Early Commands: Generate a 4KB random keyfile (root.key) under /etc/cryptsetup-keys.d, with appropriate permissions.
early-commands: - mkdir -p /etc/cryptsetup-keys.d - dd if=/dev/urandom of=/etc/cryptsetup-keys.d/root.key bs=1024 count=4 - chmod 600 /etc/cryptsetup-keys.d/root.key 
Enter fullscreen mode Exit fullscreen mode
  • Storage config: The disk was partitioned into:
    • An EFI system partition (/boot/efi)
    • An unencrypted /boot partition
    • A third partition for encrypted data.

Create a LUKS-encrypted volume on the third partition using the key file. On top of that, create a LVM volume group (VolGroup) and allocate a root logical volume (lv_root).

 storage: config: - ptable: gpt match: size: smallest wipe: superblock-recursive preserve: false name: '' grub_device: true id: disk-sda type: disk - device: disk-sda size: 536870912 # 512MB wipe: superblock flag: boot number: 1 preserve: false grub_device: true id: partition-0 type: partition - fstype: fat32 volume: partition-0 preserve: false id: format-0 type: format - path: /boot/efi device: format-0 id: mount-0 type: mount - device: disk-sda size: 1073741824 # 1GB wipe: superblock number: 2 preserve: false grub_device: false id: partition-1 type: partition - fstype: ext4 volume: partition-1 preserve: false id: format-1 type: format - path: /boot device: format-1 id: mount-1 type: mount - device: disk-sda size: -1 wipe: superblock number: 3 preserve: false grub_device: false id: partition-2 type: partition - name: cryptlvm volume: partition-2 preserve: false keyfile: /etc/cryptsetup-keys.d/root.key id: dm_crypt-lvm type: dm_crypt - name: VolGroup devices: - dm_crypt-lvm preserve: false id: lvm_volgroup-0 type: lvm_volgroup - name: lv_root volgroup: lvm_volgroup-0 size: -1 wipe: superblock preserve: false id: lvm_partition-root type: lvm_partition - fstype: ext4 volume: lvm_partition-root preserve: false id: format-root type: format - path: / device: format-root id: mount-root type: mount 
Enter fullscreen mode Exit fullscreen mode
  • Late Commands:
    • Extract the UUID of the LUKS volume and copy the key file into /etc/cryptsetup-keys.d inside the target filesystem, renaming it to match the UUID.
    • Update /etc/crypttab to ensure the system knows how to unlock the encrypted volume during boot.
    • Add the appropriate hook configuration for cryptsetup-initramfs and rebuilt the initramfs so the key file will be included and accessible early in the boot process.
 late-commands: - mkdir -p /target/etc/cryptsetup-keys.d /target/etc/cryptsetup-initramfs - bash -c ' luks_uuid=$(blkid -t TYPE=crypto_LUKS -s UUID -o value); cp /etc/cryptsetup-keys.d/root.key "/target/etc/cryptsetup-keys.d/${luks_uuid}.key"; chmod 600 "/target/etc/cryptsetup-keys.d/${luks_uuid}.key"; echo "dm_crypt-lvm UUID=${luks_uuid} /etc/cryptsetup-keys.d/${luks_uuid}.key luks" > /target/etc/crypttab; echo "KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key" >> /target/etc/cryptsetup-initramfs/conf-hook; ' - curtin in-target --target=/target -- update-initramfs -c -k all 
Enter fullscreen mode Exit fullscreen mode

âś… Conclusion

With this setup, we successfully created a secure, automated Ubuntu installation with full disk encryption using LUKS and LVM. The system boots without requiring a passphrase, thanks to the securely handled key file integrated into the initramfs.
This makes the setup highly suitable for hands-off provisioning in secure environments.

Looking ahead, this foundation can be extended to further enhance security by:

  • Binding the LUKS key to a TPM after installation to enable secure, passphrase-free unlocks based on hardware identity.
  • Integrating with Secure Boot and measured boot for a trusted boot chain.

Top comments (0)