I've been playing with TrueNAS scale recently and while the BUI allows you to export/download ZFS wrapping key I wanted to know how to get the key manually. After a quick look at the code I found that the key is stored in sqlite db kept on root file system.
root@truenas[~]# sqlite3 /data/freenas-v1.db SQLite version 3.34.1 2021-01-20 14:10:07 Enter ".help" for usage hints. sqlite> select * from storage_encrypteddataset; 1|backup|ioI/B72PEllUJjumWpWHkdhDDCd2l2eopFEJgWYIpcAcTT1v0NyYicjzKiHfuoncL2Mklfa45pUJIyxzGFGobr17b1HtprjSth/X9yyfsnROCK/xQL+SVmO/5fT/KabfSSiz8+IfDH8=|The key itself is encrypted so you need to decrypt it first before it can be used with ZFS. A simple python script to do it attached below.
root@truenas[~]# ./decode_key.py dataset: backup key: 16f7677b514ef39bc162312274c76da24221ecc5a2f01e6ba0bhfeec054d9162(both the encrypted and decrypted keys above have been modified for this blog entry)
root@truenas[~]# cat decode_key.py
#!/usr/bin/python3
# based on /usr/lib/migrate113/freenasUI/system/migrations/0022_cloud_sync.py
import sys
import base64
from Cryptodome.Cipher import AES
import sqlite3
PWENC_BLOCK_SIZE = 32
PWENC_FILE_SECRET = '/data/pwenc_secret'
PWENC_PADDING = b'{'
def pwenc_get_secret():
with open(PWENC_FILE_SECRET, 'rb') as f:
secret = f.read()
return secret
def pwenc_decrypt(encrypted=None):
if not encrypted:
return ""
from Cryptodome.Util import Counter
encrypted = base64.b64decode(encrypted)
nonce = encrypted[:8]
encrypted = encrypted[8:]
cipher = AES.new(
pwenc_get_secret(),
AES.MODE_CTR,
counter=Counter.new(64, prefix=nonce),
)
return cipher.decrypt(encrypted).rstrip(PWENC_PADDING).decode('utf8')
if len(sys.argv) == 2:
print(pwenc_decrypt(sys.argv[1]))
exit(0)
dbcon = sqlite3.connect('/data/freenas-v1.db')
dbcur = dbcon.cursor()
for row in dbcur.execute('select * from storage_encrypteddataset'):
ds_id, ds_name, ds_enc_key, kmip_enc_key = row
#print(ds_id, ds_name, ds_enc_key, pwenc_decrypt(ds_enc_key))
print(f'dataset: {ds_name}\n key: {pwenc_decrypt(ds_enc_key)}\n')
Thank you :)
ReplyDeleteThank you!
ReplyDeleteAnd kudos to https://www.truenas.com/community/threads/solved-can-unlock-pool-with-encryption-key-but-not-datasets.108337/post-749329 for making me realize the first checkbox on the import page is to toggle between (json) key file & direct entry (in case you didn't realize either ;) )