linux filesystem encryption
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:
-
ecryptfs is implemented in kernel, which can make it run faster due to less frequent context switches;
-
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;
-
ecryptfs keys are stored in the kernel keyring, identified by key signatures;
-
mount and unmount require root privilege;
-
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 packagee2fsprogs
:# 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;