User:Lukeus Maximus

From ArchWiki

Home directory encryption

One common use of stacked filesystem encryption is to encrypt a user's home directory.

If the home directory exists on an Ext4 filesystem then this form of Data-at-rest_encryption should be set up before any data is stored in the home directory (preferably just after creation). This is because Ext4 is a journaled filesystem; if existing unencrypted files are copied into the new encrypted directory, the old unencrypted version of the file is generally recoverable from the Ext4 filesystem. To make the old unencrypted versions of these files unrecoverable, a secure deletion technique must be used on them.

This article covers the cases where the home directory is empty and where it already contains user data.

Example using gocryptfs

Install gocryptfs.

Create new encrypted filesystem

As root, create the directory /home/$user.cipher:

# mkdir /home/$user.cipher

Change its permissions, owner, and group so that it matches those of the user's existing home directory:

# chown $user /home/$user.cipher
# chgrp $user /home/$user.cipher
# chmod 700 /home/$user.cipher

Then set up the encrypted filesystem using gocryptfs on the /home/$user.cipher directory:

$ gocryptfs -init /home/$user.cipher

When prompted, enter the password to be used for encryption. If you intend to set up auto-mounting, the password needs to be the same as the user's login password for it to work correctly. The process will finish by printing out the master key. Store the master key somewhere secure - it can be used to recover the filesystem data if the password is lost:

Choose a password for protecting your files.
Password: 
Repeat:

Your master key is:

    00000000-11111111-22222222-33333333-
    44444444-55555555-66666666-77777777

If the gocryptfs.conf file becomes corrupted or you ever forget your password,
there is only one hope for recovery: The master key. Print it to a piece of
paper and store it in a drawer. This message is only printed once.
The gocryptfs filesystem has been created successfully.
You can now mount it using: gocryptfs /home/$user.cipher MOUNTPOINT

If the user's home directory is empty, you can skip to configuring auto-mounting.

Moving existing home directory files to encrypted filesystem

You will need to mount the newly created encrypted filesystem and copy the entirety of the user's home directory into it. As each file is copied in, it is encrypted by gocryptfs. To avoid any programs changing files in the user's home directory in the middle of the copy operation, the user must be logged out. Then, as root:

1. Create the user's new home directory

# mv /home/$user /home/$user.old
# mkdir -m 700 /home/$user
# chown $user /home/$user
# chgrp $user /home/$user

2. Mount the encrypted filesystem at the new home directory

Enter the encryption password when prompted

# gocryptfs /home/$user.cipher /home/$user

3. Copy all home directory files into the mounted filesystem

(Using rsync)

# rsync -av /home/$user.old/ /home/$user

4. Unmount the filesystem

# fusermount -u /home/$user

Auto-mounting on login

If the user logs in without their home directory mounted, their session will not benefit from any shell profile files or any programs configured to run at login. Until the directory is mounted with gocryptfs, the user's home directory will be empty. Generally then, it is highly desirable to have the encrypted home directory mount itself when the user logs in so that those things happen properly.

This setup configures PAM and pam_mount so that the user's home directory is mounted as they authenticate. The authentication credentials (e.g. password) are passed to pam_mount so that they can be used for the filesystem decryption. This requires that the encrypted filesystem be encrypted with the same password as the user uses for login.

1. Configure FUSE

Uncomment user_allow_other in /etc/fuse.conf:

/etc/fuse.conf
# The file /etc/fuse.conf allows for the following parameters:
#
# user_allow_other - Using the allow_other mount option works fine as root, in
# order to have it work as user you need user_allow_other in /etc/fuse.conf as
# well. (This option allows users to use the allow_other option.) You need
# allow_other if you want users other than the owner to access a mounted fuse.
# This option must appear on a line by itself. There is no value, just the
# presence of the option.

user_allow_other


# mount_max = n - this option sets the maximum number of mounts.
# Currently (2014) it must be typed exactly as shown
# (with a single space before and after the equals sign).

#mount_max = 1000

2. Configure pam_mount

In /etc/security/pam_mount.conf.xml add a new XML tag just before </pam_mount>

/etc/security/pam_mount.conf.xml
...

<volume user="$user" fstype="fuse" options="nodev,nosuid,quiet,nonempty,allow_other"
path="/usr/bin/gocryptfs#/home/%(USER).cipher" mountpoint="/home/%(USER)" />

</pam_mount>

3. Configure PAM

Create /etc/pam.d/homedirs to:

/etc/pam.d/homedirs
#%PAM-1.0

auth      optional                   pam_mount.so
password  optional                   pam_mount.so
session   required                   pam_mkhomedir.so
session   optional                   pam_mount.so

Then edit /etc/pam.d/system-local-login and /etc/pam.d/system-remote-login to include the homedirs file.

/etc/pam.d/system-local-login
%PAM-1.0

auth      include   system-login
auth      include   homedirs         
account   include   system-login
account   include   homedirs
password  include   system-login
password  include   homedirs
session   include   system-login
session   include   homedirs

/etc/pam.d/system-remote-login
%PAM-1.0

auth      include   system-login
auth      include   homedirs         
account   include   system-login
account   include   homedirs
password  include   system-login
password  include   homedirs
session   include   system-login
session   include   homedirs

(source [1])

Logging in as the user will now cause the encrypted filesystem to be mounted transparently. Logging out will correspondingly unmount the encrypted filesystem.

Securely delete the unencrypted home directory

If it was not empty, the user's home directory was moved to $user.old earlier. These unencrypted files need removing securely; otherwise the encryption protecting the data can be easily avoided by just looking in the other folder. These older files need deleting securely as well - simply performing rm -rf $user.old will not remove the file from disk completely, it will just remove the reference to it.

Multiple tools exist that claim to delete files securely (most notably shred) but these come into conflict with the journaling functions of jornaling filesystems (such as Ext4). The secure deletion tool is trying to make it so that you can't recover your files whilst the journaled filesystem is trying to make sure that you can recover them.