Encrypted ZFS In FreeBSD
ZFS introduced encrypted datasets in zpool verison 30, which is only available in Solaris. FreeBSD and IllumOS use zpool version 28. For FreeBSD users, encrypted ZFS is still a possibility and is rather easy to do (I’m sure it is on IllumOS as well, I just haven’t learned how to do it). In this article, we’ll step through how to create an encrypted ZFS pool in FreeBSD. Our setup is pretty simple. We have a single pool named rpool. We’ll create a number of datasets under rpool/encrypted:
[root@fbsd-sec ~]# zfs create -omountpoint=/encrypted rpool/encrypted [root@fbsd-sec ~]# zfs create rpool/encrypted/keys [root@fbsd-sec ~]# zfs create -omountpoint=none rpool/encrypted/zvols [root@fbsd-sec ~]# zfs create -ocompression=on rpool/encrypted/zvols/testvol [root@fbsd-sec ~]# zfs create -V 1G rpool/encrypted/zvols/testvol/disk0 [root@fbsd-sec ~]# zfs create -V 1G rpool/encrypted/zvols/testvol/disk1 [root@fbsd-sec ~]# zfs create -V 1G rpool/encrypted/zvols/testvol/disk2 [root@fbsd-sec ~]# zfs create -V 1G rpool/encrypted/zvols/testvol/disk3 [root@fbsd-sec ~]# zfs create rpool/encrypted/keys/testvol
Next, we’ll create our encryption keys:
[root@fbsd-sec ~]# dd if=/dev/random of=/encrypted/keys/testvol/disk0 bs=64 count=1 1+0 records in 1+0 records out 64 bytes transferred in 0.000094 secs (679583 bytes/sec) [root@fbsd-sec ~]# dd if=/dev/random of=/encrypted/keys/testvol/disk1 bs=64 count=1 1+0 records in 1+0 records out 64 bytes transferred in 0.000161 secs (397682 bytes/sec) [root@fbsd-sec ~]# dd if=/dev/random of=/encrypted/keys/testvol/disk2 bs=64 count=1 1+0 records in 1+0 records out 64 bytes transferred in 0.000094 secs (679583 bytes/sec) [root@fbsd-sec ~]# dd if=/dev/random of=/encrypted/keys/testvol/disk3 bs=64 count=1 1+0 records in 1+0 records out 64 bytes transferred in 0.000095 secs (672771 bytes/sec)
Now, we’ll initialize geli for each of the zvols:
[root@fbsd-sec ~]# geli init -s 4096 -K /encrypted/keys/testvol/disk0 /dev/zvol/rpool/encrypted/zvols/testvol/disk0 [...snip...] [root@fbsd-sec ~]# geli init -s 4096 -K /encrypted/keys/testvol/disk1 /dev/zvol/rpool/encrypted/zvols/testvol/disk1 [...snip...] [root@fbsd-sec ~]# geli init -s 4096 -K /encrypted/keys/testvol/disk2 /dev/zvol/rpool/encrypted/zvols/testvol/disk2 [...snip...] [root@fbsd-sec ~]# geli init -s 4096 -K /encrypted/keys/testvol/disk3 /dev/zvol/rpool/encrypted/zvols/testvol/disk3 [...snip...]
Finally, we’ll attach the keys to the disks and create our encrypted ZFS pool:
[root@fbsd-sec ~]# geli attach -k /encrypted/keys/testvol/disk0 /dev/zvol/rpool/encrypted/zvols/testvol/disk0 Enter passphrase: [root@fbsd-sec ~]# geli attach -k /encrypted/keys/testvol/disk1 /dev/zvol/rpool/encrypted/zvols/testvol/disk1 Enter passphrase: [root@fbsd-sec ~]# geli attach -k /encrypted/keys/testvol/disk2 /dev/zvol/rpool/encrypted/zvols/testvol/disk2 Enter passphrase: [root@fbsd-sec ~]# geli attach -k /encrypted/keys/testvol/disk3 /dev/zvol/rpool/encrypted/zvols/testvol/disk3 Enter passphrase: [root@fbsd-sec ~]# zpool create testvol raidz /dev/zvol/rpool/encrypted/zvols/testvol/disk0.eli /dev/zvol/rpool/encrypted/zvols/testvol/disk1.eli /dev/zvol/rpool/encrypted/zvols/testvol/disk2.eli /dev/zvol/rpool/encrypted/zvols/testvol/disk3.eli [root@fbsd-sec ~]# zpool status testvol pool: testvol state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM testvol ONLINE 0 0 0 raidz1-0 ONLINE 0 0 0 zvol/rpool/encrypted/zvols/testvol/disk0.eli ONLINE 0 0 0 zvol/rpool/encrypted/zvols/testvol/disk1.eli ONLINE 0 0 0 zvol/rpool/encrypted/zvols/testvol/disk2.eli ONLINE 0 0 0 zvol/rpool/encrypted/zvols/testvol/disk3.eli ONLINE 0 0 0 errors: No known data errors
As you can see, creating an encrypted ZFS volume is easy on FreeBSD. Ideally, you might not want to store encryption keys in rpool, but rather a removable medium. I would likely create a zpool using a USB thumb drive and place the keys on there. I would then set the readonly ZFS property on the thumb drive zpool (zpool create enckeys /dev/device && [generate encryption keys] && zfs set readonly=on enckeys). You can always set readonly=off when you need to create, destroy, or modify stored encryption keys.