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.
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.
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.
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.
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
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 the bootcode to partition 1 on the USB drive:
# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 da0 bootcode written to da0
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 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 (...)
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 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 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
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:
Exit the shell:
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.
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 for the other drives:
# mkdir /disk2 # mkdir /disk3
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.