Full Disk Encryption: Difference between revisions
imported>Ulinja add section on unlocking secondary drives |
m fix consistency with wording "USB stick" and minor typos |
||
| (16 intermediate revisions by 11 users not shown) | |||
| Line 1: | Line 1: | ||
There are a few options for full disk encryption. | There are a few options for full disk encryption. The easiest way is to use the graphical installer and choose "encrypt" while doing the installation. | ||
= | = LVM on LUKS = | ||
In this example, everything except for the <code>/boot</code> partition is encrypted. | In this example, everything except for the <code>/boot</code> partition is encrypted. | ||
| Line 22: | Line 22: | ||
└─vg-root 254:2 0 225.3G 0 lvm / | └─vg-root 254:2 0 225.3G 0 lvm / | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Enter password on Boot == | |||
The initrd needs to be configured to unlock the encrypted <code>/dev/sda2</code> partition during stage 1 of the boot process. | The initrd needs to be configured to unlock the encrypted <code>/dev/sda2</code> partition during stage 1 of the boot process. | ||
| Line 29: | Line 31: | ||
boot = { | boot = { | ||
loader = { | loader = { | ||
canTouchEfiVariables = true; | efi.canTouchEfiVariables = true; | ||
grub = { | grub = { | ||
enable = true; | enable = true; | ||
| Line 42: | Line 44: | ||
With <code lang="nix">initrd.luks.devices.cryptroot.device = "/dev/disk/by-uuid/UUID-OF-SDA2";</code>, the initrd knows it must unlock <code>/dev/sda2</code> before activating LVM and proceeding with the boot process. | With <code lang="nix">initrd.luks.devices.cryptroot.device = "/dev/disk/by-uuid/UUID-OF-SDA2";</code>, the initrd knows it must unlock <code>/dev/sda2</code> before activating LVM and proceeding with the boot process. | ||
= Unattended Boot via USB = | == Unattended Boot via USB == | ||
Sometimes it is necessary to boot a system without needing | Sometimes it is necessary to boot a system without needing a keyboard and monitor. You will create a secret key, add it to a key slot and put it onto a USB stick. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
dd if=/dev/random of=hdd.key bs=4096 count=1 | dd if=/dev/random of=hdd.key bs=4096 count=1 | ||
cryptsetup luksAddKey /dev/sda1 ./hdd.key | cryptsetup luksAddKey /dev/sda1 ./hdd.key | ||
</syntaxhighlight> | </syntaxhighlight>You can enable fallback to password (in case the USB stick is lost or corrupted) by setting the <code>boot.initrd.luks.devices.<name>.fallbackToPassword</code> option to <code>true</code>. By default, this option is <code>false</code> so you will have to perform a manual recovery if the USB stick becomes unavailable (which you may prefer, depending on your use case). | ||
== Option 1: Write key onto the start of the stick == | |||
=== Option 1: Write key onto the start of the stick === | |||
This will make the | This will make the USB stick unusable for any other operations than being used for decryption. Write the key onto the stick: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
| Line 73: | Line 76: | ||
# pinning to /dev/disk/by-id/usbkey works | # pinning to /dev/disk/by-id/usbkey works | ||
keyFile = "/dev/sdb"; | keyFile = "/dev/sdb"; | ||
# optionally enable fallback to password in case USB is lost | |||
fallbackToPassword = true; | |||
}; | }; | ||
}; | }; | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
== Option 2: Copy Key as file onto a vfat | === Option 2: Copy Key as file onto a vfat USB stick === | ||
If you want to use your stick for other stuff or it already has other keys on it you can use the following method by Tzanko Matev. Add this to your <code>configuration.nix</code>: | If you want to use your stick for other stuff or it already has other keys on it you can use the following method by Tzanko Matev. Add this to your <code>configuration.nix</code>: | ||
| Line 95: | Line 100: | ||
boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' | boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' | ||
mkdir -m 0755 -p /key | mkdir -m 0755 -p /key | ||
sleep 2 # To make sure the | sleep 2 # To make sure the USB key has been loaded | ||
mount -n -t vfat -o ro `findfs UUID=${PRIMARYUSBID}` /key || mount -n -t vfat -o ro `findfs UUID=${BACKUPUSBID}` /key | mount -n -t vfat -o ro `findfs UUID=${PRIMARYUSBID}` /key || mount -n -t vfat -o ro `findfs UUID=${BACKUPUSBID}` /key | ||
''; | ''; | ||
| Line 105: | Line 110: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Unattended Boot via keyfile == | |||
A simpler but insecure option for unattended boots is to copy the keyfile into the initrd itself. | |||
{{warning|1=This method is not generally recommended as anyone with physical access to your boot partition will be able to retrieve the key file and use it to decrypt your luks partition. Make sure you understand the security implications.}} | |||
First move the key to a safe location. | |||
<syntaxhighlight lang="bash"> | |||
mkdir /var/lib/secrets | |||
chown root:root /var/lib/secrets | |||
chmod 700 /var/lib/secrets | |||
mv -v hdd.key /var/lib/secrets/ | |||
chmod 600 /var/lib/secrets/hdd.key | |||
</syntaxhighlight> | |||
Then add the key to the initrd. | |||
<syntaxhighlight lang="nix"> | |||
let | |||
keyFile = "hdd.key"; | |||
in | |||
{ | |||
boot.initrd.luks.devices."root" = { | |||
device = "/dev/disk/by-uuid/<uuid>"; | |||
keyFile = "/${keyFile}"; | |||
}; | |||
boot.initrd.secrets = { "/${keyFile}" = /var/lib/secrets/${keyFile}; }; | |||
} | |||
</syntaxhighlight> | |||
== Store key on FIDO2 device or TPM == | |||
Unattended boot can also happen with a FIDO2 device (e.g. Yubikey) or TPM. This cannot be performed in a fully declarative way because every such security device is unique; some manual running of <code>systemd-cryptenroll</code> is required. | |||
For FIDO2, directly read the [https://github.com/NixOS/nixpkgs/blob/7be68f763d94cdb4c809b7980647828e3274a511/nixos/doc/manual/configuration/luks-file-systems.section.md chapter in the official manual]. | |||
For TPM, replace the crypttab and systemd-cryptsetup option <code>fido2-device=auto</code> with <code>tpm-device=auto</code> for systemd stage 1. See [https://github.com/NixOS/nixpkgs/blob/7be68f763d94cdb4c809b7980647828e3274a511/nixos/tests/systemd-initrd-luks-tpm2.nix this integration test] in the nixpkgs source code repository. | |||
Because the TPM is attached to your computer, it provides no protection against a stolen computer when used on its own (it usually allows for setting a password, but that is it). It can only protect against a stolen drive. | |||
= zimbatm's laptop recommendation = | = zimbatm's laptop recommendation = | ||
| Line 225: | Line 268: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ | { | ||
environment.etc.crypttab.text = '' | |||
cryptstorage UUID=UUID-OF-SDB /root/mykeyfile.key | cryptstorage UUID=UUID-OF-SDB /root/mykeyfile.key | ||
'' | ''; | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 234: | Line 277: | ||
Again, the secondary drive will be unlocked and made available under <code>/dev/mapper/cryptstorage</code> for mounting. | Again, the secondary drive will be unlocked and made available under <code>/dev/mapper/cryptstorage</code> for mounting. | ||
= Autologin using LUKS password = | |||
One downside of full disk encryption is that you need to type in your password twice, once for unlocking the disk and once to log into your desktop. One approach is to skip the LUKS password, such as by using a TPM2, but is [https://oddlama.org/blog/bypassing-disk-encryption-with-tpm2-unlock/ difficult to properly secure]. The other approach is to enable autologin for your display manager: | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
services.displayManager.autoLogin.user = "my username"; | |||
} | |||
</syntaxhighlight> | |||
However, this breaks software such as KWallet which uses the login password to automatically unlock its keyring. The solution is to set the LUKS password, login password, and KWallet keyring password all to the same string, and then use the LUKS password to unlock KWallet. The LUKS password is first collected by a systemd initrd, saved to the kernel keyring, read out by SDDM via a PAM module, then finally passed off to KWallet. | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
boot.initrd.systemd.enable = true; | |||
systemd.services.display-manager.serviceConfig.KeyringMode = "inherit"; | |||
security.pam.services.sddm-autologin.text = pkgs.lib.mkBefore '' | |||
auth optional ${pkgs.systemd}/lib/security/pam_systemd_loadkey.so | |||
auth include sddm | |||
''; | |||
} | |||
</syntaxhighlight> | |||
= Further reading = | = Further reading = | ||
| Line 242: | Line 306: | ||
* Have a look at https://wiki.archlinux.org/index.php/Disk_encryption to see all the possible options. This wiki page is not complete. | * Have a look at https://wiki.archlinux.org/index.php/Disk_encryption to see all the possible options. This wiki page is not complete. | ||
* [https://gist.github.com/ladinu/bfebdd90a5afd45dec811296016b2a3f Installation with encrypted /boot] | * [https://gist.github.com/ladinu/bfebdd90a5afd45dec811296016b2a3f Installation with encrypted /boot] | ||
* [[Remote | * [[Remote disk unlocking|Using Tor and SSH to unlock your LUKS Disk over the internet]]. | ||
* [[Bcachefs]], filesystem which supports native encryption | |||
* [https://discourse.nixos.org/t/full-disk-encryption-tpm2/29454/2 Automatically unlock encrypted disks using TPM2] | |||
[[Category:Desktop]] | |||
[[Category:Server]] | |||