this article introduces 3 filesystem encryption tools on the linux system: encfs, ecryptfs and fscrypt; they can encrypt specific dirs and files, either natively or using a stacked filesystem; encryption is transparent so that users can manage encrypted files as usual;

encfs

encfs is the easiest one to work with; it is a fuse-based stacked filesystem encrypting both contents and filenames; no root privilege is needed whatsoever; encfs works by mounting a secret dir containing encrypted files (aka: lower dir) onto a public dir mountpoint (aka: upper dir); the public dir provides an unencrypted view of the secret dir;

to install encfs:

# dnf install fuse-encfs

our example assumes we have 2 dirs secret and public in current dir;

mount an encfs is ezpz:

$ encfs `realpath ./secret` `realpath ./public`

the encfs command only accepts absolute paths; it then prompts for a few questions; most of the time we can simply press enter to select standard mode then type a password; we are done;

now we can work in the public dir as usual; changes done in the public dir are backed by the secret dir; when we are done, we can unmount the public dir with:

$ fusermount -u ./public

the secret dir contains a config file .encfs6.xml, which is auto created upon mount if not existing; this config file contains crypto metadata, specifically, the master key encrypted with the password; this config file is very important; losing this file means losing everything that is encrypted;

to backup an encfs, simply copy the secret dir to another place; the secret dir is self-contained and can be mounted elsewhere;

ecryptfs

ecryptfs is also a stacked filesystem; it is different from encfs in several aspects:

  1. ecryptfs is implemented in kernel, which can make it run faster due to less frequent context switches;

  2. ecryptfs stores crypto metadata in the header of each encrypted file; all encrypted files are self-contained; there is no config file in the secret dir;

  3. ecryptfs keys are stored in the kernel keyring, identified by key signatures;

  4. mount and unmount require root privilege;

  5. filename encryption is optional;

to install ecryptfs userspace utility:

# dnf install ecryptfs-utils

our example assumes we have 2 dirs secret and public in current dir;

to use ecryptfs, we need to first load kernel module ecryptfs:

# modprobe ecryptfs

then mount:

# mount -t ecryptfs ./secret ./public

this command pops some questions about mount options, then mounts;

now we can work in the public dir as usual; changes done in the public dir are backed by the secret dir; when we are done, we can unmount the public dir with:

# umount ./public

to backup an ecryptfs, simply copy the secret dir or individual files to another place; all files are self-contained and can be decrypted independently;

fscrypt

fscrypt is a kernel library that supports native filesystem encryption; while encfs and ecryptfs create another stacked filesystem on top of the underlying filesystem, fscrypt is integrated directly into the underlying filesystem;

fscrypt does not support encrypting files in-place; instead, it marks an empty dir as encrypted; crypto metadata are stored in filesystem structures such as inodes; the master key comes from the kernel keyring;

fscrypt only works with a limited set of filesystems; ext4 is one of them;

there are 2 userspace utilities that work with fscrypt:

  • an older but classic e4crypt coming from package e2fsprogs:

    # dnf install e2fsprogs
    

    our example uses this one;

  • a newer, feature-rich fscrypt; download from here;

because fscrypt is not a stacked filesystem, we do not need public or secret dirs as in previous examples; instead, we create an ext4 filesystem in a file fs and mount this filesystem to a mountpoint mp, so that we dont have to change our root filesystem;

$ truncate -s 1G fs         # create filesystem media;
$ mkfs.ext4 fs              # format filesystem into ext4;
$ tune2fs -O encrypt fs     # enable `encrypt` feature on filesystem;
$ mkdir mp                  # create mountpoint;
# mount fs mp               # mount filesystem to mountpoint;

our next job is to create an empty dir to hold encrypted contents:

$ cd mp && mkdir secret     # make an empty dir `secret`;

we then add a key into the kernel keyring:

$ e4crypt add_key
Enter passphrase (echo disabled):
Added key with descriptor [xxxxxxxxxxxxxxxx]

finally, set encryption policy (more or less a key) for the secret dir:

$ e4crypt set_policy xxxxxxxxxxxxxxxx secret
Key with descriptor [xxxxxxxxxxxxxxxx] applied to secret.

now we can use this filesystem as usual; all contents and filenames under the secret dir will be encrypted; the same filesystem can hold a mixture of both unencrypted and encrypted files;

when we are done, we replace the current session with a new one:

$ e4crypt new_session

in theory, we should not be able to see encrypted contents any more; in practice, we need to drop page cache:

# echo 3 > /proc/sys/vm/drop_caches

now if we browse the secret dir, we can only see encrypted contents;

we do not suggest an unmount here, because users often do not unmount their root filesystem; instead, replace session as shown above;

because fscrypt is not a stacked filesystem, there is no “lower” filesystem for us to backup; to backup encrypted contents, we need to decrypt first;

comparison

encfs, ecryptfs and fscrypt may have different filename length limit, symlink size limit and per-file size overhead; here we did a comparison (all numbers in bytes):

  len(filename) len(symlink) len(overhead)
encfs 175 3055 8
ecryptfs 143 3007 8192
fscrypt 255 4093 4096

some notes about the comparison:

  • some numbers come from our tests, which may vary on your system; read them with a grain of salt;

  • encfs usually has 8-byte per-file overhead when uniqueIV is enabled in the config file (which is the default); this option enables per-file initialization vector; when disabled, encfs has 0 overhead;

  • the ecryptfs 8192-byte overhead is based on an empty file; ecryptfs often incurs more overhead on non-empty files;

  • when filename encryption is disabled, ecryptfs supports the full 255-byte filename length and the full 4095-byte symlink size;

  • fscrypt file size overhead is currently unknown; our tests show each encrypted file uses 4096-byte more disk space than unencrypted; note that the displayed file size is the same whether encrypted or not;

  • fscrypt has an extra 2-byte overhead on symlink targets, hence 4093;

visit here for more comparisons:

additional topics

this article is meant to show a minimal example of these linux filesystem encryption tools; there are additional topics that we didnt cover in this article: password change, auto mount, key wrapping, etc.; visit their homepages to find more information;