Add instructions for suspend/hibernate with an encrypted swap partition and/or file
seanthegeek opened this issue · comments
The Ubuntu 20.04 btrfs-luks guide states:
As I have no use for hibernation or suspend-to-disk, I will simply use a random password to decrypt the swap partition using the crypttab
For my use case, I need to have a fully encrypted laptop with suspend-to-disk/hibernate support. How can I do this? The section about it in dm-crypt/Swap encryption is not clear to me.
Once I find some time, I will update the guides for 21.04 and will show how to enable hibernation. In Pop!_OS it is very easy by simply encrypting the swap partition in your crypttab. I am not sure whether this will also work in Ubuntu and what changes are required in Grub. I will leave this issue open until I update the guides.
Same problem here: I can't get hibernation to work properly. I've done a ton of research, but can't seem to get the kernelstub or crypttab configuration correct. When I try to hibernate, journalctl reports PM: Image not found (code -22). My encrypted swap partition is working correctly (I've tested it) for everything but hibernation. I guess the hibernation file is never being written? Not sure. Either way, your help getting this working would be very much appreciated. And thank you for the great BTRFS + LUKS + PopOS tutorial! I learned a lot.
+1 on this, 21.04 guide for luks+btrfs worked great but I can't get the hibernation to work as guides are all over the place online
Fyi there is also a lengthy discussion on the discourse of Ubuntu Re-visiting hibernate on ubuntu.
That discussion was pretty unhelpful. I don't know how you got it working with a /dev/urandom encrypted swap.
I was able to get it working by making the swap luks partition use a passphrase instead of the random keyfile. But then I had two type two passwords on startup and resume. I could not get resume to work with a static key-file on the encrypted root partition at all.
Then I was able to get it to work using a swap-file on the encrypted root partition. No swap partition needed. This is the way to do it as far as I'm concerned.
The following three links will help you setup a swapfile on BTRFS, use a swap file instead of a partition, and setup hibernation to that swapfile on Pop OS:
I spent a lot of time trying to find a solution to this. Hopefully one day I'll get around to making polished instructions in a PR, but here's an info dump for now:
TL;DR swap partition encrypted with a /dev/urandom key will not support hibernation. In theory you could make a keyscript to make it work by saving the random key on disk somewhere, but there are literally zero benefits to this approach. Just use your data partition password (or a separate password) to unlock swap directly.
For any auto-login users, consider using keyscript=decrypt_keyctl
as in method 2. Then you can unlock your keyring with the encryption password.
Source
Method 1: Separate Password
Note that you will have to enter two passwords on every startup (from shutdown or hibernate).
- Create a LUKS partition for swap with a password of choice:
cryptsetup luksFormat /dev/nvme0n1p3
- Change the line for the swap partition in
/etc/crypttab
to look like this:
cryptswap UUID=bla-bla-bla none luks,discard,swap
- Add
"resume=/dev/mapper/cryptswap"
as a kernel flag:
sudo kernelstub -a "resume=/dev/mapper/cryptswap"
(or manually add it to the "user" section of /etc/kernelstub/configuration
)
-
Add line
RESUME=/dev/mapper/cryptswap
to/etc/initramfs-tools/conf.d/resume
, or replaceRESUME
line if it exists. -
Update initramfs:
update-initramfs -c -k all
Method 2 (Recommended): Kernel Keyring
Feel free to read the top of /usr/lib/cryptsetup/scripts/decrypt_keyctl
or the linked source for an explanation. Basically, your LUKS password(s) can be cached in the kernel keyring and used to unlock other partitions or even unlock the keyring.
- Create a LUKS partition for swap with the same password as cryptdata:
cryptsetup luksFormat /dev/nvme0n1p3
- Change
/etc/crypttab
to look like this:
cryptdata UUID=something-something none luks,discard,keyscript=decrypt_keyctl
cryptswap UUID=bla-bla-bla none luks,discard,swap,tries=1,keyscript=decrypt_keyctl
- Add
"resume=/dev/mapper/cryptswap"
as a kernel flag:
sudo kernelstub -a "resume=/dev/mapper/cryptswap"
(or manually add it to the "user" section of /etc/kernelstub/configuration
)
-
Add line
RESUME=/dev/mapper/cryptswap
to/etc/initramfs-tools/conf.d/resume
, or replaceRESUME
line if it exists. -
Update initramfs:
update-initramfs -c -k all
Source plus sources from method 1
Method 3: Swap as LVM Volume
I have not tried this at all, but it should be possible to create a swap partition inside cryptdata using lvcreate -C
. That way only one cryptdevice needs to be unlocked to decrypt both data and swap. Of course you will need to specify UUIDs rather than /dev/mapper/cryptswap
in /etc/fstab
, the kernelstub configuration, and /etc/initramfs-tools/conf.d/resume
.
Source
As an aside, my primary motivation for this was to ensure nothing is left decrypted after a period of extended inactivity. That is, I want the system to always hibernate after sitting in suspend for some time. Creating a symlink /etc/systemd/system/systemd-suspend.service
that points to /usr/lib/systemd/system/systemd-suspend-then-hibernate.service
overrides the normal suspend mode with suspend-then-hibernate, no matter how the suspend is triggered (power menu, inactivity, command line, etc.). HibernateDelaySec
in /etc/systemd/sleep.conf
controls how long the system will stay in suspend before hibernating (you can set it in minutes like HibernateDelaySec=30min
). Of course this behavior is not necessary for working hibernation, but it will ensure the system can't stay decrypted (and running) indefinitely.
Source 1, Source 2
Thank you for this; this should provide ample information for those who want to try out the different methods.