Is it possible to have multiple partitions in a single LUKS or cryptsetup container? If so, how?
While I haven't found anything online describing such a setup, it turns out to work ok. Some advantages are you only have to enter your password once, and tools that can resize partitions work without having to know about the crypto layer. But there are other solutions for entering your password only once, and gnome partition editor is nowadays able to move/resize encrypted partitions too, so this is not really recommended. Plus, nobody seems to be doing this so there isn't much help online.
If you want to do this anyway:
- Create a LUKS encrypted volume any way you like and mount it.
If the volume is named
cryptvolumeit will appear in
- Open the volume with GParted:
gparted /dev/mapper/cryptvolumeChoose device > create partition table (alternatively, use a command line tool to create a partition table) Now you can create partitions in GParted any way you like.
- Create lines in
/etc/fstabif you want to mount the volume automatically on startup. There are may descriptions online of how to do that so I won't cover it here.
This should in principle be enough to have a working multi-partition LUKS container, and on Ubuntu 18.04 this works. Except that when rebooting this causes an error as systemd is not able to mount the encrypted partition(s). What's missing is that nothing tells the kernel to re-scan partition tables after the encrypted volume has been decrypted. The command to do that is
partprobe. On systemd systems, to tell the system to run partprobe at the right time, put the following file at
cryptdisk1.mount with the appropriate mount point(s) for your system and
/dev/mapper/cryptdisk with the path to the decrypted LUKS device.
[Unit] Description=partprobe after cryptsetup # By default services depend on partitions being mounted. Leaving this out leads to cyclic dependencies. DefaultDependencies=no # We don't need to Requires=cryptsetup.target, as cryptsetup.target is always present After=cryptsetup.target # The mount target is named after the mount path. # Run `systemctl list-dependencies local-fs.target` to list mount targets. Before=cryptdisk1.mount [Service] Type=oneshot # You don't have to specify the path to the decrypted device, but doing so will speed up the boot a bit ExecStart=/sbin/partprobe /dev/mapper/cryptdisk [Install] # Required by local-fs.target or by all the partitions in the LUKS container to be more specific RequiredBy=cryptdisk1.mount
After creating the file run
sudo systemctl enable partprobe.service to enable the file.
This has been tested on Ubuntu 18.04 with GPT partitions. On different systems paths may differ. For non-systemd systems you will need to find a different way to run partprobe before the partitions are mounted.