Trouble unlocking an encrypted dataset from the CLI

I have a set of backup drives that I rotate out, keeping one offsite. The job that replicates to the backup drives sends the backups to an encrypted dataset under the pool root:

Pool: offsite-backup

Dataset: backup

I’m trying to set things up so that when the TrueNAS reboots, it unlocks the dataset automatically using a script at launch, so scheduled backups can run. However, when I try to run the command from the CLI, the dataset does not unlock. The command I am running is:

midclt call pool.dataset.unlock name:offsite-backup/backup passphrase:(Redacted)

I am not getting an error message when I run the command, just a set of numbers (21627 when I run it as me, 21630 when I run it using sudo -s and then running it as root).

How can I unlock the dataset from the CLI, using a script? The articles I have found online don’t seem to be working.

That’s because it’s a job: pool.dataset.unlock — TrueNAS API v25.10.1 documentation

This method is a job.

Which means that its return value without a -j specified is the job id.

WARNING: running a script like this with password provided in payload is insecure. It will leak your password into your shell history and potentially make it visible to other processes.

1 Like

OK, thank you. I just looked at the documentation, and it’s lacking any examples.

If I wanted to call a script at boot that unlocked a dataset using a passphrase, how would I set this up? I can see I would use a JSON file, but there’s no example file, and no example command to call that file.

I’m using a passphrase and not a key, because the keys would need to be stored somewhere that’s not on the encrypted drives (making them either insecure, or not backed up). If I know the passphrase, I can always manually unlock the drives if I need to recover them on another system.

I think I have this. The code I am using is:

midclt call pool.dataset.unlock “offsite-backup/backup” “{“datasets”: [{“name”: “offsite-backup/backup”,“passphrase”: “(REDACTED)”}]}”

I’ve set it up as a Command (not a Script - thank you for that) on boot in the Advanced Settings.

When my current backup is done later today, I’ll reboot and see if it unlocks the dataset.

Thank you for the guidance!

Out of interest why did you not use a key to encrypt instead of a passphrase as that auto unlocks at boot?

I do this. The datasets only unlock if:

  1. A specific USB (identified with UUID) is inserted into the system
  2. That USB contains the ‘encrypted.passphrase’ file containing the unlock passphrase.
  3. The decryption key file ‘my.key’ exists somewhere in the boot pool
  4. The decrypted passphrase matches the dataset password

If I need physical theft security, I pull the USB key. Done. When the system boots with the USB inserted, it will unlock any datasets configured in the script. It can also be run manually.

My script runs POSTINIT.
image

This thread should get you there. This approach can be used to unlock the parent first then any child datasets on boot.

1 Like

Frank, this is brilliant. It would work for me… except for the fact that I have cats. Specifically, I have one cat that LOVES pulling on dongles, cables, etc. If the key is in the device, he WILL pull it out.

For now, what I have works (I’m more worried about the drive that is offsite being compromised, than the one in my house). When I eventually get to an enclosed rack that is (hopefully) cat-proof, I will revisit this and try the physical key method.

@FrankWard - I just thought of something. The decryption key file is in the Boot pool - meaning it’s not on your main data set. How is that key backed up? My main worry would be backing up the key would put it in the pool that’s encrypted, which means if I lose the key, I can’t unencrypt to get the key back. (This also answers @Johnny_Fartpants question - see my comment above for more information.)

For clarity of future readers, these keys are created manually and not part of TrueNAS. Keeping it somewhere on the boot-pool ensures it can be accessed when needed, but it can be lost during events like upgrades depending on where you store it. Should your boot-pool meet an untimely demise, you just pull your copy of it out of encrypted local or cloud storage, replace it, and run the script.

I don’t suggest keeping keys on datasets. Store them safely somewhere you can get to easily that’s away from your server. KeepassXC, encrypted AWS, etc.

OK, this makes a lot more sense now, thank you. I think the documentation on encryption for TrueNAS assumes a lot of basic underlying knowledge - now that you’ve spelled this out, it makes sense to go with a key file.

I just generated one, so now I can look into how to back it up properly in BitWarden.

Part of my brain is still saying '“What if you lose the file?” and that a password is better. But the key seems to be more straightforward and technically easier. I’m going to back up my key, and once I can confirm it will work once backed up and restored, will set that up for my backup drives.

Hmm.. Let’s make sure you’re on the right track. The key file you use is created outside of TrueNAS. It’s not a key file created when turning on encryption for a dataset. In fact, once the encrypted dataset is created, you’ll change the encryption to ‘passphrase’ mode and choose a passphrase. You can then discard the key file that TrueNAS created.

Once the dataset is encrypted with your chosen passphrase, you’ll use OpenSSL to create a symmetric encryption key using the passphrase.

  1. Create a file named secret.key that contains a 44-character Base64 string, which serves as a symmetric encryption key.
# Create the symmetric encryption key
openssl rand -base64 32 > secret.key

# Secure the key
chmod 400 secret.key # Restrict file access read-only for the owner   
chown root:root secret.key # Ensure only root can access it
  1. This command takes a plaintext string (“your-dataset-passphrase”) and encrypts it to Ciphertext using the secret key generated in the first step.
# Create ciphertext of the passphrase
echo "your-dataset-passphrase" | openssl enc -aes-256-cbc -salt -pbkdf2 -out passphrase.enc -pass file:secret.key
  1. Test the decryption
# Decrypt the ciphertext using the secret.key
openssl enc -aes-256-cbc -d -salt -pbkdf2 -in passphrase.enc -pass file:secret.key
  1. You can safely store passphrase.enc on the USB, remote server, cloud storage, an insecure backup location, or Bitwarden while the secret.key can be stored on the boot-pool. This passphrase.enc file contains the scrambled, unreadable version of your passphrase. Since we used strong AES-256 encryption, an attacker without the corresponding secret.key would face a computationally impossible task to decrypt it through brute force.

  2. Create a post-init script that:

    • Checks for the USB key by UUID
    • Verifies the two files exist (passphrase.enc on the USB and secret.key on the boot-pool)
    • Decrypts the the passphrase.enc file using secret.key to obtain the passphrase
    • Issue the command (midclt call pool.dataset.unlock) unlock the datasets using the decrypted passphrase
1 Like

Keys can be downloaded and saved outside of TrueNAS. You can also extract the string from the key file and save it in a password manager. This is recommended to ensure you don’t lock yourself out of your data.

If you’re worried about losing the key, @winnielinnie possibly has a tip for you:

2 Likes