Skip to main content.

Filesystem-based encryption with PEFS


Live demo in BSD Now Episode 029 | Originally written by Kris for | 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


# 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 
# ls ~/encrypted/
.7ve2p00YVmMBFLlAzJ0k+BC85G67t4KT .pefs.db
# cat ~/encrypted/.7ve2p00YVmMBFLlAzJ0k+BC85G67t4KT 

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   no_warn allow_local
 #auth      sufficient     no_warn try_first_pass
 #auth      sufficient      no_warn try_first_pass
+auth       sufficient     try_first_pass delkeys
 auth       required     no_warn try_first_pass nullok

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

 # session
 #session   optional      want_agent
+session        optional         delkeys
 session        required      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

Two Year Anniversary


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


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?


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...

EuroBSDCon 2014


As you might expect, both Allan and Kris will be at EuroBSDCon this year. They'll be busy hunting down various BSD developers and forcing them to do interviews, but don't hesitate to say hi if you're a listener!...

Episode 186: The Fast And the Firewall: Tokyo Drift


Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines AsiaBSDcon Reports and Reviews AsiaBSDcon schedule Schedule and slides from the 4th bhyvecon Michael Dexter’s trip report on the iXsystems blog NetBSD AsiaBSDcon booth report TrueOS Community Guidelines are here! TrueOS has published its new Community Guidelines The TrueOS Project has existed for over ten years. Until...

Episode 185: Exit Interview


Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Interview – Kris Moore – / @pcbsdKrisTrueOS founder, FreeNAS developer, BSD Now co-hostBenedict Reuschling – / @bsdbcrFreeBSD commiter & FreeBSD Foundation Vice President, BSD Now co-host Send questions, comments, show ideas/topics, or stories you want mentioned on the show...

Episode 184: Tokyo Dreaming


Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines OpenBSD A2k17 hackathon reports a2k17 hackathon report: Patrick Wildt on the arm64 port a2k17 hackathon report: Antoine Jacoutot on syspatch, rc.d improvements and more a2k17 hackathon report: Martin Pieuchot on NET_LOCK and much more a2k17 hackathon report: Kenneth Westerback on...

Episode 183: Getting Steamy Here


Direct Download:VideoHD VideoMP3 AudioOGG AudioTorrent This episode was brought to you by Headlines playonbsd with TrueOS: It’s Getting Steamy in Here and I’ve Had Too Much Wine We’ve done a couple of tutorials in the past on using Steam and Wine with PC-BSD, but now with the addition of playonbsd to the...