ZFS on laptop with encrypted /home
With Ubuntu 19.10 it’s simple to get a workstation with boot and root on ZFS. But what’s missing from the install is encryption. This is how I did it.
I suggest you first have:
- basic zfs knowledge
- good linux knowledge
- no important data on the target system
- more than 4 GB RAM
- SSD or better
How-to
- Install Ubuntu as normal, but choose “use ZFS”. It’s marked as experimental, but that’s because how Ubuntu uses it may change in later releases. The code it self is solid.
- After install is done, you’re left with a bpool and an rpool. I will only focus on encrypting /home/<user>. I’ll use username john in this example.
- Your layout will look something like this:
$ zfs list -r rpool
NAME USED AVAIL REFER MOUNTPOINT
rpool 165G 293G 96K /
rpool/ROOT 18,8G 293G 96K none
rpool/ROOT/ubuntu_oyzpo3 18,8G 293G 3,92G /
rpool/ROOT/ubuntu_oyzpo3/usr 1,06M 293G 96K /usr
rpool/ROOT/ubuntu_oyzpo3/usr/local 992K 293G 144K /usr/local
rpool/ROOT/ubuntu_oyzpo3/var 13,4G 293G 96K /var
rpool/ROOT/ubuntu_oyzpo3/var/games 320K 293G 96K /var/games
rpool/ROOT/ubuntu_oyzpo3/var/lib 4,36G 293G 3,72G /var/lib
rpool/ROOT/ubuntu_oyzpo3/var/lib/AccountServices 320K 293G 96K /var/lib/AccountServices
rpool/ROOT/ubuntu_oyzpo3/var/lib/NetworkManager 3,67M 293G 208K /var/lib/NetworkManager
rpool/ROOT/ubuntu_oyzpo3/var/lib/apt 87,0M 293G 74,9M /var/lib/apt
rpool/ROOT/ubuntu_oyzpo3/var/lib/dpkg 87,4M 293G 41,2M /var/lib/dpkg
rpool/ROOT/ubuntu_oyzpo3/var/log 574M 293G 170M /var/log
rpool/ROOT/ubuntu_oyzpo3/var/mail 2,25M 293G 104K /var/mail
rpool/ROOT/ubuntu_oyzpo3/var/snap 8,46G 293G 8,46G /var/snap
rpool/ROOT/ubuntu_oyzpo3/var/spool 10,4M 293G 3,51M /var/spool
rpool/ROOT/ubuntu_oyzpo3/var/www 320K 293G 96K /var/www
rpool/USERDATA 141G 293G 96K /
rpool/USERDATA/john_75qybu 140G 293G 126G /home/john
rpool/USERDATA/root_75qybu 1,07G 293G 1,07G /root
We want to replace rpool/USERDATA/john_75qybu with a new, encrypted file system.
- Create another temporary user, smith, and log out of john and in as smith.
- Set filesystem name in a variable, so you can copy/paste the rest: $oldfs=”rpool/USERDATA/john_75qybu”; $newfs=”rpool/USERDATA/john_crypt”
- Unmount: sudo zfs umount $oldfs
- Reset mountpoint: sudo zfs set mountpoint=none $oldfs
- Create a new, encrypted file system for your main user: sudo zfs create -o encryption=on -o keyformat=passphrase $newfs
- Set mountpoint: sudo zfs set mountpoint=/home/john $newfs
- Mount: sudo zfs mount -a
- If you get complaints on missing key, run: sudo zfs load-key -a and then mount again.
If you had any data on the unencrypted home dir, you can mount it anywhere else (zfs set mountpoint=/mnt ...), and copy data.
Last thing you need to do is enable key loading at boot.
- Create the file /etc/systemd/system/zfskey-tank@.service as:
[Unit]
Description=Load %I encryption keys
Before=systemd-user-sessions.service
Before=zfs-mount.service
After=zfs-import.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/bash -c 'systemd-ask-password "Encrypted ZFS password for %I" --no-tty | zfs load-key -a'
[Install]
WantedBy=zfs-mount.service
Note that I’ve changed the suggested example from Arch Wiki which ended in zfs load-key %I to zfs load-key -a. That way all encrypted filesystems will be mounted.
- And enable: $ sudo systemctl enable zfskey-tank@john_crypt
Reboot and check that everything works. If you have trouble logging in, you can log in as smith and check what fails. Unlocking, mounting or access rights. It will look the same in a zfs list, but you should see a difference if you run:
$ sudo zfs get encryption rpool/USERDATA/john_crypt
NAME PROPERTY VALUE SOURCE
rpool/USERDATA/john_crypt encryption aes-256-ccm -
If everything works, you can move along to setting up snapshots or other fancy zfs stuff. =)