Gentoo Encrypted Root, with LUKS and LVM
2009-12-20 11:22 - Linux
I'm upgrading my home server to be a bit beefier, as I've started using it for some video processing and other demanding tasks. Along the way of configuring a new blank machine from scratch, I decided to set up disk encryption (better safe than sorry, eh?), something I've never done for a linux server before. I found it a bit tricky, so here's a log, with some explanations, of what I did. If it's useful to you, great! It's geared towards the Gentoo linux distribution, as that's what I use and love, and generally towards experts. If you don't understand anything below, please research it, before you try to do something like this.
-
Boot a recent Gentoo Minimal LiveCD. I used install-x86-minimal-20091103.iso. Anything newer than that should probably also work.
-
Work through the Gentoo Handbook until step 4. Using fdisk as described there, define one small partition (I used 256M) to boot from, and one more taking the rest of the drive. This left me with:
# fdisk -l /dev/sda Disk /dev/sda: 640.1 GB, 640135028736 bytes 255 heads, 63 sectors/track, 77825 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x83e6d949 Device Boot Start End Blocks Id System /dev/sda1 1 34 273073+ 83 Linux /dev/sda2 35 77825 624856207+ 83 Linux
With that done, format the boot partition:
# mke2fs /dev/sda1 mke2fs 1.41.3 (12-Oct-2008) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 68272 inodes, 273072 blocks 13653 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67633152 34 block groups 8192 blocks per group, 8192 fragments per group 2008 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185 Writing inode tables: done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 20 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
And the encrypted partition:
# cryptsetup --verify-passphrase luksFormat /dev/sda2 WARNING! ======== This will overwrite data on /dev/sda2 irrevocably. Are you sure? (Type uppercase yes): YES Enter LUKS passphrase: Verify passphrase: Command successful.
-
At this point we need to set up the encrypted partition layer.
# cryptsetup luksOpen /dev/sda2 root
In order to get multiple "partitions" inside the single encrypted layer, we set up LVM. I keep /tmp (nosuid and no execute), as well as /var (in case logs fill it up) and /home, separate from /, so I did:
# pvcreate /dev/mapper/root Physical volume "/dev/mapper/root" successfully created # vgcreate vg /dev/mapper/root Volume group "vg" successfully created # lvcreate --size 1G --name swap vg Logical volume "swap" created # lvcreate --size 10G --name root vg Logical volume "root" created # lvcreate --size 1G --name tmp vg Logical volume "tmp" created # lvcreate --size 10G --name var vg Logical volume "var" created # lvcreate --extents 100%FREE --name home vg Rounding up size to full physical extent 573.90 GB Logical volume "home" created # vgchange --available y 5 logical volume(s) in volume group "vg" now active
Use vgs or vgdisplay to find out how much room you have left for the last logical volume.
Format these partitions as you like, I did:
# mkswap /dev/mapper/vg-swap Setting up swapspace version 1, size = 1048572 KiB no label, UUID=b43468c8-8652-4035-9227-6ef562975dbd # mkfs.xfs /dev/mapper/vg-root meta-data=/dev/mapper/vg-root isize=256 agcount=4, agsize=655360 blks = sectsz=512 attr=2 ... # mkfs.xfs /dev/mapper/vg-tmp meta-data=/dev/mapper/vg-tmp isize=256 agcount=4, agsize=65536 blks = sectsz=512 attr=2 ... # mkfs.xfs /dev/mapper/vg-var meta-data=/dev/mapper/vg-var isize=256 agcount=4, agsize=655360 blks = sectsz=512 attr=2 ... # mkfs.xfs /dev/mapper/vg-home meta-data=/dev/mapper/vg-home isize=256 agcount=4, agsize=37611264 blks = sectsz=512 attr=2 ...
-
Continue with the Gentoo Handbook, until step seven. We need cryptsetup installed and configured properly before we build our kernel, so first emerge cryptsetup. Now follow step seven as normal, but be sure to use genkernel. Do not use any splash, vga or framebuffer related options (trying to use these caused me lots of grief).
# genkernel --menuconfig --install --symlink --lvm --luks all * Gentoo Linux Genkernel; Version 3.4.10.904 * Running with options: --menuconfig --install --symlink --lvm --luks all * Linux Kernel 2.6.28-hardened-r9 for x86... * kernel: >> Running mrproper... * config: Using config from /etc/kernels/kernel-config-x86-2.6.28-hardened-r9 * Previous config backed up to .config.bak * >> Running oldconfig... * kernel: >> Cleaning... * config: >> Invoking menuconfig... *** End of Linux kernel configuration. *** Execute 'make' to build the kernel or try 'make help'. * >> Compiling 2.6.28-hardened-r9 bzImage... * >> Compiling 2.6.28-hardened-r9 modules... * Copying config for successful build to /etc/kernels/kernel-config-x86-2.6.28-hardened-r9 * busybox: >> Using cache * initramfs: >> Initializing... * >> Appending base_layout cpio data... * >> Appending auxilary cpio data... * >> Appending busybox cpio data... * >> Appending lvm cpio data... * LVM: Adding support (compiling binaries)... * >> Appending luks cpio data... * Including LUKS support * >> Appending modules cpio data... * * Kernel compiled successfully! ...
Since you might be running genkernel again in the future, for upgrades, it might be worth looking at /etc/genkernel.conf to set the options passed on the commandline, above. In the config step be sure to include these kernel options statically (not as a module):
Device Drivers ---> [*] Multiple devices driver support (RAID and LVM) ---> <*> Device mapper support <*> Crypt target support -*- Cryptographic API ---> *** Digest *** -*- SHA224 and SHA256 digest algorithm *** Ciphers *** <*> AES cipher algorithms
-
The machine I'm setting up has some sort of problem with grub. I'm not sure what, but it detects free memory incorrectly, thinks there's 0k available, and refuses to run anything, because 0k is not enough room. So at the bootloader step, this time I'm using LILO. So:
# echo "sys-boot/lilo device-mapper" >> /etc/portage/package.use # emerge lilo
Then, I need to properly fill out /etc/lilo.conf, based on Handbook step 10c. Note the crypt_root, which is the real device, encrypted with LUKS, and the real_root which is the virtual (LVM) device, under the LUKS encryption layer, that we tell the kernel is the real root, after LUKS and LVM has been set up properly.
append="init=/linuxrc dolvm crypt_root=/dev/sda2 real_root=/dev/mapper/vg-root" boot=/dev/sda compact default=gentoo lba32 prompt read-only root=/dev/ram0 timeout=50 image=/boot/kernel initrd=/boot/initramfs label=gentoo image=/boot/kernel.old initrd=/boot/initramfs.old label=backup optional
Finally, install LILO as the boot loader with:
# /sbin/lilo Added gentoo * Added backup
-
Continue with the Gentoo Handbook, which at this point is basically just rebooting and using the system!
If something goes wrong somewhere in the middle, and you need to re-boot from the LiveCD, and mount your virtual encrypted partitions, it should go something like:
# cryptsetup luksOpen /dev/sda2 sda2 Enter LUKS passphrase: padlock: VIA PadLock not detected. padlock: VIA PadLock Hash Engine not detected. key slot 0 unlocked. Command successful. # vgscan Reading all physical volumes. This may take a while ... Found volume group "vg" using metadata type lvm2 # vgchange -ay 5 logical volume(s) in volume group "vg" now active
Then a bunch of mount commands.
It was a bit difficult to find all the right information to make this happen. Some of the references I used:
- http://blog.pioto.org/encryption/
- http://www.saout.de/tikiwiki/tiki-index.php?page=LUKSOnGentoo
- http://en.gentoo-wiki.com/wiki/AES-encrypted_root_partition_using_LVM2
- http://www.linux.com/archive/feature/36596
- http://forums.remote-exploit.org/bt4beta-howtos/20218-bt4-encrypted-hdd-install-using-luks-lvm.html
2010-01-02 12:35 - tvhwy
Thank you very much for these instructions, which deserve a place in official Gentoo documentation. I had been trying periodically for months to make an encrypted root, using some of the same sources you cited. I knew little about genkernel, luks, or LVM before. Now I feel competent.
It worked almost perfectly. My password would not unlock the key slot at boot time until I compiled some more Cryptographic API features into the kernel. Since cryptsetup luksDump told me my encrypted partition uses an SHA hash, I chose every feature with "SHA" in its description. I also built in every mode of operation not marked EXPERIMENTAL. (I am using kernel 2.6.31-r6 on amd64.)
I wish I had approached the problem more scientifically so I could tell you which change did the trick. But I didn't want to wait for genkernel to compile after each change!
GRUB worked when I had it pass almost the same kernel arguments you did with LILO. I did not try to append a ramdisk argument; there was no ill effect, perhaps because an 8M ramdisk was set as default in my kernel configuration. Framebuffer arguments didn't hurt me, though their effective function continued to elude me!