Code Aesthetics

Programming, agility, technical stuff ...

How to use ZFS and Encryption on a ubuntu home server

Recently I set up a home file server out of old hardware and installed ubuntu server edition. The idea was to make use of my old hard disks (which range from 80 GB to 500 GB capacity) and the next time I replace a hard disk it should be easy to integrate the old disk into my home file server. ZFS is perfect for this purpose because it allows to add disks later on to a pool and we do not need to use LVM and extend file systems and so on. Unfortunately the linux port of  ZFS can only be run in user space currently (ZFS FUSE). Anyhow this is good enough for my home server!

Installing ZFS is straight forward:

sudo apt-get install zfs-fuse

In order to setup your ZPool you can check out this article. For my special purpose - I simply wanted to stripe the data across all my hard disks - I used this command:

sudo zpool create storage /dev/sdb /dev/sdc

Remember to replace sdb and sdc with your hard disks you want to use.  To destroy the zpool again you can use:

sudo zpool destroy storage

But what about encryption?

There is a  project to build in encryption for ZFS on OpenSolaris (I think they have integrated that already). I am not sure that the ZFS fuse port is supporting that, so I went for another solution (make sure that you destroy again the zpool before continuing):

First create a partition on each hard disk drive you want to use.

sudo fdisk /dev/sdb
...
sudo fdisk /dev/sdc
...

Next install LUKS:

sudo apt-get install cryptsetup

Now it is possible to encrypt the partitions. I am assuming that the disks are new (and therefore empty), otherwise you want to wipe out the content first. This can be done for example with this command:

sudo dd if=/dev/zero of=/dev/sdb1 bs=512

To encrypt the partitions, you can use for example this:

sudo cryptsetup --verify-passphrase luksFormat /dev/sdb1 -c aes -s 256 -h sha256
sudo cryptsetup --verify-passphrase luksFormat /dev/sdc1 -c aes -s 256 -h sha256

In order to unlock and map the partition use (/dev/mapper/encrypted1 and /dev/mapper/encrypted2):

sudo cryptsetup luksOpen /dev/sdb1 encrypted1
sudo cryptsetup luksOpen /dev/sdc1 encrypted2

Now it is possible to use the encrypted partitions as the base for our zpool:

sudo zpool create storage /dev/mapper/encrypted1 /dev/mapper/encrypted2

The result is an encrypted ZPool. You simply need to repeat the process of creating an encrypted partition for each hard drive you want to add. If you do not enter the password and map the encrypted partitions ZFS will report "Faulted" as the state. After entering the password it will report "Healthy". Remember restarting zfs-fuse after unlocking the drives.

Improvements

Instead of using a password it makes sense to use a key file on a USB stick, so that you can put that in while booting your home server and everything is loaded automatically (like the keys for a car).

Johannes Täuber

I am a software architect and agility advocate. I am interested in all technologies out there and like to discuss options. My platform of choice is the .NET framework.