Your Linux Data Center Experts

Encrypted root With LVM on Fedora 8

By  Sean Reifschneider Date November 24, 2007

Overview

This recipe details how you can install F8 (and most likely also F7 and CentOS 5) on a system such that everything except /boot is encrypted. This recipe makes use of your full disc (no unused space is left after it's completed), and doesn't require booting into a Live DVD (important because many of my machines don't have DVD drives on them, many don't even have CD drives). It also does not require a second hard drive.

I think this procedure is one of the easiest to do, and doesn't require any resources to do beyond what a normal install would require. The end result is the same as what you would get if you had done a normal install using LVM for the root and swap. It also supports hibernation to an encrypted swap partition. Installation can be done via PXE as well as from the DVD.

Introduction

Stories abound about laptops being lost, and data possibly exposed because of it. I'm also concerned about someone breaking into my house and stealing our backup server, and through that exposing sensitive or confidential client data for many of our customers. I'm actually not that worried about the loss of the machines, they're cheap computers and data on our home backup server is duplicated at our facility. So, I like to run encrypted file-systems.

The benefits are huge. It's very convenient, you don't have to encrypt and decrypt things as you need the. Though I still do encrypt particularly sensitive data (ssh keys, access information), it's nice to know that the loss of my laptop is unlikely to reveal sensitive information that I don't normally think of as high security (and therefore specifically encrypt). I don't have to worry about leakage of things that can reveal more information than I'd like about our customers and clients, and our business.

Of course, it's not an end-all security mechanism. You absolutely have to protect your system to prevent access to the unencrypted file-system. For example, keeping up to date on patches, and locking or hibernating your computer when you are away from the keyboard... For example, I always type Ctl-Alt-L when I leave my keyboard, or before I suspend, to make sure that if someone were able to get to it they don't have access to my sessions.

Before you Begin

Note that in the below instructions it assumes that you will be installing to a whole disc (wiping anything else that was on the system). These procedures should be able to be adapted to a dual-boot system, but I don't run any dual boot systems, so someone else will need to provide "patches" to this procedure for such a thing.

This recipe also assumes that your disc is named "sda". If your disc is named something else, you will have to adapt the information below.

Severe Data Loss Warning

This procedure wipes everything on your current disc, if you follow them exactly. Additionally, if you forget your pass-phrase, any data on your system is gone. Any important data you have should be backed up in at least several locations.

Step One: Formatting the Disc

The first thing that needs to happen is to partition the disc. The installer partitioning software doesn't have the flexibility to be able to do this, so you'll need to boot into the installer.

Once in the installer, you should be able to use Ctl-Alt-F2 to get a root prompt. Then run:

fdisk /dev/sda

You need to create an "sda1" which is around 100MB, has the boot flag set, and is of type 83 (Linux), and "/dev/sda3" which is around 10GB (but less than half the remaining space on the drive), and is at the end of the disc, and partition type 8e (Linux LVM). When done, it should look something like:

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda3           29000       30401    11253532   83  Linux LVM

I just tried a few different starting values for sda3, to get around 11GB. Though sda3 doesn't have to be at the absolute end of the disc, it hast to have an unallocated space slightly larger than it right before it. So if you wanted to make it 5GB you could create a sda2 right after sda1, and use "+6G" for the size of sda2, then do the "+5GB" for sda3, then delete sda2.

We will be later creating sda2 and resizing it to use all additional space on the disc, that's why sda3 needs to be created after sda2 and sda2 needs to have slightly more space than sda3 (to hold the contents of sda3 as well as the LUKS information).

Once done, write the partition table and reboot the system.

Step Two: Installing the OS

The installation must be done using the graphical installer, because the text installer doesn't allow a custom installation to use LVM.

For the partitioning, select "Custom", and tell it to format sda1 as /boot, and sda3 as an LVM physical partition.

Then use the "LVM" button to create a volume group, and a logical volume within it for the "/" file-system. You can also create swap or other LVM partitions if you like. Note that you'll be able to resize the partitions later, so they don't need to be the desired target space or proportion right now.

The default volume group name should be used, or you will need to substitute "VolGroup00" for your name in the rest of this recipe.

After the partitioning, the rest of the installation can be done as normal.

Step Three: Create sda2

Boot into the installed system and create sda2 using fdisk. It needs to be the space between sda1 and sda3, and it should have a partition type of 83 (Linux) (it does not need to be type 8e, Linux LVM).

Reboot the system to get it to recognize the new partition.

Step Four: Set up encrypted partition

You now need to set up the encrypted partition, using the command:

cryptsetup --key-size 128 --verbose --verify-passphrase --cipher \
      aes-cbc-essiv:sha256 luksFormat /dev/sda2

It will ask you to confirm you want to destroy all data on the partition, and then will ask for a pass-phrase. You will need to remember this pass-phrase for future use of your system.

Step Five: Fix system to properly build initrd

Add the following line to "/etc/sysconfig/mkinitrd" (which may not already exist:

MODULES="aes sha256 dm_crypt cbc"

This tells mkinitrd that you will need these modules. If there is already a "MODULES=" line, you will need to add the above modules to that line.

The "/sbin/mkinitrd" file needs to be updated as well. I hate to do it, but I just end up modifying the file in-place. Future updates of this package will overwrite it, but at least these changes will cause future kernel updates to properly build an initrd. So, apply this patch (available via FTP) to "/sbin/mkinitrd":

*** mkinitrd.orig	Mon Nov 19 06:19:24 2007
--- mkinitrd	Mon Nov 19 06:20:06 2007
***************
*** 1317,1322 ****
--- 1317,1323 ----
  
  inst /sbin/insmod "$MNTIMAGE" /bin/insmod
  inst /sbin/rmmod "$MNTIMAGE" /bin/rmmod
+ inst /sbin/cryptsetup "$MNTIMAGE" /bin/cryptsetup
  
  if [ -e /etc/fstab.sys ]; then
      inst /etc/fstab.sys "$MNTIMAGE"
***************
*** 1540,1545 ****
--- 1541,1549 ----
      done
  fi
  
+ emit "echo Decrypting root device"
+ emit "cryptsetup luksOpen /dev/sda2 lvm"
+ 
  if [ -z "$nolvm" -a -n "$vg_list" ]; then
      emit "echo Scanning logical volumes"
      emit "lvm vgscan --ignorelockingfailure"

Step Six: Build new initrd

Move the existing initrd to the same name, but ending in ".old". We will be booting using the old initrd in a bit, so don't get clever and delete it instead of making a new one... For example:

cd /boot
mv initrd-2.6.23.1-42.fc8.img initrd-2.6.23.1-42.fc8.img.old

Now, run mkinitrd with the path to the initrd and kernel version, for example:

cd /boot
mkinitrd initrd-2.6.23.1-42.fc8.img 2.6.23.1-42.fc8

Step Seven: Reboot into init=/bin/sh and copy data

Boot the system using the old initrd, and adding "init=/bin/sh" to boot the system into a minimal environment (the root file-system isn't even mounted read/write).

In GRUB, use "e" to edit the boot options.

Use the down arrow to move to the initrd line and type "e" to edit the initrd to append ".old" to the name.

Use the arrow keys to select the kernel line (probably the line above the initrd line) and use "e" to append a <space> and "init=/bin/sh".

Press "b" to boot into this mode. You should get to a root prompt fairly quickly, with no errors.

Step Eight: Copy the LVM to the encrypted partition

Open the encrypted file-system with:

/sbin/cryptsetup luksOpen /dev/sda2 lvm

Enter your pass-phrase. Now you can copy the sda3 to the encrypted sda2:

dd if=/dev/sda3 of=/dev/mapper/lvm

This may take a while, especially on a slow laptop. I recently did a 5GB partition on an slower laptop and it took a good half hour to copy.

When it's done, close the encrypted partition with:

/sbin/cryptsetup luksClose lvm

Step Nine: Remove the old LVM partition

We must remove sda3 before rebooting, so that it isn't used during the reboot. We might as well re-partition it so that sda2 is the full size of the disc as well.

Run:

fdisk /dev/sda

Use the "p" command to print the current partition table and make note of the existing sda2 and sda3 start and end. This will be useful if you have made any mistakes, you can restore the partition table if it doesn't reboot properly, and use the ".old" initrd to boot into the non-encrypted LVM to try to fix things.

Now delete sda3 and sda2, and re-create sda2 with the same starting block, and a larger size. I just use the defaults, so it creates sda2 as the full remaining size of the disc except for sda1.

Write the changes to the partition table.

Step Ten: Reboot

At this point you should be able to do Ctl-Alt-Del and reboot the system. It should ask you for your pass-phrase, then the system should boot as normal.

Step Eleven: Resize the root file-system

I'm just running with a single large root partition. So, when I'm done with the above I want to extend the size of the root partition. Though you can create new logical volumes (for swap or other partitions) or extend other existing partitions similarly.

We need to resize the crypto device first with:

cryptsetup resize lvm

This will detect the new partition size (resized before the reboot) and resize the crypto device.

Now we need to resize the physical volume in the volume group:

pvresize /dev/mapper/lvm

You can find the existing size of your logical volume by looking at the output of "lvdisplay" under the "Current LE" line for the partition you want to increase the size of. That's the logical extents. Each logical extent is 32MB, probably, so a 5GB partition would have around 150 LE.

Next, you can find out how many physical extents are available by running "vgdisplay" and seeing the "Free PE" line. You can add up to this many physical extents to your logical volume. So, take the current number of logical extents, add to it the number of physical extents you want to add, and use it in the "-l" option in:

lvextend -l 900 /dev/VolGroup00/LogVol00

Again, this assumes that your volume group is named VolGroup00, and that the partition you want to extend is named "LogVol00". See the "df" output for information on what this may actually be named. Note that you can also use a more symbolic size with "-L", for example "-L 30G" instead of the "-l 900" above

I usually want to make my root partition the full size of the device, which is hard to do with the symbolic name. So, I just get the current Logical Extent number, add to it the free Physical Extents, and resize it to use all of them.

Now, resize the file-system with:

resize2fs /dev/VolGroup00/LogVol00

This will take several minutes, and while running if you do "df" in another window you will see the file-system growing in size.

Wrapping Up

So you now should have a full-disc, with the exception of /boot, encrypted logical volume. Future kernels should build an initrd that automatically includes the encryption code, so updates shouldn't break anything.

Enjoy.

comments powered by Disqus