google / fscrypt

Go tool for managing Linux filesystem encryption
Apache License 2.0
886 stars 99 forks source link

Add new 'metadata_dir' configuration file option #325

Closed sbuisson-ddn closed 2 years ago

sbuisson-ddn commented 2 years ago

The new 'metadata_dir' configuration file option specifies a path to store the fscrypt metadata directory (.fscrypt). This is useful if you want to put this outside of any filesystem or directory configured for encryption.

sbuisson-ddn commented 2 years ago

I just signed Google Individual CLA, it should be better now.

ebiggers commented 2 years ago

Can you explain more concretely what the use case is for this option? Encryption policies are only valid on the filesystem on which they are applied, so it makes sense to store them on the same filesystem as the encrypted directories. It can make sense to store protectors elsewhere (and in fact login protectors are always stored on the root filesystem), but it seems desirable to keep things simple. So I am not sure the benefit of this outweights the extra complexity; can you explain your use case?

sbuisson-ddn commented 2 years ago

As it is not possible to encrypt the root of an ext4 file system, this patch is useful when you want to present only encrypted content to users. The idea is to mount the root of the file system somewhere not visible/accessible to users, and then make use of a bind mount to present the encrypted directory that we want to make accessible to users. In this scenario, the .fscrypt directory (at the root of the file system) cannot be found by fscrypt when calling ‘fscrypt unlock’ on the bind mount directory. And fscrypt cannot follow the bind mount trace back to the original root mount, as we intentionally make it inaccessible. By using the new ‘metadata_dir’ option, we can instruct fscrypt to fetch its metadata from a different location, independent from the file system configured for encryption. Maybe the proposed patch is not the most straightforward way to achieve this, so I would be glad to try a different approach if you can think of a less complex move.

ebiggers commented 2 years ago

Two things.

  1. fscrypt isn't the right tool to encrypt a whole filesystem with one key. If you want to do this, then LUKS/dm-crypt would be a better choice. Does your use case involve multiple keys per filesystem?

  2. Suppose that we made it so that if the filesystem's /.fscrypt directory is bind-mounted somewhere, then fscrypt automatically recognized that the metadata should be stored there. Would this solve your problem? For example, consider the following mounts:

Filesystem    Subtree       Mountpoint
----------    -------       ----------
/dev/sda      /home         /home
/dev/sda      /.fscrypt     /.fscrypt

So, there is a filesystem on /dev/sda, and only the /home and /.fscrypt subtrees of it are mounted in the current mount namespace. Currently, fscrypt errors out in this case because all subtrees are nonoverlapping and all mountpoints are nonoverlapping. That seems unexpected. We could make fscrypt recognize that metadata should be stored in the .fscrypt directory if it is mounted directly (instead of being visible via a whole-filesystem mount). This would require some changes in the filesystem/ directory in the source, but it shouldn't be too hard.

sbuisson-ddn commented 2 years ago

Indeed, making fscrypt recognize that metadata should be stored in the .fscrypt directory if it is mounted directly would do the trick. And this solution would not have the drawback of storing policies and protectors on a different filesystem than the encrypted directories, so it sounds all good.

Do you have any idea on how this could be implemented in fscrypt? If you can give some hints I could try to make a patch.

ebiggers commented 2 years ago

Indeed, making fscrypt recognize that metadata should be stored in the .fscrypt directory if it is mounted directly would do the trick. And this solution would not have the drawback of storing policies and protectors on a different filesystem than the encrypted directories, so it sounds all good.

Do you have any idea on how this could be implemented in fscrypt? If you can give some hints I could try to make a patch.

The code that scans /proc/self/mountinfo to determine where to store the fscrypt metadata for each filesystem is located in filesystem/mountpoint.go and filesystem/filesystem.go. findMainMount() would need to be updated to return a Mount with Subtree == "/" + baseDirName (i.e. /.fscrypt), if one is present and a Mount with Subtree == "/" is not present. Also, BaseDir() would need to be updated to return the mount path directly if the Mount has Subtree == "/" + baseDirName. There are some unit tests that would need to be updated. I'm not sure whether there would be anything else, maybe documentation?

sbuisson-ddn commented 2 years ago

This pull request can be closed in favor of https://github.com/google/fscrypt/pull/327 .