There are many possible encrypted root setups. This guide is for setting up LVM over Luks, which is an easy and safe setup that will satisfy most users. Other setups should still be sufficiently similar.
edit ImportantHere you will find *only* NixOS-specific bits. For general information regarding this setup, how to partition disks and such refer to [1] or other detailed guide. edit Updating from how it was previouslyLuks got changed lately (see mailinglist from 3.3.2012 titled "[Nix-dev] luks changes") If you had:
boot.initrd.luksRoot = "/dev/sda2";
Then now you have to write:
boot.initrd.luks.enable = true;
boot.initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; } ];
edit the configuration of /etc/nixos/configuration.nixIn this example we assume that:
edit Make sure initrd finds and mounts the root partitionThe current implementation always opens the luks devices in the stage1 (before mounting the rootfs). This part of configuration.nix will make cryptsetup luksOpen to be called after the LVM initialisation for /dev/sda2 to the name 'luksroot':
boot.initrd.luks.enable = true;
boot.initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; } ];
You can extend the list, if you have for example a ciphered swap partition too, or any else:
boot.initrd.luks.devices = [
{ name = "luksroot"; device = "/dev/sda2"; }
{ name = "swap"; device = "/dev/sda3"; }
];
Notice that you will have to set the root filesystem to be mounted from the device /dev/mapper/luksroot, and the swap enabled for the device /dev/mapper/swap. Or, if you set labels, you can use the labels. In case you had luks *over* LVM, you want to luksOpen the device *before* lvm vgscan gets called:
boot.initrd.luks.devices = [
{ name = "luksroot"; device = "/dev/sda2"; preLVM = true; }
];
edit creating encrypted swapIf you don't use LVM then you have a problem with creating and using an encrypted swap. One approach would be to unlock the swap partition with a keyfile instead of a random key: First create a normal encrpyted partition and after unlocking it, format it as swap space using mkswap. cryptsetup luksFormat /dev/sdXY cryptsetup luksOpen /dev/sdXY swap mkswap /dev/mapper/swap Then create a keyfile for auto-unlocking swap and store it in the root folder (if this is your first installation store it in /mnt/root/) and add it to the swap partition dd if=/dev/urandom of=/root/keyfile bs=1024 count=1 chmod 0400 /root/keyfile cryptsetup luksAddKey /dev/sdXY /root/keyfile Then, in this case, you can't benefit from the current boot.initrd.luks, because it does not support keyfile. As in the stage1 the rootfs gets mounted to /mnt-root, you can use this postMountCommands to get the swap dmcrypt device opened.
boot.initrd.postMountCommands = "cryptsetup luksOpen --key-file /mnt-root/root/keyfile /dev/sdaXY swap";
swapDevices = [
{ device = "/dev/mapper/swap"; }
];
edit no encrypted root filesystem, no encrypted swap but only encrypted /homeIf you only want to have an encrypted home directory, you need to set something like this, for example:
boot.initrd.luks.enable = true;
boot.initrd.device = [ { device = "/dev/sda3"; name = "lukshome"; };
edit Extra kernel modules you might needDepending on the encryption algorithm you have chosen for your Luks volume, you will probably need to ensure kernel has the necessary crypto modules. If you are unsure which ones, run cryptsetup luksDump /dev/sda2 What you are looking for is this: LUKS header information for /dev/sda2 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 In this example you need SHA1, SHA256, AES, and CBC. You can put the required crypto modules into initrd along with dm_crypt module needed by Luks like this: boot.initrd.kernelModules = ["dm_crypt" "aes-i586" "sha256" "sha1" "cbc"]; On my 64bit system (2.6.32) I needed this modules instead the listed above: boot.initrd.kernelModules = ["dm_crypt" "sha256_generic" "sha1_generic" "cbc" "aes_x86_64" "aes_generic" "xts" ];
edit Root Filesystem
fileSystems = [ {
mountPoint = "/";
device = "/dev/mapper/vg-root";
#device = "/dev/mapper/luksroot"; # use this instead when NOT using LVM
} {
mountPoint = "/boot";
device = "/dev/sda1";
}
#other filesystems go here
]
edit Mounting from a rescue systemWithin the rescue system: # cryptsetup luksOpen /dev/sda2 crypt # vgscan # vgchange -ay Now your logical volumes should be available. |