zauthrs is a simple program to decrypt and mount encrypted ZFS user home directories at login using Yubikey HMAC or a Simple USB drive as 2FA written in rust.
This program currently supports two methods for 2FA:
In this mode the program looks for a Yubikey on login and uses it's HMAC mode on SLOT 2 along with your password to derive the final encryption key.
Yubikey mode is set with the -f
flag.
NOTE It currently only reads the SLOT 2 of the Yubikey for HMAC.
In this mode the program looks for a file (can be any file) and use that along with your password to derive the final encryption.
File mode is set using the -f <path to file>
option.
The idea with this method is to keep the file on a USB storage device and present it during the login to derive the encryption key.
You can use any preexisting file.
Note: Since the file becomes part of your encryption key and its Security cannot be guaranteed as with Yubikey you are responsible for keeping it secure.
Clone repo using
bash
git clone https://github.com/ashuio/zauthrs.git
Build using
bash
cargo build --release
bash
sudo cp target/release/zauthrs /usr/bin
This command takes paramenters in the following form
zauthrs \
Modes
Flags/Options
NOTE: The -y
(Yubikey mode) flag and the -f <path to file>
(File mode) option are interchangeable in all our examples.
Test this program once with the zauthrs config -y -p <test_string>
before attempting to use it.
NOTE: Remember to update your encryption key as well if you update your password.
You can create user home datasets using the config mode
bash
zauthrs config -y -p <PASSWORD> | zfs create -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=prompt <zfs path>
Example
bash
zauthrs config -y -p "hunter2" | zfs create -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=prompt zroot/data/home/hunter
You can also change/update the key for existing ZFS datasets by running
bash
zauthrs config -y -p <PASSWORD> | zfs change-key <zfs dataset path>
Example
bash
zauthrs config -y -p "hunter2" | zfs change-key zroot/data/home/hunter
Simply add the option -z
to unlock any zfs dataset
Example
bash
zauthrs -y -p "hunter2" -z zroot/data/home/hunter/secrets
You can use the -f
option instead of the -y
flag to substitute a Yubikey with any USB Drive.
Auto mount the USB so zauthrs can find the required keyfile on login
We can use udev
for this, simply create and add the following to /etc/udev/rules.d/99-usb-automount.rules
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_SERIAL_SHORT}=="<Serial Number of device>", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode <Desired Mount point>"
Example
ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_SERIAL_SHORT}=="4C530001241012111173", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/usb"
You can get the serial number by running
bash
udevadm info --query=all --name=<Target disk> | grep ID_SERIAL_SHORT
Example
bash
udevadm info --query=all --name=/dev/sdb | grep ID_SERIAL_SHORT
Run udevadm control --reload-rules
after to make sure new rules are loaded.
This program uses the pam_exec.so module to execute during the login process.
simply add the following line to your desired pam login method file.
In our example we will be adding it to /etc/pam.d/sddm to handle graphical logins and /etc/pam.d/login to handle CLI logins.
Add the following line to you pam config file
auth optional pam_exec.so expose_authtok <full path to program> pam -y -b <base home dir>
Example
auth optional pam_exec.so expose_authtok /etc/pf/zauthrs pam -y -b zroot/data/home
Where zroot/data/home
mounts to /home
Since ZFS mounts datasets OVER preexisting directories and we defined our module in PAM as optional we still get authenticated with JUST the pass even though our dataset is NOT decrypted (eg. Because Yubikey was not inserted).
We can use this to our advantage and essentially have TWO home directories.
First which would be your normal encrypted home directory which would be unlocked and mounted when your Yubikey is present at login.
Second would be the directory which would already be present and would be loaded on decryption failure i.e when no Yubikey is inserted during login.
Let me know if interested and maybe i can write up a more detailed guide.