Main Menu: Home | Ebola | Facts | FAQ | Food Club | FreeBSD | LOVE_BOT | Music | Patriot | Sexy | Tea | Who? | Contact Bob Vesterman

FreeBSD Full Disk Encryption, with an external boot drive, GELI, and UFS

Table of Contents


January, 2015. For about a decade now, I've been using full disk encryption on FreeBSD. Many articles I've seen on the web giving directions on how to accomplish this are not really "full disk"; they leave some of your hard drive unencrypted because the boot code itself needs to be unencrypted. I, on the other hand, am unreasonably paranoid, and so have long had my boot code on an external thumb drive so that my entire hard drive is encrypted. After booting, the thumb drive can be removed and physically kept with you or in a trusted place.

In the past, whenever I set up a new computer, I've used the instructions in the paper Complete Hard Disk Encryption Using FreeBSD's GEOM Framework by Marc Schiesser to accomplish this. This worked well for me for many years, but unfortunately, it now seems to be obsolete with respect to newer versions of FreeBSD (at least as of FreeBSD 10.1; perhaps earlier versions too).

So, I recently went looking for information on how to accomplish this same thing nowadays. I was unable to find such information. However, what I did find was able to get me far enough that I could figure the rest out, and I eventually got it up and running. I don't really want to figure this stuff out again every time I make a new machine, so I figured I would write down the steps I took in order to get it all working. Then I decided I might as well publish it to the web in case anyone else is interested.

These instructions worked for me as of FreeBSD 10.1-RELEASE. They use the UFS file system, not the newfangled ZFS (originally I tried using ZFS, but I kept getting kernel crashes). They also use GELI, not GBDE (I have no opinion on the relative merits of the two - I know virtually nothing about how they work, and I've never even used GBDE at all).

Please note that following these instructions assume you do not want any of the data that may already be on your disks. That information will be gone forever if you follow these intructions.

As I alluded to above, these instructions are heavily based upon, and indebted to, other instructions I found on the web that were very helpful but did not quite get me all the way to where I wanted to go. These include, but are not necessarily limited to, Disk Setup on FreeBSD by Warren Block, and Full Disk Encryption in FreeBSD & OpenBSD by TJ and Allan Jude. And once again, thanks to the above-mentioned Complete Hard Disk Encryption Using FreeBSD's GEOM Framework by Marc Schiesser, which served me well for many years.

Initial Setup

Plug in the USB thumb drive that you want to set up to be a boot drive. Put the FreeBSD install CD in your CD drive. Boot from the FreeBSD install CD. Select "Boot Multi User". When the "Welcome" menu comes up, select "Install". Continue through the installation process setting whatever options you want, until you get to the "Partitioning" menu. There, select "Shell", and a command line shell should open.

Determine Existing Disks

Use sysctl to determine what disks exist; in this case, there are one USB drive (da0), three hard drives (ada0, ada1, ada2), and one CD drive (cd0):

		      # sysctl kern.disks
		      kern.disks: da0 ada2 ada1 ada0 cd0

The USB drive is my thumb drive, which I want to make into my boot drive. The CD drive currently contains my FreeBSD install CD. I want the hard drive ada0 to contain my system's root partition and a swap partition, and the other two hard drives (ada1 and ada2) to each contain a data partition and a swap partition.

Wipe Preexisting Data

Optionally, at this point you might want to overwrite any preexisting data on your hard drives with zeroes or, preferably, random values. You can do so using the dd command; exact instructions are not given here, but you can find them on the web, or try "man dd".

Please note that even if you skip this step, following the remainder of the instructions will still make your preexisting data unusable (I guess without serious disk recovery efforts). So do not confuse skipping this step with retaining your data.

Destroy Existing Partitions

Get rid of any partitioning currently on the USB drive and the hard drives (I'm warning you one last time that following these instructions will result in you losing whatever data you might already have on these disks):

		      # gpart destroy -F da0
		      da0 destroyed
		      # gpart destroy -F ada0
		      ada0 destroyed
		      # gpart destroy -F ada1
		      ada1 destroyed
		      # gpart destroy -F ada2
		      ada2 destroyed

Partition the USB Drive

Create a GPT partitioning scheme on the USB drive:

		      # gpart create -s gpt da0
		      da0 created

Add two partitions to the USB drive, the first for the boot loader and the second for /boot:

		      # gpart add -t freebsd-boot -s 512k -a 4k da0
		      da0p1 added
		      # gpart add -t freebsd-ufs -l boot -s 1g -a 1m da0
		      da0p2 added

Install Bootcode on the USB Drive

Install the bootcode to partition 1 on the USB drive:

		      # gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 da0
		      bootcode written to da0

Partition the Hard Drives

Create GPT partitioning schemes on each of the three hard drives:

		      # gpart create -s gpt ada0
		      ada0 created
		      # gpart create -s gpt ada1
		      ada1 created
		      # gpart create -s gpt ada2
		      ada2 created

Figure out how much space is available on the first hard drive:

		      # gpart show ada0
		      =>        34  1953525101  ada0  GPT  (932G)
		                34  1953525101        - free -  (932G)

Add a partition for the root directory, giving it an offset (-b) of 1 megabyte, and sizing it (-s) so as to leave enough room for swap (in this case, I want 8 gigabytes of swap, and there are 932G on the drive, so 923G to take rounding and such into account):

		      # gpart add -t freebsd-ufs -l root -b 1M -s 923G ada0
		      ada0p1 added

Check to see that there's really enough room for swap:

		      # gpart show ada0
		      =>        34  1953525101  ada0  GPT  (932G)
		                34        2014        - free -  (1.0M)
		              2048  1935671296     1  freebsd-ufs  (923G)
		        1935673344    17851791        - free -  (8.5G)

In this case there is, as there's 8.5G free at the end of the disk and we want an 8G swap partition. If there weren't, "gpart delete -i 1 ada0" to delete ada0's first partition, and the "gpart add" it again using a smaller size.

Add the partition for swap:

		      # gpart add -t freebsd-swap -l swap -s 8G ada0
		      ada0p2 added

Create partitions for the other two disks. In this case I want two partitions each, an eight gig swap and a rest-of-disk UFS partition:

		      # gpart add -t freebsd-swap -l swap -b 1M -s 8G ada1
		      ada1p1 added
		      # gpart add -t freebsd-ufs -l disk2 ada1
		      ada1p2 added
		      # gpart add -t freebsd-swap -l swap -b 1M -s 8G ada2
		      ada2p1 added
		      # gpart add -t freebsd-ufs -l disk3 ada2
		      ada2p2 added

Initialize Hard Drives for Encryption

Initialize the various non-swap partitions on the various hard drives for encryption (the "-b" parameter will make it ask for the password at boot time, thus enabling an encrypted root). Note 1: Do not encrypt the thumb drive; boot needs to be unencrypted. Note 2: Do not encrypt the swap drives; they will eventually wind up being encrypted, but this is not how to do it. Note 3: I suggest using the same password for all of them; this will make booting easier, as you'll only have to provide the password once, rather than once per drive.

		      # geli init -b -s 4096 ada0p1
		      Enter new passphrase:
		      Reenter new passphrase:
		      # geli init -b -s 4096 ada1p2
		      # geli init -b -s 4096 ada2p2

GELI Attach

Attach geli to the various non-swap partitions on the hard drive:

		      # geli attach ada0p1
		      Enter passphrase:
		      GEOM_ELI: Device ada0p1.eli created.
		      # geli attach ada1p2
		      # geli attach ada2p2

Note that this results in new devices becoming available: /dev/ada0p1.eli, /dev/ada1p2.eli, and /dev/ada2p2.eli. These are essentially the decrypted views of what's on the associated encrypted drives (/dev/ada0p1 and so forth). These (ada*.eli, as opposed to ada*) are what we'll be working with from now on.

Create File Systems

Create new file systems for the non-swap partitions on the hard drives and for the /boot partition on the thumb drive (note the ".eli" for the ones on the hard drive, since we're creating their filesystems within the encryption):

		      # newfs -U /dev/da0p2
		      /dev/da0p2: blah blah blah (...)
		      # newfs -U /dev/ada0p1.eli
		      # newfs -U /dev/ada1p2.eli
		      # newfs -U /dev/ada2p2.eli

Mount the /boot and root partitions, and do some linking for some reason:

		      # mount /dev/ada0p1.eli /mnt
		      # mkdir /mnt/unenc
		      # mount /dev/da0p2 /mnt/unenc
		      # mkdir /mnt/unenc/boot
		      # ln -s unenc/boot /mnt/boot

Create Preliminary fstab

Create fstab, adding entries for the root and the various swaps. Do not add entries for the boot drive (not needed) or for the non-swap portions of the other hard drives (we'll do them later). Note that the swaps should have ".eli" appended to their partition names - this apparently automatically causes FreeBSD to encrypt them via geli. Also note that you have to create fstab in /tmp/bsdinstall_etc, not in the normal location (/etc):

		      # vi /tmp/bsdinstall_etc/fstab

Edit it as such (for the current example):

		      /dev/ada0p1.eli /    ufs  rw 1 1
		      /dev/ada0p2.eli none swap sw 0 0
		      /dev/ada1p1.eli none swap sw 0 0
		      /dev/ada2p1.eli none swap sw 0 0

Create loader.conf

Edit loader.conf (again, in a certain wacky directory) to load geli and to tell it which partition to use to mount root:

		      # vi /tmp/bsdinstall_boot/loader.conf

Edit it to be:


Also take this opportunity to modify loader.conf in whatever other ways you may want (potentially unrelated to this whole disk encryption thing). For example, I want to enable Samba, so I add:


Resume Normal Installation and Reboot

Exit the shell:

		      # exit

The normal installation process should then resume. After it finishes, reboot (from the thumb drive; you can also try without the thumb drive to make sure it doesn't reboot). It should ask you for the password for the root partition (as you specified in geli init). However, the message asking you for it will probably be hidden in a bunch of random interspersed booting messages, and could be easy to miss. Also, at least on my machine, it seems to take a while before it actually accepts input, and it gives no indication as to when it becomes ready, so you may have to try multiple times to enter the password before it's actually accepted even if you enter it correctly.

Once it's booted up, you should be able to remove the thumb drive (no umount necessary).

We're not done with installation yet; there's a little more to set up.

Check Swap Is Encrypted

Do a swapinfo to make sure that the swap drives are ".eli" (i.e. they're encrypted using geli):

		      $ swapinfo
		      Device          1K-blocks     Used    Avail Capacity
		      /dev/ada0p2.eli   8388608        0  8388608     0%
		      /dev/ada1p1.eli   8388608        0  8388608     0%
		      /dev/ada2p1.eli   8388608        0  8388608     0%
		      Total            25165824        0 25165824     0%

Create Mount Points

Create mount points for the other drives:

		    	# mkdir /disk2
		    	# mkdir /disk3

Create Final fstab

Edit fstab (in the normal place this time) to mount them:

		      # vi /etc/fstab

Add in entries for the other disk's data partitions:

		      /dev/ada0p1.eli /      ufs  rw 1 1
		      /dev/ada0p2.eli none   swap sw 0 0
		      /dev/ada1p1.eli none   swap sw 0 0
		      /dev/ada1p2.eli /disk2 ufs  rw 2 2
		      /dev/ada2p1.eli none   swap sw 0 0
		      /dev/ada2p2.eli /disk3 ufs  rw 2 2

Mount them to make sure fstab is correct (rebooting is a hassle if not):

		      # mount /disk2
		      # mount /disk3
		      # df -g
		      Filesystem      1G-blocks Used Avail Capacity Mounted on
		      /dev/ada0p1.eli       894    0   822     0%   /
		      devfs                   0    0     0   100%   /dev
		      /dev/ada1p2.eli       894    0   822     0%   /disk2
		      /dev/ada2p2.eli       894    0   822     0%   /disk3


Reboot to make sure everything comes up as intended.