Protecting your data with two factors and ZFS dataset encryption

It’s really easy to use ZFS dataset encryption to protect your data in a way so you have to know something and to own something to get access to encrypted data.

Basic idea

The idea is pretty simple and obvious. One USB drive is your datastore, the other one is your keystore. An dataset on this datastore is encrypted with a file as the source of the encryption key. This keysource is on the keystore USB drive. However it’s not stored unencrytped there. This USB drive contains an encrypted dataset with your keyfile for the dataset on your data store usb stick. However this one is protected with a pass phrase.

Implementation

Let us “format” the USB sticks with ZFS at first. In this case, the rmformat command is quite handy to find out about the names of the USB drives in the device tree.

jmoekamp@solaris:~$ rmformat
Looking for devices...
     1. Logical Node: /dev/rdsk/c10t0d0p0
        Physical Node: /pci@0,0/pci8086,265c@b/storage@2/disk@0,0
        Connected Device: SanDisk  U3 Cruzer Micro  8.02
        Device Type: Removable
	Bus: USB
	Size: 3.8 GB
	Label: <None>
	Access permissions: Medium is not write protected.
(...)
     3. Logical Node: /dev/rdsk/c9t0d0p0
        Physical Node: /pci@0,0/pci8086,265c@b/storage@1/disk@0,0
        Connected Device: SanDisk  U3 Cruzer Micro  8.02
        Device Type: Removable
	Bus: USB
	Size: 3.8 GB
	Label: <None>
	Access permissions: Medium is not write protected.

Okay, let’s create the pools:

root@solaris:/# zpool create a_keystore_usbstick /dev/dsk/c10t0d0p0<br />
root@solaris:/# zpool create datastore /dev/dsk/c9t0d0p0

Afterwards we create an dataset with a passphrase:

root@solaris:/# zfs create -o encryption=on a_keystore_usbstick/keys<br />
Enter passphrase for 'a_keystore_usbstick/keys': <b>supersecret</b><br />
Enter again: <b>supersecret</b>

Everything we write into this dataset will be encrypted and will be just available to you, when you enter the passphrase. We will write a file with our key for the real data into this dataset. So the key is protected by the passphrase, because without passphrase you can’t encrypt the dataset with the key file (and without key file you can’t decrypt the dataset containing the data). Creating a keyfile is fairly easy with Solaris. We can use the pktool tool for it.

root@solaris:/# pktool genkey keystore=file keytype=aes keylen=128 outkey=/a_keystore_usbstick/keys/joergsdatastick.key

With this file as a keysource we create the dataset for our secret files on the second USB drive.

root@solaris:/# zfs create -o encryption=on -o keysource=raw,file:///a_keystore_usbstick/keys/joergsdatastick.key datastick/joergssecrets

Let’s move some data into this directory:

root@solaris:/datastick/joergssecrets# mv /home/jmoekamp/highlyconfidential_nda_presos.tgz .

Now we export the usb drives in order to remove them from the system.

root@solaris:/# zpool export a_keystore_usbstick
root@solaris:/# zpool export datastick

Okay, now you can unplug both USB-sticks and put one in your safe and one at your keyring or in a different safe. After a while you need to access your data. You need the key source, so you have to import the a_keystore_usbstick first:

root@solaris:/# zpool import a_keystore_usbstick<br />
Enter passphrase for 'a_keystore_usbstick/keys': <b>supersecret</b><br />
root@solaris:/#

Now you have to import your datastick pool:

root@solaris:/# zpool import datastick<br />
root@solaris:/# cd datastick/joergssecrets<br />
root@solaris:/datastick/joergssecrets# ls<br />
highconfidential_nda_presos.tgz

It doesn’t ask for the keyfile because the location is stored in the metadata of the dataset. And this location is one in the encrypted dataset on the keystore usb stick. As long as the file /a_keystore_usbstick/keys/joergsdatastick.key is available and it’s containing the correct key, it will automatically decrypt the data. However as mentioned before, it’s just available when you imported the pool a_keystore_usbstick with the correct passphrase.

Conclusion

This way you need to know the passphrase for the dataset storing the key and you need the USB stick containing the keysource. Without having both, you can’t decrypt the encrypted data on the USB stick.