Following the short introduction to eCryptfs and file-system encryption solutions; this article describes how I used eCryptfs to encrypt my entire $HOME, and dm-crypt to protect swap space (without breaking hibernation).



Topics:

eCryptfs basics

Encrypting a directory

Encrypting $HOME

$ su -

# mv /home/user /home/user.old

# mkdir -m 700 /home/user

# chown user:user /home/user

# usermod -d /home/user.old user

$ su -

# mkdir -p /home/.ecryptfs/user/.Private

# chmod 755 /home/.ecryptfs

# chmod -R 700 /home/.ecryptfs/user

# chown -R user:user /home/.ecryptfs/user

# ln -s /home/.ecryptfs/user/.Private /home/user/.Private

# chmod 500 /home/user

# mount -t ecryptfs /home/user/.Private /home/user

Key type: passphrase

Passphrase: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Cypher: twofish

Key byte: 32

Plaintext passtrough: yes

Filename encryption: yes

Add signature to cache: yes

# < /dev/urandom tr -cd \[:graph:\] | fold -w 32 | head -n 5

# Encrypted volumes /home/user/.Private /home/user ecryptfs rw,user,noauto,exec,ecryptfs_sig=XYZ,ecryptfs_cipher=twofish,ecryptfs_key_bytes=32,ecryptfs_passthrough,ecryptfs_fnek_sig=XYZ,ecryptfs_unlink_sigs 0 0

# touch /root/.ecryptfs/auto-mount

# ecryptfs-wrap-passphrase /root/.ecryptfs/wrapped-passphrase

Passphrase to wrap: [enter mount passphrase]

Wrapping passphrase: [enter user password]



# umount /home/user

Auto mounting on login

# mv /root/.ecryptfs /home/.ecryptfs/user

# chown -R user:user /home/.ecryptfs/user/.ecryptfs

# ln -s /home/.ecryptfs/user/.ecryptfs /home/user/.ecryptfs

# -*- shell-script -*- # if [ -r "${HOME}/.ecryptfs/auto-mount" ]; then grep -qs "${HOME} ecryptfs" /proc/mounts if [ $? -ne 0 ]; then mount -i "${HOME}" ; cd "${HOME}" fi fi

#%PAM-1.0 #... auth required pam_unix.so try_first_pass nullok auth required pam_ecryptfs.so unwrap #... password required pam_ecryptfs.so password required pam_unix.so try_first_pass nullok sha512 shadow #... # eCryptfs optional in session context #session optional pam_ecryptfs.so

$ ecryptfs-insert-wrapped-passphrase-into-keyring /home/user/.ecryptfs/wrapped-passphrase

Passphrase: [enter user password]



$ mount -i /home/user

$ rsync -aP /home/user.old/ /home/user/

# umount /home/user

# usermod -d /home/user user



# chmod 600 /home/profile.sh

# chown user:user /home/profile.sh

# mv /home/profile.sh /home/.ecryptfs/user/.Private/.profile

# ln -s /home/.ecryptfs/user/.Private/.profile /home/user/.profile



# exit

$ ln -s /home/.ecryptfs/user/.ecryptfs /home/user/.ecryptfs

$ ln -s /home/.ecryptfs/user/.Private /home/user/.Private

Encrypting swap space

$ su -



Disable swap space

# swapoff /dev/sda3



Encrypt /dev/sda3 and set a passphrase (no connection to eCryptfs one)

# cryptsetup -h sha256 -c twofish-xts-essiv:sha256 -s 256 luksFormat /dev/sda3



Map /dev/sda3 to /dev/mapper/swap (using the passphrase)

# cryptsetup luksOpen /dev/sda3 swap



Make /dev/mapper/swap a swap device

# mkswap /dev/mapper/swap



Enable the encrypted swap

# swapon -p 1 /dev/mapper/swap

#/dev/sda3 swap swap defaults 0 0 # Encrypted volumes /dev/mapper/swap swap swap defaults 0 0

#resume device = /dev/sda3 resume device = /dev/mapper/swap

/bin/cryptsetup luksOpen /dev/sda3 swap

# mkinitcpio -p kernel26

Encrypting other directories

# Pseudo none /tmp tmpfs defaults,size=512M,mode=1777 0 0

Notes on security

$ ls -al ~/.ecryptfs/wrapped-passphrase

lrwxrwxrwx 1 user user 18 2009-03-14 21:45 /home/user/.ecryptfs/wrapped-passphrase -> /mnt/usb/.ecryptfs/key

usb -fstype=vfat,utf8,shortname=mixed,noexec,umask=077,fmask=0177,dmask=0077,uid=1000,gid=1000 :/dev/sdc1

eCryptfs is a kernel-native stacked cryptographic file-system for GNU/Linux, that is used on top of existing mounted file-systems. It is a part of Linux since version 2.6.19 (the ecryptfs module), but to work with it you need the userspace tools: ecryptfs-utils , which in turn require keyutils (tools for the kernel key management system). Once you install these two packages you can modprobe ecryptfs and continue with the setup. If you are interested in implementation details I highly recommend the Linux Journal article by Michael Halcrow , the architect and former developer of eCryptfs. Today Michael works at Microsoft on BitLocker - their own disk encryption solution.I co-authored another article on eCryptfs, that guides you trough the process of creating a secure and private directoryyour $HOME. You can read it on the Arch Linux wiki First you need to backup your current $HOME, what I did was:After your new $HOME becomes /home/user.old re-login to the system. Then prepare the rest of the eCryptfs directory structure:Directory /home/.ecryptfs is owned by root and it is a central place for everything related to eCryptfs and user accounts. Everything under /home/.ecryptfs/user is owned by you and the actual encrypted data will be stored in /home/.ecryptfs/user/.Private. That directory will be mounted on top of /home/user (for convenience I will use the symlink /home/user/.Private when mounting). While /home/user is not mounted we made sure that nothing can be written there with that last chmod command. This will prevent cronjobs and other software from causing problems.: Previously this article explained a much simpler setup, using /home/user as both lower and upper directory. This new approach is better and safer. Among other things it avoids problems with cronjobs (as explained), and it is much easier to access your encrypted data (i.e. for backup).We can now mount eCryptfs over /home/user - notice that while mounted it will have the same permissions as the lower .Private directory:Since this is the first time you are mounting this directory eCryptfs will ask you some questions about how you want it set up. Summary of my own options:Filename encryption is available from Linux 2.6.29, and I enabled passtrough because I needed it for auto-mounting later (it allows un-encrypted files to be stored in the lower directory). When asked you can also generate an additional key that will be used for filename encryption, or you can use the same key you generated for encrypting file contents. As for your passphrase, I don't need to tell you that it should be strong, you can generate a batch of strong pseudo-random passphrases with a command like:Remember it or print it on paper for safe keeping, this will be your mount passphrase which will be used to mount this directory. Without it your data is: The relation between aand(s) could be confusing, so I will explain it in more detail; The passphrase is your mount passphrase which will be salted, hashed and loaded into the kernel keyring. In eCryptfs terms, this salted, hashed passphrase is your "file encryption key, encryption key", or(I will refer to it as just "key" later in the text). Also, in eCryptfs terms the key used to protect filenames is known as "filename encryption key", or. Usually it is automatically generated from the same passphrase, which is salted and hashed a little differently then it was for generating theThe directory is now mounted and your key is in the kernel keyring. We now have to edit a few files to allow easier mounts in the future. First inspect your /etc/mtab file, it contains an entry for encrypted /home/user, which you need to replicate in /etc/fstab. An example entry in fstab might then look like (XYZ represents the key signature):When mounting your new $HOME as a user you will use mount -i so you don't invoke the mount helper again. Using -i by default mounts with noexec, nosuid, nodev - this being your $HOME you will probably want to have executable files, so I added exec to the above fstab line.When you mounted, a /root/.ecryptfs directory was automatically created - that's where the signature cache was stored. Let's create a few other files in there (later we will move this configuration directory, and transfer the ownership to you):Let's explain the second command. We are using a passphrase for our mount point and the key needs to be added to the kernel keyring every time we want to mount /home/user. Our later goal is to have auto-mounting on login, so to make that easier and automatic we encrypted our mount passphrase with our login password. The resulting hash is stored in the wrapped-passphrase file, which can be unwraped by the eCryptfs PAM module on login (more about this below). This also has some security implications, which we will discuss later on.Our initial setup is done, let's un-mount the directory:To be able to auto-mount when you login to the system your eCryptfs configuration directory must be readable, it can't be encrypted. We will now move it to /home/.ecryptfs/user:Now we have to write the actual auto-mounting code. Forthe simplest solution was to employ shell initialization files. In my case and ZSH those being ~/.zprofile and ~/.zshrc. In case of BASH ~/.profile and ~/.bashrc can be used. The way your shell reads init files is important, the profile file is read first and in case it's an interactive shell the rc file is read next. You could add the auto-mount code to your existing profile or rc file and leave it un-encrypted. But let's not expose any more information than it is absolutely needed. I setup my ~/.zprofile to mount on login and left ~/.zshrc encrypted. Let's see the example code:In order for this code to be executed the file must be readable. That's why we enabled passtrough before. Save it as /home/profile.sh for now.: An alternative to mounting from your shell profile is to use the pam-mount package. You should also know that eCryptfs PAM module has some auto-mounting functionality, but most of it was written with Ubuntu in mind. To make use of it you would have to setup everything exactly the way Ubuntu does. In fact, if you followed this guide then you already did so. However it's not possible to change default options and you would have to use AES and a 16 byte key. How does it work? If the PAM module finds the auto-mount file it unwraps the passphrase and proceeds to call /sbin/mount.ecryptfs_private which can successfully mount only if all above requirements are met. Same thing applies to un-mounting when session is closed, provided the PAM stack is configured correctly.Now we need to configure PAM to automatically unwrap the passphrase on login (using the password the user entered to login to the system). My current workstation is running Arch Linux so I modified /etc/pam.d/system-auth - on other distributions /etc/pam.d/login or common-auth could be used (also consider the run-level and possibly login manager you are using). The important part being to add the first setting immediatelythe line referencing the pam_unix.so module in the auth context and the second immediatelythe line referencing the pam_unix.so module in the password context. Let's see an example from Arch Linux:Now that you prepared everything for automatic mounting you can once again mount /home/user to transfer your files back - and encrypt them in the process. When you un-mounted the directory the key was deleted from the kernel keyring so you will have to insert it once more. This would also be a good place to mention thatutility can be used for key management or for some simpler operations you can use theNow move or copy your files from /home/user.old to /home/user. If you have enough space you should definitely copy so you have a backup. Files will be encrypted as they are placed in their new home:When it's done you should exit and login as root, un-mount the encrypted directory and change your $HOME once more. Last step is to setup the shell profile you prepared earlier:You can now login as a user to test if auto-mounting works. PAM will unwrap your passphrase and insert the key into the kernel keyring. Your auto-mount code from ~/.profile will be run next. You are now using an encrypted $HOME directory.It is a good idea to create another set of links (this time encrypted) to your eCryptfs configuration directories, so that both your encrypted and un-encrypted $HOME points to them:Various data is leaked to your swap space. If we are encrypting our $HOME we have to encrypt swap too. Since eCryptfs is not ideal for encrypting entire partitions we will use dm-crypt for this. Since nothing permanent is stored in swap you can setup dm-crypt to use agenerated key every boot and re-write the swap space. But in order for suspend to disk to work the hibernation image must not be changed/deleted. I have read all kinds of miss-information about this, many claimed it's impossible to use encrypted swap with hibernation. It's not true. Important thing being to use akey for encryption - so your swap stays unchanged on next boot and hibernation image intact.: My swap partition is /dev/sda3 and I use uswsusp for suspend/hibernate. Examples are written accordingly.First we will setup an encrypted swap space, with dm-crypt and LUKS . Luks is needed because of the static key, in Arch Linux package is calledSwap is configured, now edit a few files to tell your system to use this new swap. Everything that will be written to it will be encrypted on the fly and actually written to your real swap partition. First comment out your current swap entry in /etc/fstab and create a new one pointing to your new swap space:Uswsusp (or whatever method you are using - kernel, TuxOnIce) also needs to know that the new resume device is /dev/mapper/swap. Edit /etc/suspend.conf and replace your entry:: You can also setup encryption with uswsusp it self. More information can be found in /usr/share/doc/suspend/README.encryption. Basically you generate a key file /etc/suspend.key, enable encryption in suspend.conf and point "RSA key file" entry to the key you generated. Your hibernate image would already be encrypted once when written to /dev/mapper/swap, but if you really want two layers of encryption you could do it.Now comes the really tricky part. In order to resume from hibernation your (encrypted)swap must be mounted early on. How hibernation is usually done is with a resume hook in your initrd. You will need another hook in there that will setup swap before resume hook is run. I will explain my setup on Arch Linux, for Debian I found one guide on how to do it there Arch Linux already has an encrypt hook that is used to mount the root (and) file-system in case it's encrypted. All other encrypted partitions are mounted later on from /etc/crypttab - not of much use for hibernation, because by then it would be too late. I modified the hook /lib/initcpio/hooks/encrypt and changedto "/dev/sda3" andto "swap". In recent versions the syntax has changed andis used like so: cryptdevice="/dev/sda3:swap swap=/dev/mapper/swap". This also means that you can append "cryptdevice=/dev/sda3:swap" to the kernel in your boot loader configuration and avoid editing the hook all together.The basic thing here is that a command like the following example must be run on boot (it will ask for the passphrase and then unlock the swap partition):Add the encrypt hook to /etc/mkinitcpio.confthe uresume/resume and filesystems hooks. You should then re-create the initrd:All done. You can reboot and test it with a clean hibernation cycle.: If you have concerns about using a static key, consider using a static key only when you hibernate, while using a random key otherwise. It can be done and you will find examples of automation on the web. If nothing else you can re-mount the swap by hand, using a passphrase, before hibernating.Some other directories to consider for encryption are: /tmp and /var/tmp. You could use dm-crypt or eCryptfs with random keys for /tmp since nothing permanent is stored there. But because of this, you could also just setup /tmp asand have it in memory. The /var/tmp directory is trickier, it holds some data that should be preserved and it should be mountedin the boot process (before anything else is written there). Doing it would be an interesting exercise.An example fstab entry for the tmpfs:If you decided to use auto-mounting eCryptfs setup explained here employs a strong encryption passphrase for your files, but actually protects it with your user login password (which in most cases doesn't even have 10 characters). First think about making your login password more complex, using eCryptfs or not. The Diceware method provides strong passwords that are easy to remember. I also recommend this document on password recovery speeds Simple method for drastically improving the security of your eCryptfs setup is to move your wrapped-passphrase file to a removable storage device, like a memory card. Symlink it to your eCryptfs configuration directory, and in this scenario you get two-factor authentication, something you(your password) and something only you(your wrapped-passphrase file):: If you ever change your login password you can use the ecryptfs-rewrap-passphrase utility to update and re-encrypt your wrapped-passphrase file.Using this method requires your removable storage to be mounted before you login. Modern distributions allow you to auto-mount through udev but there are also legacy solutions like autofs which still work good. Using it your media would be mounted the moment PAM tries to read your wrapped-passphrase. Here are some mount options to consider:Consider using additional layers of encryption. You can encrypt individual files (i.e. that hold passwords) or tarball-ed directories with GPG . If needed, tools like Elettra provide plausible deniability.Last topic I will discuss are backups. Backup is mandatory, but if you went through all this to secure your data you can't just dump it on a file-server. The data must remain encrypted. One approach is to encrypt the destination it self, the other to backup the source in encrypted form (or both, yes). For removable drives both options are feasible, but in case of a network file-system eCryptfs is still not fully functional over NFS. My personal backup solution, rybackup , has eCryptfs support and could give you some ideas.