Encrypted ZFS with Ubuntu

Slashdot it! Delicious Share on Facebook Tweet! Digg!

Making It Boot

The steps described so far are reasonably straightforward and do not deviate significantly from a more or less standard installation. To make the new system boot, however, some more elaborate steps are required.

Booting a ZFS system requires a special initial RAM disk. Although there's a PPA and package for this, the version for 12.10 (Quantal) has broken dependencies and cannot be installed. The reason is that booting used to require a specially patched GRUB. With the inclusion of GRUB 2 in Ubuntu 12.10, this is no longer necessary, but the dependencies have not been updated to reflect that yet. Although it's not the prettiest solution, a feasible workaround is to install the files that this special initramfs package provides manually:

## apt-get install wget
## wget http://ppa.launchpad.net/zfs-native/stable/ubuntu/pool/main/z/zfs-linux/zfs-initramfs_0.6.0.91-0ubuntu1~quantal1_amd64.deb
## dpkg -x zfs-initramfs_0.6.0.91-0ubuntu1~quantal1_amd64.deb zfs-initramfs
## cp -r zfs-initramfs/* /

The only files the zfs-initramfs package contains are hooks for the tool that creates the initial RAM disk. These hooks copy the required binaries and configuration into the initramfs . Next, you can set up the configuration files to tell the system about the encrypted partition on which the system is installed:

## echo 'cryptroot UUID=<UUID> none luks' >> /etc/crypttab

The first component in the configuration file designates the name of the device that provides access to the encrypted container. Choosing the same name you used to set up the ZFS pool and the rest of the system is important.

The UUID of the encrypted partition can be obtained using the blkid command. You could use a filesystem path here instead of the UUID, but because the paths are assigned dynamically by udev and it is possible for them to change, using the UUID is recommended. Similar configuration must be provided for the tool that creates the initial RAM disk:

## echo 'target=cryptroot,source=UUID=<UUID>,key=none,rootdev' >>/etc/initramfs/conf.d/cryptroot

The name of this file is arbitrary; cryptroot was chosen here to be consistent with the rest of the setup. Again, the name given as target must be the same as for the rest of the setup. The UUID is the same as before. This concludes the configuration required to create the initial RAM disk. You can run the following command to create it:

## update-initramfs -c -k all

The other element required to make the system bootable is the bootloader. The GRUB configuration needs to be changed to boot the ZFS system. In /etc/default/grub , find the command line passed to the kernel (GRUB_CMDLINE_LINUX_DEFAULT ), and add the following options to it:

root=ZFS=rpool/root boot=zfs

This step will tell GRUB to boot a ZFS system and where to find the root filesystem. Also at this point, remove the splash option from the command line – the splash screens are not installed in this basic installation and enabling this option will prevent you from seeing the prompt for the passphrase of the encrypted partition. Next, let GRUB generate a new configuration file:

## update-grub

The main configuration is now done. Before you can boot into the new system, just a few loose ends need to be tied up. The symlink to the encrypted device you created earlier in /dev needs to be persistent for future updates of the GRUB configuration to succeed. Tell udev to create it as follows:

## echo 'ENV{DM_NAME}=="cryptroot",SYMLINK+="cryptroot"' >/etc/udev/rules.d/99-local.rules

The particular number at the beginning of the file name does not matter as long as it ensures that this rule file is run after the mappings for the encrypted containers have been set up. The file that does this has number 55 on the image I used. Again, the name given in the file needs to match the name for the encrypted mapping specified earlier.

All that remains to make the new system usable is to set the root password:

## passwd root

Do not forget this step. You will not be able to use the new system unless you do this. Optionally, you can set up network interfaces and other basic system configuration. Finally, unmount the filesystems and exit the chroot :

## umount /boot
## umount /sys
## umount /proc
## exit

In the live system, unmount the chroot 's /dev directory, export the pool and reboot:

# umount /mnt/dev
# zpool export rpool
# reboot

Congratulations! You should now have a pure encrypted ZFS system. You can now set up the rest of the system, add users, and install a desktop environment.

Note that support for this kind of setup by Ubuntu is still somewhat lacking. In particular, after kernel upgrades, you should take care that the ZFS modules and the initial RAM disk are recreated correctly. You will not be able to boot if they are not.

Adding a Cache Device

ZFS pools can have cache devices – usually solid-state disk (SSD) – that are used to speed up the filesystem operations. Many modern systems, and even some laptops, have SSDs in addition to normal hard disks now. Adding a cache device can be done by executing a simple command, but you should, of course, encrypt the cache device.

Having another encrypted device would require you to enter a second passphrase when booting. This would be annoying and is actually unnecessary, because the Ubuntu cryptsetup package ships with a script that allows you to derive a passphrase from data on a disk.

Here, I will use the decrypted main disk as source for the derived passphrase. Although this approach is not as secure as an independent passphrase, it does not constitute a security risk here because the main disk still needs to be decrypted before the passphrase can be derived, and because the second disk is only a cache device.

Assuming that the cache device is /dev/sdb , you can set up the encrypted partition as follows:

# /lib/cryptsetup/scripts/decrypt_derived cryptroot > /tmp/key
# cryptsetup luksFormat -l 512 -c aes-xts-plain64 -h sha512/dev/sdb --key-file /tmp/key
# rm /tmp/key
# /lib/cryptsetup/scripts/decrypt_derived cryptroot | cryptsetupluksOpen /dev/sdb cryptcache

This will set up the new encrypted container as cryptcache with the same parameters as the other one. Adding the encrypted device as cache to the pool is straightforward:

# zpool add rpool cache /dev/mapper/cryptcache

Now, you just need to add the information about the encrypted device to the system.

No additional steps are required to make the ZFS configuration persistent:

# echo 'cryptcache UUID=<UUID> cryptroot luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived' >> /etc/crypttab

You can verify that the cache device is present and obtain usage statistics by typing zpool iostat -V .

Buy this article as PDF

Express-Checkout as PDF

Pages: 4

Price $0.99
(incl. VAT)

Buy Ubuntu User

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content