Resource icon

Reusing Encryption Keys & Passphrases

Let's get the messy bit out of the way. This resource makes no claim about whether you should or should not use encryption. Discussion on the merits or implementation strategy used in FreeNAS is not relevant to this resource. I'm not looking to advocate for or against encryption.

This resource is intended as an instructional guide for folks to follow as an educational tool to learn more about FreeNAS encryption in a specific use-case. Whether you are comfortable reusing the keys and passphrases is up to you; but if you're ever wondered how to do it, this guide should teach you.

This resource assumes you have downloaded your original primary and recovery keys, User Key 0 and User Key 1 respectively. The original primary key will be referred to as original.key and the original recovery key will be referred to as original_recovery.key.

Further, it assumes you have made them available on your system somehow. Keep in mind that you do not want errant copies of these keys lying around (save for your actual backups of these keys). One option is to use removable media such as a thumb drive which can easily be erased when the process is complete.

Finally, when referring to devices in the pool as /dev/gptid/{device} you can find the value of {device} by using zpool status {pool}. Omit the trailing .eli when setting keys on devices.


Required Pre-Reading
Check out this post giving a brief explanation of how encryption works in FreeNAS.

Also, take a look through the geli man pages.

Also, check the User Guide for advice about using encryption. Here is a subset of sections to read over.
Managing Encrypted Pools
Adding a Spare Device
Extending a Pool
Export/Disconnect a Pool
Importing a Pool
Replacing an Encrypted Disk
I will add that some of what is suggested below may seem to be in contradiction with the User Guide. It seems to me that the User Guide takes the most conservative approach in general which isn't always a bad thing.

Finally, you should perform these steps at your own risk. Don't just blindly copy these instructions without understanding them. I also highly recommend that you not perform these steps on any data without a valid backup. You may consider testing this on a dummy pool for learning purposes.

Replacing a Single Disk
In this scenario you've replaced a single disk in your pool and you'd like to make absolutely certain that the new drive uses the same primary key, recovery key, and passphrase as the rest of the pool. It assumes that the pool is unlocked while you are doing the steps unless otherwise noted.
  1. Perform the resilver/replacement as you normally would per the instructions in the User Guide.

  2. For each new device in your pool reset the recovery key (User Key 1) with geli setkey -n 1 -P -K /path/to/original_recovery.key /dev/gptid/{device}.
    Note: You don't need to reset the primary key (User Key 0). During disk replacement you are prompted for your passphrase; this sets the primary key as stored in /data/geli and the passphrase for User Key 0 on the new disk.

  3. Perform any verification you'd like. I recommend you lock/unlock your pool using both your passphrase and the recovery key as a start. You can also export/import your new pool using the original.key & passphrase to import. You may also choose to reboot the server.

  4. Now, clean up after yourself. Remove any extraneous copies of your recover key rm /path/to/original_recovery.key. Of course, don't delete your actual backups of your keys as they are now needed for your new pool!
Replacing an Entire Pool
In this scenario you are replacing an entire pool with a new pool composed of wholly new drives. It assumes that the pool is unlocked while you are doing the steps unless otherwise noted.
  1. Create the new pool; be sure to check the box to use encryption on the new pool.

  2. For pools with a passphrase navigate to the pool and add a passphrase, it can be whatever value you like just don't forget it.
    Note: For pools without a passphrase skip this step.

  3. Set the primary key (User Key 0) for every drive in your new pool by issuing the following command for each drive: geli setkey -n 0 -K /path/to/original.key /dev/gptid/{device}. You will be prompted for a passphrase; set it to the original passphrase.
    Note: For pools without a passphrase add the -P flag.

  4. Set the recovery key (User Key 1) for every drive in your new pool by issuing the following command for each drive: geli setkey -n 1 -P -K /path/to/original_recovery.key /dev/gptid/{device}.
    Note: Several of the flags use different values than the above; take care to get the flags correct.

  5. Check ls -l /data/geli, the newest key file is the key for your newly created pool. I will refer to this key as {pool}.key. You can double-check it by locking your pool, renaming this file, and then trying to unlock it. It will fail if you've found the correct key. Put the name back and it will unlock normally.

  6. Copy the old key to a temporary location mv /data/geli/{pool}.key /data/geli/{pool}.key.bak and then put the original in its place mv /path/to/original.key /data/geli/{pool}.key.

  7. Perform any verification you'd like. I recommend you lock/unlock your pool using both your passphrase and the recovery key as a start. You can also export/import your new pool using the original.key & passphrase to import. You may also choose to reboot the server and then unlock it using both the passphrase and recovery key or even try exporting the pool and importing it into a new system entirely.

  8. Now, clean up after yourself. Remove the backup temporary key rm /data/geli/{pool}.key.bak and the copies of your original key and recovery key rm /path/to/original.key; rm /path/to/original_recovery.key. Of course, don't delete your actual backups of these keys as they are now needed for your new pool!
Adding a Spare
As I explain in this post, when you add a spare to a pool you have to reset the passphrase and recovery key. The process preserves your primary key (User Key 0) but invalidates the recovery key (User Key 1). What if you wanted to keep everything the same?

  1. Add a spare to your pool and upon completion navigate to your pool and add a passphrase; use your original passphrase.

  2. Set the recovery key (User Key 1) for every drive in your new pool including the spare by issuing the following command for each drive: geli setkey -n 1 -P -K /path/to/original_recovery.key /dev/gptid/{device}.

  3. Perform any verification you'd like. I recommend you lock/unlock your pool using both your passphrase and the recovery key as a start. You can also export/import your new pool using the original.key & passphrase to import. You may also choose to reboot the server and then unlock it using both the passphrase and recovery key or even try exporting the pool and importing it into a new system entirely.

  4. Now, clean up after yourself. Remove the recovery key rm /path/to/original_recovery.key. Of course, don't delete your actual backups of the keys as they are still needed for your pool!
Extending a Pool by Adding a Vdev

Extending a pool by adding a vdev is has similar behavior as adding a spare drive to a pool; the act of adding a new vdev invalidates your passphrase and recovery keys. You preserve them in the same was you would with adding a spare.
  1. Extend your pool by adding a vdev and add a passphrase; use your original passphrase.

  2. Set the recovery key (User Key 1) for every drive in your new pool by issuing the following command for each drive: geli setkey -n 1 -P -K original_recovery.key /dev/gptid/{device}

  3. Perform any verification you'd like. I recommend you lock/unlock your pool using both your passphrase and the recovery key as a start. You can also export/import your new pool using the original.key & passphrase to import. You may also choose to reboot the server and then unlock it using both the passphrase and recovery key or even try exporting the pool and importing it into a new system entirely.

  4. Now, clean up after yourself. Remove any extraneous copies of original.key and recovery.key. Of course, don't delete your actual backups of these keys as they are now needed for your new pool!
Importing a Pool

When you import a pool you must provide either either original.key and the passphrase (if set) or recovery.key. If you provide original.key and the passphrase this section can be skipped as doing so leaves your pool configured such that all keys and passphrases still work. However, if you provide the recovery key something interesting happens; it breaks your passphrase and primary key. The reason is explained in more detail in this post.

Assuming you imported your pool using the recovery key and you still have all keys still available you can take the following steps to reset your pool such that both keys and the passphrase work.
  1. Set the recovery key to User Key 1 for every drive in the pool. geli setkey -n 1 -P -K original_recovery.key/dev/gptid/{device}

  2. Set the primary key to User Key 0 for every drive in the pool. geli setkey -n 0 -K original.key/dev/gptid/{device}
    Note: If this pool has no passphrase add the -P flag.

  3. Tell the database that this pool should require a passphrase. sqlite3 /data/freenas-v1.db 'UPDATE storage_volume SET vol_encrypt = 2 WHERE vol_name = "{pool}";'
    Note: If this pool has no passphrase skip this step.

  4. Make the primary key available in /data/geli with mv original.key /data/geli/tmp.key where /data/geli/tmp.key can be identified by sqlite3 /data/freenas-v1.db 'SELECT vol encryptkey FROM storage volume WHERE vol name = "pool";'

Note: I've only tested this on 11.2-U6. Though, I imagine it will work on a wide range of versions.

EDIT: I've tested the sqlite commands and geli setkey commands in 11.3-U2.1 as well.

Let me know if you think I've missed something here or made a mistake. I'll update this with any corrections as they come up.
  • Like
Reactions: Ericloewe
Author
PhiloEpisteme
Views
2,804
First release
Last update
Rating
0.00 star(s) 0 ratings

More resources from PhiloEpisteme

Top