Freebsd loader.conf/rc.conf configuration - unlock data geli providers/mount zfs pool after / mounts

Hello FreeBSD community,

I’m seeking validation for my current configuration using Geli encryption with ZFS. While everything appears to be working correctly, I’d like to confirm whether this setup aligns with best practices or if there are recommended improvements.

Context
I’m a new user of Geli encryption, and I’ve configured it to secure ZFS vdevs. Through a combination of the FreeBSD handbook, geli man pages, and various forum posts, I was able to assemble a working setup. However, I couldn’t find a single, definitive "preferred" approach for this use case. Before moving critical data to my ZFS pool, I’d like to ensure this configuration is robust and adheres to common practices. I added passphrase as well as key file to allow for recovery in case key file becomes inaccessible as well as used geli backup to backup the metadata and master keys.

Current Setup

Root Pool:

Root on a ZFS pool (zroot) residing on a Geli-encrypted vdev.
This vdev requires a user password to unlock Geli during boot.
(I read that it was recommended a separate pool for file server rather than dataset on zroot)

File Server Pool:

Separate ZFS pool added for file server data.
Geli-encrypted vdevs in this pool are configured with two user keys:
Keyslot 0: Passphrase-based key.
Keyslot 1: Keyfile-based key (no passphrase).
The keyfile is stored at /geli.key.

Behavior:

The system boots without errors.
The data ZFS pool and its datasets mount successfully after boot.
Geli devices are present and active.
Here are the relevant sections from /boot/loader.conf and /etc/rc.conf for your reference:

cat /boot/loader.conf
aesni_load="YES"
geom_eli_load="YES"
cryptodev_load="YES"
zfs_load="YES"


cat /etc/rc.conf
zfs_enable="YES"
geli_groups="data"
#keyfile stored on encrypted root zfs dataset
geli_z1_flags="-n 1 -p -k /geli.key"
geli_z1_devices="da1 da2 da3"

Questions
Does this setup follow standard practices for using Geli with ZFS?
Are there any potential pitfalls, security concerns, or recommended changes to improve the configuration?
Is storing the keyfile at /geli.key acceptable, or is there a more secure alternative?
I’ve rebooted the system several times and reviewed logs, but I’d greatly appreciate input from experienced users to ensure this setup is both efficient and secure.

Thank you in advance for your time and guidance!
 
Behavior:

The system boots without errors.
Are the following variable values errors in the transcript? As the file server pool providers cannot be decrypted, the pool cannot be imported with this configuration.
geli_groups="data"
...
geli_z1_flags="-n 1 -p -k /geli.key"
geli_z1_devices="da1 da2 da3"
The geli_groups "data" value does not match with the following "_flags" and "_devices" group names.

"-p" option: are the server pools geli(8) provider not configured with two user keys?
Geli-encrypted vdevs in this pool are configured with two user keys:
Keyslot 0: Passphrase-based key.
Keyslot 1: Keyfile-based key (no passphrase).
geli(8) attach -p Do not use a passphrase as a component of the User Keys.

[EDIT]
One more issue

The geli(8) (attach) "-n 1" option is not strictly necessary.

Summarized how it should be configured based on comments in the opening post:
Code:
geli_groups="z1"
geli_z1_devices="da1 da2 da3"
geli_z1_flags="-k /geli.key"


Does this setup follow standard practices for using Geli with ZFS?
It cannot be said that there are standard procedures for the use of geli(8). It always depends on the use case, see EXAMPLES in the manual.

Is storing the keyfile at /geli.key acceptable, or is there a more secure alternative?
Since the server pool uses two user keys (passphrase and key file), and the key is stored on encrypted root-on-ZFS, the risk for compromising the encrypted pool is not high. (obligatory xkcd security)

An alternative would be to store the key file(s) on a USB stick. EXAMPLES in the manual should give an idea.

EDIT:
One more issue,
geli_z1_devices="da1 da2 da3"
It's not a good idea to use whole disks without a partition table. In case disks need to be replaced, there might be differences in size, even when the disks are the same brand and model.

The disk controller can have an impact as well: Thread unable-to-run-geli-attach-with-disk-internally.93003
/EDIT
 
I maybe misunderstanding but to unlock the file server pool automatically I initialized each provider disk with a passphrase (this was done so I wouldn't have to back up the key file). I then set a key file as another option to unlock the drives. I used the same key file for each drives.

#initialize a provider with passphrase as backup
geli init -s 4096 -l 256 /dev/da1
geli init -s 4096 -l 256 /dev/da2
geli init -s 4096 -l 256 /dev/da3

#create geli user key
dd if=/dev/urandom of=/root/geli.key bs=64K count=1

#add key without password to keyslot 1
geli setkey -n 1 -K geli.key -P /dev/da1
geli setkey -n 1 -K geli.key -P /dev/da2
geli setkey -n 1 -K geli.key -P /dev/da3

Edit: I think I may understand. I will test in my lab. I don't need -p because it's a key file without a password. I would still need -n 1 correct since I chose that slot for the key file during set key?
 
Back
Top