Skip to main content.

Filesystem-based encryption with PEFS

2014-03-19

Live demo in BSD Now Episode 029 | Originally written by Kris for bsdnow.tv | Last updated: 2014/03/19

NOTE: the author/maintainer of the tutorial(s) is no longer with the show, so the information below may be outdated or incorrect.

In the day and age we live in, it seems security and privacy have been thrust into the forefront of the computing world. More than ever, users and companies are trying to find ways to keep their private data private. Encryption has always been a good choice and there are a number of utilities to use, some commercial and some open-source, some kernel level and some userland. On FreeBSD, most users have been using the kernel-level "GELI" framework, usually for low-level disk encryption. Typically this would sit "underneath" the user's file-system, such as UFS or ZFS. However, this may be less than optimal in a few situations, such as wanting to encrypt only a single directory or wanting to replicate ZFS snapshots which sit on top of the GELI layer. Enter the PEFS framework. PEFS, which stands for Private Encrypted File System, is a kernel-level stacked cryptographic filesystem for FreeBSD.

One of the main differences between GELI and PEFS is that, while GELI sits below your filesystem encrypting blocks of data before it hits the disk, PEFS will sit on top, encrypting files and directories before they hit the underlying filesystem. This allows PEFS to run on the top of ZFS, which can be a benefit when wanting to replicate encrypted data using ZFS send/receive functionality. In addition, PEFS also comes bundled with a PAM module, allowing for entire home directories to be encrypted and decrypted based upon the user logging into the system, which can be very beneficial to multi-user workstations. In today’s tutorial we will be taking a look at how to install and create PEFS-encrypted directories, as well as enabling PAM logins for PEFS home directory encryption.


Getting PEFS

To start, we will need to grab PEFS from the ports tree or package repo. On PC-BSD 9.2 and later, this is included in the base-world.

# cd /usr/ports/sysutils/pefs-kmod
# make install clean

or

# pkg install pefs-kmod

Once installed, we next need to load the pefs kernel module:

# kldload pefs

If we want to keep this module loaded across reboots, add it to /boot/loader.conf:

# echo 'pefs_load="YES"' >> /boot/loader.conf

To create our first encrypted directory, we will begin with creating two new dirs:

# mkdir ~/encrypted ~/unencrypted

By default PEFS does not store any meta-data related to your keys on disk, and as such has no way to verify the correctness of the key entered. However, to achieve this functionality, PEFS does have support for keychains. A single key can be used to replicate traditional key storage.

Next we will add a single parent key to our encrypted directory.

# pefs addchain -f -Z ~/encrypted
Enter parent key passphrase:
Reenter parent key passphrase:

The -Z flag is used to specify that this keychain will consist of only a single parent key, no children. The -f flag will skip checking the underlying filesystem to see if it is already encrypted. Next, we will mount the pefs filesystem. Note that this does not require the encryption key, that will come later.

# pefs mount ~/encrypted ~/unencrypted

Note at this point that the ~/unencrypted file-system only contains the single .pefs.db file (for the keychain), and is mounted read-only. To decrypt the directory, we will next add our key:

# pefs addkey -c ~/unencrypted
Enter passphrase:

The -c flag is used to "check" the key supplied against the keychain database, and reject a mis-typed or bad key. Now the ~/unencrypted directory should be mounted r/w and we can begin adding our private data.

# echo "testing" > ~/unencrypted/test.txt
# ls ~/unencrypted/
.pefs.db test.txt
# cat ~/unencrypted/test.txt 
testing
# ls ~/encrypted/
.7ve2p00YVmMBFLlAzJ0k+BC85G67t4KT .pefs.db
# cat ~/encrypted/.7ve2p00YVmMBFLlAzJ0k+BC85G67t4KT 
<garbage>

Now we can just as easily remove our key and re-encrypt the ~/unencrypted directory:

# pefs flushkeys ~/unencrypted
# ls ~/unencrypted
.7ve2p00YVmMBFLlAzJ0k+BC85G67t4KT .pefs.db

Note that for this tutorial we used both ~/encrypted and ~/unencrypted directories. It is possible to have all this done on a single "~/encrypted" directory, simply by replacing ~/unencrypted with ~/encrypted in the commands run. Next, we will take a look at how we can use PEFS to create an encrypted home directory.

To get started, if this is an existing user, we will want to move their files out of their home directory:

# mv /usr/home/test /usr/home/test.old
# mkdir /usr/home/test
# chown test:test /usr/home/test
# pefs addchain -f -Z /usr/home/test
# pefs mount /usr/home/test /usr/home/test

Enter your username password.

# pefs addkey /usr/home/test

Enter your user's password. Next move out the .pefs.db file

# mv /usr/home/test/.pefs.db /tmp/.pefs.db

Copy data back into the encrypted filesystem.

# tar cvf - -C /usr/home/test.old . | tar xvf - -C /usr/home/test 

Unmount pefs.

# umount /usr/home/test

Copy database file back.

# mv /tmp/.pefs.db /usr/home/test/
# chown test:test /usr/home/test/.pefs.db

Re-mount pefs.

# pefs mount /usr/home/test /usr/home/test

If your /home directory is a symlink to /usr/home, you may need to adjust the passwd file. PEFS will not work on symlinks, run "vipw" and adjust your users home dir to the real path.

Lastly we need to add the PAM module to our login process.

Edit /etc/pam.d/system:

--- system  2013-08-26 09:39:18.014375012 -0400
+++ system  2014-02-25 09:36:57.141849155 -0500
@@ -9,6 +9,7 @@
 auth       requisite   pam_opieaccess.so   no_warn allow_local
 #auth      sufficient  pam_krb5.so     no_warn try_first_pass
 #auth      sufficient  pam_ssh.so      no_warn try_first_pass
+auth       sufficient  pam_pefs.so     try_first_pass delkeys
 auth       required    pam_unix.so     no_warn try_first_pass nullok

 # account
@@ -18,6 +19,7 @@

 # session
 #session   optional    pam_ssh.so      want_agent
+session        optional    pam_pefs.so         delkeys
 session        required    pam_lastlog.so      no_fail

 # password

Now we should be able to open a fresh login with the "test" user, and the home-directory will be automatically decrypted upon login, and re-encrypted at logout.


PEFS also supports more advanced keychain functionality, such as escalating privledge and such (which are outside the scope of this tutorial today). For reference, take a look at the manpage or the wiki.

Latest News

New announcement

2017-05-25

Hi, Mr. Dexter...

Two Year Anniversary

2015-08-08

We're quickly approaching our two-year anniversary, which will be on episode 105. To celebrate, we've created a unique t-shirt design, available for purchase until the end of August. Shirts will be shipped out around September 1st. Most of the proceeds will support the show, and specifically allow us to buy...

New discussion segment

2015-01-17

We're thinking about adding a new segment to the show where we discuss a topic that the listeners suggest. It's meant to be informative like a tutorial, but more of a "free discussion" format. If you have any subjects you want us to explore, or even just a good name...

How did you get into BSD?

2014-11-26

We've got a fun idea for the holidays this year: just like we ask during the interviews, we want to hear how all the viewers and listeners first got into BSD. Email us your story, either written or a video version, and we'll read and play some of them for...


Episode 207: Bridge over the river Cam

2017-08-16

Direct Download:HD VideoMP3 AudioTorrent This episode was brought to you by Headlines BSDCam recap The 2017 Cambridge DevSummit took place from 2-4 August 2017. The event took place over three days including a formal dinner at St John's College, and was attended by 55 registered developers and guests. Prior to the start of...

Episode 206: To hier is UNIX

2017-08-09

HD VideoMP3 AudioTorrent This episode was brought to you by Headlines Lumina Desktop v1.3 released Notable Changes: New Utility: lumina-mediaplayer. Lumina Media Player is a graphic interface for the Qt QMediaPlayer Class, with Pandora internet radio streaming integration. Lumina Media Player supports many audio formats, including .ogg, .mp3, .mp4, .flac, and .wmv. It is also...

Episode 205: FreeBSD Turning it up to 11.1

2017-08-02

Direct Download:HD VideoMP3 AudioTorrent This episode was brought to you by Headlines FreeBSD 11.1-RELEASE FreeBSD 11.1 was released on July 26th You can download it as an ISO or USB image, a prebuilt VM Image (vmdk, vhd, qcow2, or raw), and it is available as a cloud image (Amazon EC2, Microsoft Azure, Google Compute Engine,...

Episode 204: WWF - Wayland, Weston, and FreeBSD

2017-07-26

Direct Download:HD VideoMP3 AudioTorrent This episode was brought to you by Headlines Matt Ahrens answers questions about the “Scrub of Death” In working on the breakdown of that ZFS article last week, Matt Ahrens contacted me and provided some answers he has given to questions in the past, allowing me to answer them using...