fscrypt is a high-level tool for the management of Linux native filesystem
encryption.
fscrypt manages metadata, key generation, key wrapping, PAM integration, and
provides a uniform interface for creating and modifying encrypted directories.
For a small low-level tool that directly sets policies, see
fscryptctl.
To use fscrypt, you must have a filesystem that supports the Linux native
filesystem encryption API (which is also sometimes called "fscrypt"; this
documentation calls it "Linux native filesystem encryption" to avoid confusion).
Only certain filesystems, such as ext4 and
f2fs, support this API. For a full list
of supported filesystems and how to enable encryption support on each one, see
Runtime dependencies.
Operating-system level storage encryption solutions work at either the
filesystem or block device level. Linux native filesystem
encryption
(the solution configured by fscrypt) is filesystem-level; it encrypts
individual directories. Only file contents and filenames are encrypted;
non-filename metadata, such as timestamps, the sizes and number of files, and
extended attributes, is not encrypted. Users choose which directories will
be encrypted, and with what keys.
Before using fscrypt, you should consider other solutions:
dm-crypt/LUKS is block device
level encryption: it encrypts an entire block device (and hence an entire
filesystem) with one key. Unlocking this key will unlock the entire block
device. dm-crypt/LUKS is usually configured using
cryptsetup.
eCryptfs is an alternative
filesystem-level encryption solution. It is a stacked filesystem, which means
it sits on top of a real filesystem, rather than being directly integrated
into the real filesystem. Stacked filesystems have a couple advantages (such
as working on almost any real filesystem), but also some significant
disadvantages. eCryptfs is usually configured using
ecryptfs-utils.
The ZFS filesystem supports
encryption in its own way (not compatible with fscrypt). ZFS encryption has
some advantages; however, ZFS isn't part of the upstream Linux kernel and is
less common than other filesystems, so this solution usually isn't an option.
Which solution to use? Here are our recommendations:
eCryptfs shouldn't be used, if at all possible. eCryptfs's use of filesystem
stacking causes a number of issues, and eCryptfs is no longer actively
maintained. The original author of eCryptfs recommends using Linux native
filesystem encryption instead. The largest users of eCryptfs (Ubuntu and
Chrome OS) have switched to dm-crypt or Linux native filesystem encryption.
If you need fine-grained control of encryption within a filesystem, then use
fscrypt, or fscrypt together with dm-crypt/LUKS. If you don't need this,
then use dm-crypt/LUKS.
To understand this recommendation: consider that the main advantage of
fscrypt is to allow different files on the same filesystem to be encrypted
by different keys, and thus be unlockable, lockable, and securely deletable
independently from each other. Therefore, fscrypt is useful in cases such
as:
Multi-user systems, since each user's files can be encrypted with their
own key that is unlocked by their own passphrase.
Single-user systems where it's not possible for all files to have the
strongest level of protection. For example, it might be necessary for the
system to boot up without user interaction. Any files that are needed to
do so can only be encrypted by a hardware-protected (e.g. TPM-bound) key
at best. If the user's personal files are located on the same filesystem,
then with dm-crypt/LUKS the user's personal files would be limited to this
weak level of protection. With fscrypt, the user's personal files could
be fully protected using the user's passphrase.
fscrypt isn't very useful in the following cases:
Single-user systems where the user is willing to enter a strong passphrase
at boot time to unlock the entire filesystem. In this case, the main
advantage of fscrypt would go unused, so dm-crypt/LUKS would be better
as it would provide better security (due to ensuring that all files and
all filesystem metadata are encrypted).
Any case where it is feasible to create a separate filesystem for every
encryption key you want to use.
Note: dm-crypt/LUKS and fscrypt aren't mutually exclusive; they can be used
together when the performance hit of double encryption is tolerable. It only
makes sense to do this when the keys for each encryption layer are protected
in different ways, such that each layer serves a different purpose. A
reasonable set-up would be to encrypt the whole filesystem with dm-crypt/LUKS
using a TPM-bound key that is automatically unlocked at boot time, and also
encrypt users' home directories with fscrypt using their login passphrases.
Threat model
Like other storage encryption solutions (including dm-crypt/LUKS and eCryptfs),
Linux native filesystem encryption is primarily intended to protect the
confidentiality of data from a single point-in-time permanent offline compromise
of the disk. For a detailed description of the threat model, see the kernel
documentation.
It's worth emphasizing that none of these encryption solutions protect unlocked
encrypted files from other users on the same system (that's the job of OS-level
access control, such as UNIX file permissions), or from the cloud provider you
may be running a virtual machine on. By themselves, they also do not protect
from "evil maid" attacks, i.e. non-permanent offline compromises of the disk.
Briefly, fscrypt deals with protectors and policies. Protectors represent some
secret or information used to protect the confidentiality of your data. The
three currently supported protector types are:
Your login passphrase, through PAM.
The included PAM module (pam_fscrypt.so) can automatically unlock
directories protected by your login passphrase when you log in, and lock them
when you log out. IMPORTANT: before using a login protector, follow
Setting up for login protectors.
A custom passphrase. This passphrase is hashed with
Argon2id, by default calibrated to
use all CPUs and take about 1 second.
These protectors are mutable, so the information can change without needing to
update any of your encrypted directories.
Policies represent the actual key passed to the kernel. This "policy key" is
immutable and policies are (usually) applied to a single directory. Protectors
then protect policies, so that having one of the protectors for a policy is
enough to get the policy key and access the data. Which protectors protect a
policy can also be changed. This allows a user to change how a directory is
protected without needing to reencrypt the directory's contents.
Concretely, fscrypt contains the following functionality:
fscrypt setup - Creates /etc/fscrypt.conf and the /.fscrypt directory
This is the only functionality which always requires root privileges
fscrypt setup MOUNTPOINT - Gets a filesystem ready for use with fscrypt
fscrypt encrypt DIRECTORY - Encrypts an empty directory
fscrypt unlock DIRECTORY - Unlocks an encrypted directory
fscrypt lock DIRECTORY - Locks an encrypted directory
fscrypt purge MOUNTPOINT - Locks all encrypted directories on a filesystem
fscrypt status [PATH] - Gets detailed info about filesystems or paths
fscrypt metadata - Manages policies or protectors directly
See the example usage section below or run fscrypt COMMAND --help for more
information about each of the commands.
Building and installing
fscrypt has a minimal set of build dependencies:
Go 1.16 or higher. Older versions may work
but they are not tested or supported.
A C compiler (gcc or clang)
make
Headers for libpam.
Install them with the appropriate package manager:
Once all the dependencies are installed, you can get the repository by running:
go get -d github.com/google/fscrypt/...
Running make in $GOPATH/src/github.com/google/fscrypt builds the binary
(fscrypt) and PAM module (pam_fscrypt.so) in the bin/ directory.
Running sudo make install installs fscrypt into /usr/local/bin,
pam_fscrypt.so into /usr/local/lib/security, and pam_fscrypt/config into
/usr/local/share/pam-configs.
On Debian (and Debian derivatives such as Ubuntu), use sudo make install PREFIX=/usr to install into /usr instead of the default of /usr/local.
Ordinarily you shouldn't manually install software into /usr, since /usr is
reserved for Debian's own packages. However, Debian's PAM configuration
framework only recognizes configuration files in /usr, not in /usr/local.
Therefore, the PAM module will only work if you install into /usr. Note: if
you later decide to switch to using the Debian package libpam-fscrypt, you'll
have to first manually run sudo make uninstall PREFIX=/usr.
It is also possible to use make install-bin to only install the fscrypt
binary, or make install-pam to only install the PAM files.
Alternatively, if you only want to install the fscrypt binary to
$GOPATH/bin, simply run:
go get github.com/google/fscrypt/cmd/fscrypt
See the Makefile for instructions on how to further customize the build.
Runtime dependencies
To run, fscrypt needs the following libraries:
libpam.so (almost certainly already on your system)
In addition, fscrypt requires a filesystem that supports the Linux native
filesystem encryption API. Currently, the filesystems that support this are:
ext4, with upstream kernel v4.1 or later. The kernel configuration must
contain CONFIG_FS_ENCRYPTION=y (for kernels v5.1+) or
CONFIG_EXT4_ENCRYPTION=y or =m (for older kernels). The filesystem must
also have the encrypt feature flag enabled; to enable this flag, see
here.
f2fs, with upstream kernel v4.2 or later. The kernel configuration must
contain CONFIG_FS_ENCRYPTION=y (for kernels v5.1+) or
CONFIG_F2FS_FS_ENCRYPTION=y (for older kernels). The filesystem must also
have the encrypt feature flag enabled; this flag can be enabled at format
time by mkfs.f2fs -O encrypt or later by fsck.f2fs -O encrypt.
UBIFS, with upstream kernel v4.10 or later. The kernel configuration must
contain CONFIG_FS_ENCRYPTION=y (for kernels v5.1+) or
CONFIG_UBIFS_FS_ENCRYPTION=y (for older kernels).
Lustre, with Lustre v2.14.0 or later. For details,
see the Lustre documentation. Please note that Lustre is not part of the
upstream Linux kernel, and its encryption implementation has not been reviewed
by the authors of fscrypt. Questions/issues about Lustre encryption should
be directed to the Lustre developers. Lustre version 2.14 does not encrypt
filenames, even though it claims to, so v2.15.0 or later should be used.
To check whether the needed option is enabled in your kernel, run:
It is also recommended to use Linux kernel v5.4 or later, since this
allows the use of v2 encryption policies. v2 policies have several
security and usability improvements over v1 policies.
Be careful when using ext4 encryption on removable media, since ext4 filesystems
with the encrypt feature cannot be mounted on systems with kernel versions
older than the minimums listed above -- even to access unencrypted files!
If you configure fscrypt to use non-default features, other kernel
prerequisites may be needed too. See Configuration
file.
Configuration file
Running sudo fscrypt setup will create the configuration file
/etc/fscrypt.conf if it doesn't already exist. It's a JSON file
that looks like the following:
"source" is the default source for new protectors. The choices are
"pam_passphrase", "custom_passphrase", and "raw_key".
"hash_costs" describes how difficult the passphrase hashing is.
By default, fscrypt setup calibrates the hashing to use all CPUs
and take about 1 second. The --time option to fscrypt setup can
be used to customize this time when creating the configuration file.
"options" are the encryption options to use for new encrypted
directories:
"padding" is the number of bytes by which filenames are padded
before being encrypted. The choices are "32", "16", "8", and
"4". "32" is recommended.
"contents" is the algorithm used to encrypt file contents. The
choices are "AES_256_XTS", "AES_128_CBC", and "Adiantum".
Normally, "AES_256_XTS" is recommended.
"filenames" is the algorithm used to encrypt file names. The
choices are "AES_256_CTS", "AES_128_CTS", and "Adiantum".
Normally, "AES_256_CTS" is recommended.
To use algorithms other than "AES_256_XTS" for contents and
"AES_256_CTS" for filenames, the needed algorithm(s) may need to
be enabled in the Linux kernel's cryptography API. For example,
to use Adiantum, CONFIG_CRYPTO_ADIANTUM must be set. Also,
not all combinations of algorithms are allowed; for example,
"Adiantum" for contents can only be paired with "Adiantum" for
filenames. See the kernel
documentation
for more details about the supported algorithms.
"policy_version" is the version of encryption policy to use.
The choices are "1" and "2". If unset, "1" is assumed.
Directories created with policy version "2" are only usable on
kernel v5.4 or later, but are preferable to version "1" if you
don't mind this restriction.
"use_fs_keyring_for_v1_policies" specifies whether to add keys for v1
encryption policies to the filesystem keyrings, rather than to user keyrings.
This can solve issues with processes being unable to access unlocked
encrypted files.
However, it requires kernel v5.4 or later, and it makes unlocking and locking
encrypted directories require root. (The PAM module will still work.)
The purpose of this setting is to allow people to take advantage of some of
the improvements in Linux v5.4 on encrypted directories that are also
compatible with older kernels. If you don't need compatibility with older
kernels, it's better to not use this setting and instead (re-)create your
encrypted directories with "policy_version": "2".
"allow_cross_user_metadata" specifies whether fscrypt will allow
protectors and policies from other non-root users to be read, e.g. to be
offered as options by fscrypt encrypt. The default value is false, since
other users might be untrusted and could create malicious files. This can be
set to true to restore the old behavior on systems where fscrypt metadata
needs to be shared between multiple users. Note that this option is
independent from the permissions on the metadata files themselves, which are
set to 0600 by default; users who wish to share their metadata files with
other users would also need to explicitly change their mode to 0644.
Setting up fscrypt on a filesystem
fscrypt needs some directories to exist on the filesystem on which encryption
will be used:
MOUNTPOINT/.fscrypt/policies
MOUNTPOINT/.fscrypt/protectors
(If login protectors are used, these must also exist on the root filesystem.)
To create these directories, run fscrypt setup MOUNTPOINT. If MOUNTPOINT is
owned by root, as is usually the case, then this command will require root.
There will be one decision you'll need to make: whether non-root users will be
allowed to create fscrypt metadata (policies and protectors).
If you say y, then these directories will be made world-writable, with the
sticky bit set so that users can't delete each other's files -- just like
/tmp. If you say N, then these directories will be writable only by root.
Saying y maximizes the usability of fscrypt, and on most systems it's fine
to say y. However, on some systems this may be inappropriate, as it will
allow malicious users to fill the entire filesystem unless filesystem quotas
have been configured -- similar to problems that have historically existed with
other world-writable directories, e.g. /tmp. If you are concerned about this,
say N. If you say N, then you'll only be able to run fscrypt as root to
set up encryption on users' behalf, unless you manually set custom permissions
on the metadata directories to grant write access to specific users or groups.
If you chose the wrong mode at fscrypt setup time, you can change the
directory permissions at any time. To enable single-user writable mode, run:
sudo chmod 0755 MOUNTPOINT/.fscrypt/*
To enable world-writable mode, run:
sudo chmod 1777 MOUNTPOINT/.fscrypt/*
Setting up for login protectors
If you want any encrypted directories to be protected by your login passphrase,
you'll need to:
Secure your login passphrase (optional, but strongly recommended)
Enable the PAM module (pam_fscrypt.so)
If you installed fscrypt from source rather than from your distro's package
manager, you may also need to allow fscrypt to check your login passphrase.
Securing your login passphrase
Although fscrypt uses a strong passphrase hash algorithm, the security of
login protectors is also limited by the strength of your system's passphrase
hashing in /etc/shadow. On most Linux distributions, /etc/shadow by default
uses SHA-512 with 5000 rounds, which is much weaker than what fscrypt uses.
To mitigate this, you should use a strong login passphrase.
If using a strong login passphrase is annoying because it needs to be entered
frequently to run sudo, consider increasing the sudo timeout. That can be
done by adding the following to /etc/sudoers:
Defaults timestamp_timeout=60
You should also increase the number of rounds that your system's passphrase
hashing uses (though this doesn't increase security as much as choosing a strong
passphrase). To do this, find the line in /etc/pam.d/passwd that looks like:
Append rounds=1000000 (or another number of your choice; the goal is to make
the passphrase hashing take about 1 second, similar to fscrypt's default):
Then, change your login passphrase to a new, strong passphrase:
passwd
If you'd like to keep the same login passphrase (not recommended, as the old
passphrase hash may still be recoverable from disk), then instead run
sudo passwd $USER and enter your existing passphrase. This re-hashes your
existing passphrase with the new rounds.
Enabling the PAM module
To enable the PAM module pam_fscrypt.so, follow the directions for your Linux
distro below. Enabling the PAM module is needed for login passphrase-protected
directories to be automatically unlocked when you log in (and be automatically
locked when you log out), and for login passphrase-protected directories to
remain accessible when you change your login passphrase.
Enabling the PAM module on Debian or Ubuntu
The official libpam-fscrypt package for Debian (and Debian derivatives such as
Ubuntu) will install a configuration file for Debian's PAM configuration
framework to
/usr/share/pam-configs/fscrypt. This file contains reasonable defaults for
the PAM module. To automatically apply these defaults, run
sudo pam-auth-update and follow the on-screen instructions.
This file also gets installed if you build and install fscrypt from source,
but it is only installed to the correct location if you use make install PREFIX=/usr to install into /usr instead of the default of /usr/local.
Enabling the PAM module on Arch Linux
On Arch Linux, follow the recommendations at the Arch Linux
Wiki.
We recommend using the Arch Linux package, either fscrypt (official) or
fscrypt-git (AUR). If you instead install fscrypt manually using sudo make install, then in addition to the steps on the Wiki you'll also need to create
/etc/pam.d/fscrypt.
Enabling the PAM module on other Linux distros
On all other Linux distros, follow the general guidance below to edit
your PAM configuration files.
The fscrypt PAM module implements the Auth, Session, and Password
types.
The Password functionality of pam_fscrypt.so is used to automatically rewrap
a user's login protector when their unix passphrase changes. An easy way to get
the working is to add the line:
password optional pam_fscrypt.so
after pam_unix.so in /etc/pam.d/common-password or similar.
The Auth and Session functionality of pam_fscrypt.so are used to automatically
unlock directories when logging in as a user, and lock them when logging out.
An easy way to get this working is to add the line:
auth optional pam_fscrypt.so
after pam_unix.so in /etc/pam.d/common-auth or similar, and to add the
line:
session optional pam_fscrypt.so
after pam_unix.so in /etc/pam.d/common-session or similar, but before
pam_systemd.so or any other module that accesses the user's home directory or
which starts processes that access the user's home directory during their
session.
To make pam_fscrypt.so print debugging messages to the system log, add the
debug option. All hook types accept this option.
Allowing fscrypt to check your login passphrase
This step is only needed if you installed fscrypt from source code.
Some Linux distros use restrictive settings in /etc/pam.d/other that prevent
programs from checking your login passphrase unless a per-program PAM
configuration file grants access. This prevents fscrypt from creating any
login passphrase-protected directories, even without auto-unlocking. To ensure
that fscrypt will work properly (if you didn't install an official fscrypt
package from your distro, which should have already handled this), also create a
file /etc/pam.d/fscrypt containing:
auth required pam_unix.so
Backup, restore, and recovery
Encrypted files and directories can't be backed up while they are "locked", i.e.
while they appear in encrypted form. They can only be backed up while they are
unlocked, in which case they can be backed up like any other files. Note that
since the encryption is transparent, the files won't be encrypted in the backup
(unless the backup applies its own encryption).
For the same reason (and several others), an encrypted directory can't be
directly "moved" to another filesystem. However, it is possible to create a new
encrypted directory on the destination filesystem using fscrypt encrypt, then
copy the contents of the source directory into it.
For directories protected by a custom_passphrase or raw_key protector, all
metadata needed to unlock the directory (excluding the actual passphrase or raw
key, of course) is located in the .fscrypt directory at the root of the
filesystem that contains the encrypted directory. For example, if you have an
encrypted directory /home/$USER/private that is protected by a custom
passphrase, all fscrypt metadata needed to unlock the directory with that
custom passphrase will be located in /home/.fscrypt if you are using a
dedicated /home filesystem or in /.fscrypt if you aren't. If desired, you
can back up the fscrypt metadata by making a copy of this directory, although
this isn't too important since this metadata is located on the same filesystem
as the encrypted directory(s).
pam_passphrase (login passphrase) protectors are a bit different as they are
always stored on the root filesystem, in /.fscrypt. This ties them to the
specific system and ensures that each user has only a single login protector.
Therefore, encrypted directories on a non-root filesystem can't be unlocked
via a login protector if the operating system is reinstalled or if the disk is
connected to another system -- even if the new system uses the same login
passphrase for the user.
Because of this, fscrypt encrypt will automatically generate a recovery
passphrase when creating a login passphrase-protected directory on a non-root
filesystem. The recovery passphrase is simply a custom_passphrase protector
with a randomly generated high-entropy passphrase. Initially, the recovery
passphrase is stored in a file in the encrypted directory itself; therefore, to
use it you must record it in another secure location. It is strongly
recommended to do this. Then, if ever needed, you can use fscrypt unlock to
unlock the directory with the recovery passphrase (by choosing the recovery
protector instead of the login protector).
If you really want to disable the generation of a recovery passphrase, use the
--no-recovery option. Only do this if you really know what you are doing and
are prepared for potential data loss.
Alternative approaches to supporting recovery of login passphrase-protected
directories include the following:
Manually adding your own recovery protector, using
fscrypt metadata add-protector-to-policy.
Backing up and restoring the /.fscrypt directory on the root filesystem.
Note that after restoring the /.fscrypt directory, unlocking the login
protectors will require the passphrases they had at the time the backup was
made even if they were changed later, so make sure to remember these
passphrase(s) or record them in a secure location. Also note that if the UUID
of the root filesystem changed, you will need to manually fix the UUID in any
.fscrypt/protectors/*.link files on other filesystems.
The auto-generated recovery passphrases should be enough for most users, though.
Encrypting existing files
fscrypt isn't designed to encrypt existing files, as this presents significant
technical challenges and usually is impossible to do securely. Therefore,
fscrypt encrypt only works on empty directories.
Of course, it is still possible to create an encrypted directory, copy files
into it, and delete the original files. The mv command will even work, as it
will fall back to a copy and delete (except on older
kernels).
However, beware that due to the characteristics of filesystems and storage
devices, this may not properly protect the files, as their original contents may
still be forensically recoverable from disk even after being deleted. It's
much better to encrypt files from the very beginning.
There are only a few cases where copying files into an encrypted directory can
really make sense, such as:
The source files are located on an in-memory filesystem such as tmpfs.
The confidentiality of the source files isn't important, e.g. they are
system default files and the user hasn't added any personal files yet.
The source files are protected by a different fscrypt policy, the old and
new policies are protected by only the same protector(s), and the old policy
uses similar strength encryption.
If one of the above doesn't apply, then it's probably too late to securely
encrypt your existing files.
As a best-effort attempt, you can use the shred program to try to erase the
original files. Here are the recommended commands for "best-effort" encryption
of an existing directory named "dir":
mkdir dir.new
fscrypt encrypt dir.new
cp -a -T dir dir.new
find dir -type f -print0 | xargs -0 shred -n1 --remove=unlink
rm -rf dir
mv dir.new dir
However, beware that shred isn't guaranteed to be effective on all storage
devices and filesystems. For example, if you're using an SSD, "overwrites" of
data typically go to new flash blocks, so they aren't really overwrites.
Note: for reasons similar to the above, changed or removed fscrypt protectors
aren't guaranteed to be forensically unrecoverable from disk either. Thus, the
use of weak or default passphrases should be avoided, even if changed later.
Example usage
All these examples assume there is an ext4 filesystem which supports
encryption mounted at /mnt/disk. See
here for how
to enable encryption support on an ext4 filesystem.
Setting up fscrypt on a directory
# Check which directories on our system support encryption
>>>>> fscrypt status
filesystems supporting encryption: 1
filesystems with fscrypt metadata: 0
MOUNTPOINT DEVICE FILESYSTEM ENCRYPTION FSCRYPT
/ /dev/sda1 ext4 not enabled No
/mnt/disk /dev/sdb ext4 supported No
# Create the global configuration file. Nothing else necessarily needs root.
>>>>> sudo fscrypt setup
Defaulting to policy_version 2 because kernel supports it.
Customizing passphrase hashing difficulty for this system...
Created global config file at "/etc/fscrypt.conf".
Allow users other than root to create fscrypt metadata on the root filesystem?
(See https://github.com/google/fscrypt#setting-up-fscrypt-on-a-filesystem) [y/N] y
Metadata directories created at "/.fscrypt", writable by everyone.
# Start using fscrypt with our filesystem
>>>>> sudo fscrypt setup /mnt/disk
Allow users other than root to create fscrypt metadata on this filesystem? (See
https://github.com/google/fscrypt#setting-up-fscrypt-on-a-filesystem) [y/N] y
Metadata directories created at "/mnt/disk/.fscrypt", writable by everyone.
# Initialize encryption on a new empty directory
>>>>> mkdir /mnt/disk/dir1
>>>>> fscrypt encrypt /mnt/disk/dir1
The following protector sources are available:
1 - Your login passphrase (pam_passphrase)
2 - A custom passphrase (custom_passphrase)
3 - A raw 256-bit key (raw_key)
Enter the source number for the new protector [2 - custom_passphrase]: 2
Enter a name for the new protector: Super Secret
Enter custom passphrase for protector "Super Secret":
Confirm passphrase:
"/mnt/disk/dir1" is now encrypted, unlocked, and ready for use.
# We can see this created one policy and one protector for this directory
>>>>> fscrypt status /mnt/disk
ext4 filesystem "/mnt/disk" has 1 protector and 1 policy
PROTECTOR LINKED DESCRIPTION
7626382168311a9d No custom protector "Super Secret"
POLICY UNLOCKED PROTECTORS
16382f282d7b29ee27e6460151d03382 Yes 7626382168311a9d
请发表评论