Preseeding Full Disk Encryption

Usually I try to write articles that are not aimed at a particular distribution. Although I may give examples assuming a Debian-based distribution, whenever possible, I try to make my instructions applicable to everyone. This is not going to be one of those articles. Here, I document a process I went through recently with Debian preseeding (a method of automating a Debian install, like kickstart on Red Hat-based systems) that I found much more difficult than it needed to be, mostly because documentation was so sparse. In fact, I really found only two solid examples to work from in my research, one of which referred to the other.

In this article, I describe how to preseed full-disk encryption in a Debian install. This problem came up as I was trying to create a fully automated "OEM" install for a laptop. The goal was to have an automated boot mode that would guide users through their OS install and use full-disk encryption by default, but would make the process as simple as possible for users. Normally, unless you are going to encrypt the entire disk as one big partition, the Debian installer makes you jump through a few hoops to set up disk encryption during an install.

In my case, I couldn't just use the full disk, because I needed to carve off a small section of the disk as a rescue partition to store the OEM install image itself. My end goal was to make it so users just had to enter their passphrase, and it would set up an unencrypted /boot and rescue disk partition and an encrypted / and swap. As an additional challenge, I also wanted to skip the time-consuming disk-erasing process that typically happens when you enable disk encryption with Debian, since the disk was going to be blank to start with anyway.

Unfortunately, although there is a lot of documentation on how to automate ordinary partitioning and LVM with preseeding (I actually wrote a whole section on the topic myself in one of my books), I had a hard time finding much documentation on how to add encryption to the mix. After a lot of research, I finally found two posts (and as I mentioned, one of them referenced the other) that described the magic incantation that would enable this. Unfortunately, the only supported mode for encrypted disks in Debian preseed requires the use of LVM (something I confirmed later when I read the source code responsible for this part of the install). That's not the end of the world, but it would have been simpler in my mind if it didn't have that requirement.

Since you need a basic unencrypted /boot partition to load a kernel and prompt the user for a passphrase, I had to account for both and preserve a small 2GB rescue disk partition that already was present on the disk. After that, the remaining / and swap partitions were encrypted. Here is the partition section of the preseed config:

d-i partman-auto/method string crypto
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-lvm/confirm boolean true
d-i partman-auto-lvm/guided_size string max
d-i partman-auto-lvm/new_vg_name string crypt
d-i partman-auto/disk string /dev/sda
d-i partman-auto/choose_recipe select root-encrypted
d-i partman-auto/expert_recipe string                         \
      root-encrypted ::                                       \
              500 500 500 ext3                                \
                      $primary{ } $bootable{ }                \
                      method{ format } format{ }              \
                      use_filesystem{ } filesystem{ ext4 }    \
                      mountpoint{ /boot }                     \
              .                                               \
              2000 2000 2000 linux-swap                       \
                      $lvmok{ } lv_name{ swap }               \
                      in_vg { crypt }                         \
                      $primary{ }                             \
                      method{ swap } format{ }                \
              .                                               \
              500 10000 1000000000 ext4                       \
                      $lvmok{ } lv_name{ root }               \
                      in_vg { crypt }                         \
                      $primary{ }                             \
                      method{ format } format{ }              \
                      use_filesystem{ } filesystem{ ext4 }    \
                      mountpoint{ / }                         \
              .                                               \
              2000 2000 2000 ext4                             \
                      $primary{ }                             \
                      method{ keep }                          \
                      use_filesystem{ } filesystem{ ext4 }    \
                      label{ rescuedisk }                     \

d-i partman-md/device_remove_md boolean true
d-i partman-basicfilesystems/no_mount_point boolean false
d-i partman-partitioning/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true


Kyle Rankin is SVP of Security and Infrastructure at Zero, the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin