zfs icon indicating copy to clipboard operation
zfs copied to clipboard

Multiple encryption keys/key methods

Open sjau opened this issue 6 years ago • 70 comments

I'd like to propose a feature request to support multiple key slots/method slots like LUKS does it.

This can be very useful so that for example 2 different people have different passwords and they can independantly open up the encrypted dataset without needing to know the other's (highly secure and complex) passphrase.

Also, if you have multiple zpools it could be useful to provide path to the keyfile to automatically unlock it if needed...

sjau avatar Nov 05 '17 09:11 sjau

I too desire multiple key slots. My thoughts are these:

  1. Having a second key may allow recovery. Meaning you can have a master encryption key on a USB flash drive, kept locked up. But the normal operations staff have access to a another one with a password. If the password get's lost or changed without knowing what it is, the master can be used.

  2. Additionally, an option to allow either R/W or R/O keys would be useful. This would affect mounting the dataset and ability to change the keys, (like operations for backups would only need R/O). But, there would be a safeguard to prevent deleting the last R/W key.

  3. Also, perhaps a Master / Secondary flag for each key. This would allow 2 slots to both be R/W, but a Secondary could not delete / change the key or password from the Master slot. Again useful when dealing with operations staff who may perform scheduled changes involving reboots or pool imports. Plus, there should be a safeguard in place that would prevent the last Master key from being deleted.

For the last, it could very well be numerical order, and not Master / Secondary. That would be useful if we had more than 2 keys.

Having watched the chaos when users have used FreeNAS's Geli disk encryption, and not understood it, I would prefer a scheme that had more than 1 key slot. (Still won't protect users from themselves. But, this may protect Unix SysAdmins from having to perform restores when someone else looses or changes the key, and can't supply any key...)

Lady-Galadriel avatar Dec 26 '17 21:12 Lady-Galadriel

@sjau, in regards to;

Also, if you have multiple zpools it could be useful to provide path to the keyfile to automatically unlock it if needed...

This sort of works already. It's in the manual page, (which I don't have handy). I did submit a feature request to allow RAW keys to be stored on disk partitions, (like an USB flash drive), #6556

Lady-Galadriel avatar Dec 26 '17 21:12 Lady-Galadriel

well the think with auto-unlock was how I used luks/dm-crypt... I can either provide the key file or enter manually the key... which is convenvient

sjau avatar Dec 26 '17 21:12 sjau

All variations are supported if I remember correctly. Prompt or path to passphrase or key;

Prompt for passphrase Prompt for location of key file

Path to file with passphrase Path to file with key

As I said, I don't have the manual page handy to show examples. And if the path does not exist, it defaults back to prompt, (if I remember correctly...).

Lady-Galadriel avatar Dec 26 '17 21:12 Lady-Galadriel

the benefit is if you have multiple key slots... if you can provide a password or a path to file.. just whatever seems more convenient... e.g. have a keyfile in /root on your server, take out the disk, use it somewhere else and since the keyfile won't exist on the other system, provide password

sjau avatar Dec 26 '17 21:12 sjau

Yes, that would be useful at times.

Plus. it would allow for split mirror pools. Basically have a mirrored pool, (at least 2 way, but more is supported), and use the zpool split command to create a second pool. One you could export and import elsewhere using a passphrase.

Lady-Galadriel avatar Dec 26 '17 21:12 Lady-Galadriel

that's why I suggested it...

sjau avatar Dec 26 '17 21:12 sjau

@tcaputi

Is this possible to add as feature?

sjau avatar Feb 03 '18 10:02 sjau

@sjau

Is this possible to add as feature?

Yes. The current implementation was actually designed with the ability to support multiple keys at some point. It has just not been a priority for me at the moment and I currently have a few other projects which I've committed to working on first. With regards to some of the specific features and use-cases that have been mentioned:

This can be very useful so that for example 2 different people have different passwords and they can independantly open up the encrypted dataset without needing to know the other's (highly secure and complex) passphrase.

This is probably the biggest use case that I can think of.

Having a second key may allow recovery. Meaning you can have a master encryption key on a USB flash drive, kept locked up. But the normal operations staff have access to a another one with a password. If the password get's lost or changed without knowing what it is, the master can be used.

This really just boils down to the above use case of having 2 people with different passphrases / keys.

Additionally, an option to allow either R/W or R/O keys would be useful. This would affect mounting the dataset and ability to change the keys, (like operations for backups would only need R/O). But, there would be a safeguard to prevent deleting the last R/W key.

Also, perhaps a Master / Secondary flag for each key. This would allow 2 slots to both be R/W, but a Secondary could not delete / change the key or password from the Master slot. Again useful when dealing with operations staff who may perform scheduled changes involving reboots or pool imports. Plus, there should be a safeguard in place that would prevent the last Master key from being deleted.

Unfortunately, the cryptography here doesn't allow for this. All data is protected with symmetric key encryption, so there is no R/O key. Using public key cryptography would render the implementation uselessly slow. Without the ability to do this, it becomes impossible to have primary / secondary keys since then the secondary key could only be stopped from making changes via permissions which are trivial to patch over if you have root access to the machine. As a general rule, we have decided not to implement encryption functionality that cannot be enforced with cryptography so that we don't have this odd distinction between things that can / can't be done maliciously and things that can / can't be done inadvertently. My personal belief on the matter is that encryption and permissions need to be thought of differently and kept separate.

Plus. it would allow for split mirror pools. Basically have a mirrored pool, (at least 2 way, but more is supported), and use the zpool split command to create a second pool. One you could export and import elsewhere using a passphrase.

Not quite sure if I understand here. Couldn't you just copy the key and use it for the new pool?

tcaputi avatar Feb 03 '18 11:02 tcaputi

@tcaputi

No worries... just take your time.. I know you're quite busy... but at least #8684 is merged now :)

I wasn't sure if you've seen this before, that's why I sent a message to you. It's a convenience feature and I'm glad to hear that the current encryption is designed with multi-slots use later on.

sjau avatar Feb 03 '18 11:02 sjau

Additionally, an option to allow either R/W or R/O keys would be useful. This would affect mounting the dataset and ability to change the keys, (like operations for backups would only need R/O). But, there would be a safeguard to prevent deleting the last R/W key.

As a quick side note, scrubs / resilvers can be accomplished without any loaded keys. Backups can be taken without keys as well if you use the zfs send --raw feature.

tcaputi avatar Feb 03 '18 11:02 tcaputi

I think it's really great that scrubs / resilver / raw send don't required to load the keys. So even third parties can do that maintenance easily :)

sjau avatar Feb 03 '18 11:02 sjau

Any chance this feature will be included in a 0.8 point upgrade?

jknockaert avatar Jun 18 '19 13:06 jknockaert

In general, point releases are meant for bug fixes and so I would not expect this feature to show up in 0.8.x release. I am also not currently working on this feature at the moment.

tcaputi avatar Jun 18 '19 20:06 tcaputi

This feature would be awesome to have. I'm really paranoid about my keyfile being somehow corrupted or something, and my data being inaccessible without it. I will of course backup the keyfile to several locations, but still, one can't help but worry.

viggy96 avatar Jul 15 '19 02:07 viggy96

I agree that this feature would be nice to have, but I don't think it will help you with protecting your key file from corruption. At the end of the day keeping access to your data is just a matter of keeping access to a key that will work. Therefore, having a backup of the key is exactly the same as having a different key for this purpose. This feature is more about allowing multiple people to have their own passwords or keys to access the data.

tcaputi avatar Jul 15 '19 06:07 tcaputi

The general way to do this is to have an encrypted key, and then multiple keys which can be used to decrypt it. (Tom knows this, I'm just not sure how much other people do, so sorry if it sounds condescending.) So the change here would be to add user/key pairs somewhere, which would then be used to unlock the main key.

kithrup avatar Jul 15 '19 07:07 kithrup

@kithrup Isn't that the idea behind the current implementation? Aren't the user provided passwords/keys just used as a wrapper for the real encryption key?

viggy96 avatar Jul 15 '19 18:07 viggy96

Yes, the user/key mapping just hasn't been done :).

kithrup avatar Jul 16 '19 16:07 kithrup

Consider another vote for interest in the feature. I want to implement a clevis/tang unlocker for ZFS. Use case is needing a breakglass key in case the tang server goes up in flames. I like clevis/tang, but I'm not willing to run it (in production) without a backup way to decrypt the data.

mddeff avatar Dec 28 '19 03:12 mddeff

Could we use properties for this securely, as an interim/0.8.x measure? e.g.

# openssl enc -aes-256-cbc -pbkdf2 -a -A < tank-test.key > tank-test.key.aes
enter aes-256-cbc encryption password: ********
Verifying - enter aes-256-cbc encryption password: ********
# cat tank-test.key.aes
U2FsdGVkX19Ifd8hLvjm1RGFfA23zkNxE/GilHh9Z/32b6DDqeO44mkskgPcZy4ec1PQH/FowzPQLDZRKoP9OQ==#
# zfs set cryptkey:001='U2FsdGVkX19Ifd8hLvjm1RGFfA23zkNxE/GilHh9Z/32b6DDqeO44mkskgPcZy4ec1PQH/FowzPQLDZRKoP9OQ==' tank/test
# zfs get cryptkey:001 tank/test
NAME          PROPERTY      VALUE                                                                                     SOURCE
tank/test  cryptkey:001  U2FsdGVkX19Ifd8hLvjm1RGFfA23zkNxE/GilHh9Z/32b6DDqeO44mkskgPcZy4ec1PQH/FowzPQLDZRKoP9OQ==  local

And then running the inverse ( -d ) and setting keyformat=raw keylocation=outfile. My interest is disaster recovery here; this would probably be inconvenient for frequent key swapping. Some simple scripts could help.

I think this wouldn't work for pools with encrypted root datasets, but if somebody could correct me about the status of the root-level properties being encrypted or not that would be great.

bill-mcgonigle avatar Feb 20 '20 22:02 bill-mcgonigle

@bill-mcgonigle yes that should work as long as you are happy with the sercurity of aes-cbc. I'm not actually all that familiar with the openssl command line tool, but this looks right. It should also work for pools with encrypted root filesystems. You can still import such pools to zfs get the properties you need. It just won't mount the root filesystem without the key.

tcaputi avatar Feb 20 '20 23:02 tcaputi

@bill-mcgonigle I am not sure if I correctly understand what you're doing here. I assume that tank-test.key is the (unique) encryption key, and you're storing an encrypted version of it (encrypted using password ********) as an arbitrary zfs property (which you call cryptkey:001 but it could effectively have any name not yet in use by an existing zfs property). So in fact you're using the zfs properties table to store an (externally) encrypted version of the zfs key. Am I correct?

jknockaert avatar Mar 30 '20 15:03 jknockaert

Is this currently being worked on? I was hoping I could replace LUKS with native ZFS encryption soon.

mdPlusPlus avatar Nov 06 '20 14:11 mdPlusPlus

We need some form of recover password as it was said earlier but it is very important topic

robszy avatar Sep 24 '21 19:09 robszy

Until /etc/init.d/zfs-load-key is merged and this is implemented, I use this workaround.

/usr/lib/dracut/modules.d/99local/module-setup.sh

#!/bin/sh

check() {
  return 0
}

depends() {
  echo zfs
  return 0
}

install() {
  inst_hook pre-mount 80 "${moddir}/zfs-load-key-all.sh"
}

/usr/lib/dracut/modules.d/99local/zfs-load-key-all.sh

modprobe zfs
zpool import -N -a
# Prevent linux kernel from printing messages over passphrase prompt
echo 3 > /proc/sys/kernel/printk

while true; do
  stty -echo
  read -p "Passphrase for datasets: " PASS
  stty echo
  echo "$PASS" | zfs load-key encryption-root1 || continue
  echo "$PASS" | zfs load-key encryption-root2 || continue
  break
done

crocket avatar Nov 30 '21 13:11 crocket

@crocket Isn't this something else? The issue is about having multiple keys for a single zpool/zfs dataset, not a single key for multiple zpools/zfs datasets.

mdPlusPlus avatar Apr 08 '22 21:04 mdPlusPlus

Yes, it is something else. I just wanted one password to unlock everything.

crocket avatar Apr 09 '22 01:04 crocket

Is there any movement on this issue? It is the only thing stopping us from using zfs :(

Djarid avatar Jun 15 '22 10:06 Djarid

why does it stop you from using ZFS? you can layer ZFS on LUKS.

bghira avatar Jun 15 '22 15:06 bghira