Tuesday, January 29, 2008

Busted!

I got busted by some rancher dude for launching and landing on a light wind day conducive to ridge soaring the ocean cliffs of west Maui.

Evidence:


Yeah, OK, technically I pirated the site, but I thought the launch was on semi-public easement land. When the wind increased in strength, I did need to land down in a pasture near the ocean, instead of toplanding. I was under the impression that this was OK as long as horses were not in the fields, which is what older pilots have said in the past. Apparently not.

Oh well. Despite the area having spectacular terrain to fly over, I expect this site to only work on a few days each year because of the normally very strong trade winds we get here on Maui. So, unless we get permission from land owners in the future, I'll save the ridge soaring for O'ahu...

Sunday, January 27, 2008

Installing FreeBSD with GELI encrypted root partition on a laptop

Recently I had several false-starts attempting to install FreeBSD 7.0RC1 with GELI disk encryption on a laptop such that everything but /boot is encrypted. Not finding any documents on teh Intarweb documenting in some canonical fashion a procedure to do this, I decided to write down the method I used that ultimately worked (well enough for my not-so-demanding standards)! Your mileage may vary...

Synopsis

Briefly, the procedure requires you to install a minimal FreeBSD distribution to an external disk, then set up the internal disk/partition with GELI disk encryption, and finish by copying the external disk data over to the encrypted internal disk / partition. A /b partition holding the /boot directory will be the only thing unencrypted on the FreeBSD portion of the laptop.

I am indebted to a few documents for snippets of procedures listed below. The Encrypting Disk Partitions document within the FreeBSD handbook is one, and the GELI manpage is another. In addition, the dump/restore data copy procedure is taken from an excellent document on setting up gmirror from Ralf Engelschall.

I realize that it would be more secure to have the key be on an external device (like a USB keyring). I also realize I could do more command-line editing (like using bsdlabel instead of sysinstall). Comments welcome!

Before you begin, you should make sure you have backed up your data or are starting with a fresh laptop with nothing on it. I am not responsible for lost data!

Requirements:
  • External hard drive. Mine is a Lacie USB 2.0 device, referred to below in commands as /dev/da0s1
  • Internal hard drive, (obviously!) Mine already has a partition with Windows XP and another with Linux, and the MBR is already setup with Linux GRUB to handle the multi-booting. The FreeBSD partition is /dev/ad4s3
  • FreeBSD CDs. I used 7.0RC1 #1 CD and the 7.0RC1 livefs CD
Part I - Installing minimal FreeBSD to the external HDD

This process requires that you first install the minimal distribution to an external hard drive. Boot the #1 CD, and begin the standard installation procedure (sysinstall).

Select the da0 device (external hard disk) to add the "fdisk" style partitions. I used option A to dedicate the entire external disk to FreeBSD, resulting in a partition of da0s1.

When prompted for MBR changes, choose None.

Continuing right along, now we get to choose FreeBSD slices. We will choose to create a partition scheme that will ultimately resemble:
512M  /b    da0s1a
IM swap da0s1b
JM / da0s1d
Where I is the amount of swap space (in Megs) you want--I chose 2048M--and J is the remaining space dedicated to the / partition.

Now, similar to something Microsoft could be accused of, sysinstall tries to be clever here, and we will need to do a bit of subterfuge to get our way. Sysinstall will automagically attempt to assign the / slice as sXa (instead of sXd). So when creating the slices, you will need to initially choose the 512Meg partition to be named / (instead of /b). Similarly you will initially need to name the / partition as something else, such as /foo

After slice creation, go back and select option M to change the mountpoints to the proper /b (da0s1a) and / (da0s1d). Whew. (For information WHY we need to do it this way, see the ASIDE after identically partitioning the internal disk below)...

OK, moving right along, after Qing out of that step, you will be in the distribution set selection phase. For now, choose the Minimal option. Select OK and then chooes your installation media (CD/DVD).
Last Chance! Are you SURE you want to continue the installation?

If you're running this on a disk with data you wish to save then WE STRONGLY ENCOURAGE YOU TO MAKE PROPER BACKUPS before proceeding!

We can take no responsibility for lost disk contents!
Now you watch and wait until the installation finishes on your external drive. After it completes, you can run through the various post-installation configuration options as you desire. I don't set up Linux binary compatibility at this point nor browse the package collection merely to save a little bit of time. You can always do these after completely installing FreeBSD on your encrypted internal hard disk.

OK after minimal post-installation configuration, go ahead and exit the installation, and reboot with the livefs CD.

Part II - Preparing the internal encrypted disk

At the sysinstall main menu, choose a Custom installation. Select the Partition option, on the internal hard disk (/dev/ad4 in my case). Make sure you don't change any of the existing partitions for the other operating systems (if you have them). Make sure the partition dedicated to FreeBSD is set to the FreeBSD type (using option T if needed). If you made any changes, you will need to use the W option to write the changes out. When prompted for a boot loader on the MBR, I choose None because I already have GRUB set up to do it.

Next, from the Custom installation menu, choose the Label option. It should automatically choose the internal harddisk for you since you selected it in the previous Partition phase. Here you will need to create the exact same slices as you did on your external HDD. Don't worry if the size of the / slice is different, but /b and swap should be the same. You will hafta jump through the same naming hoops as before. Ultimately you should end up with a slices like so:
512M   /b    ad4s3a
IM swap ad4s3b
JM / ad4s3d
ASIDE: The reason for having / be on a later slice (sXd) instead of the first one (sXa) is because the FreeBSD boot procedure by default will always attempt to load the /boot/loader from the first (sXa) slice of the dedicated FreeBSD partition. Also, / will be encrypted, and so will not be initially readable. If / was on sXa, then you would see a "No UFS" error when attempting to boot.
After completing the slices, select the W option to write out your changes. Then Q to return to the Custom menu. Exit this menu, then exit the installation, rebooting the livefs CD (why? because I'm not sure how to unmount the internal harddrive at this point, and I need it unmounted :-)

Part III - Encrypting and installing the internal hard disk

At the loader prompt on the livefs CD, hit option 6 to drop to the loader console. Load the geom_eli module and boot
load geom_eli
boot
At the main menu choose the Fixit option and choose to use the "live" filesystem CDROM/DVD.

Scramble the data on your FreeBSD swap and / slices:
dd if=/dev/random of=/dev/ad4s3b
dd if=/dev/random of=/dev/ad4s3d
Populate the /b slice on the external harddrive:
mkdir /tmp/m
mount /dev/da0s1d /tmp/m
mount /dev/da0s1a /tmp/m/b
cd /tmp/m
cp -Rp boot b
rm -rf boot
ln -s b/boot
cd /
umount /tmp/m/b
umount /tmp/m
Copy the /b slice from the external hard disk to the internal one
mount /dev/ad4s3a /tmp/m
dump -0 -f- /dev/da0s1a | (cd /tmp/m && restore -r -v -f-)
rm /tmp/m/restoresymtable
Begin GELI initialization of internal hard disk / partition. I choose Blowfish encryption, and select a good password:
dd if=/dev/random of=/tmp/m/boot/ad4s3d.key bs=64 count=1
chmod 600 /tmp/m/boot/ad4s3d.key
geli init -b -e Blowfish -s 4096 -K /tmp/m/boot/ad4s3d.key /dev/ad4s3d
geli attach -k /tmp/m/boot/ad4s3d.key /dev/ad4s3d
newfs /dev/ad4s3d.eli
Copy / from the external to the internal drive and mount /b in its proper location:
umount /tmp/m
mount /dev/ad4s3d.eli /tmp/m
dump -0 -f- /dev/da0s1d | (cd /tmp/m && restore -r -v -f-)
rm /tmp/m/restoresymtable
mount /dev/ad4s3a /tmp/m/b
Now we need to do some configuration. In particular, you will need to edit /tmp/m/etc/fstab to change the old da0s1 entries to resemble the following:
# Device          Mountpoint    FStype  Options     Dump    Pass#
/dev/ad4s3a /b ufs rw 2 2
/dev/ad4s3b.eli none swap sw 0 0
/dev/ad4s3d.eli / ufs rw 1 1
You will also need to edit /tmp/m/b/boot/loader.conf to resemble something like this:
geom_eli_load="YES"
geli_ad4s3d_keyfile0_load="YES"
geli_ad4s3d_keyfile0_type="ad4s3d:geli_keyfile0"
geli_ad4s3d_keyfile0_name="/boot/ad4s3d.key"
vfs.root.mountfrom="ufs:/dev/ad4s3d.eli"
I find that now is a good time for performing other configuration of files in /etc, like rc.conf, sysctl.conf, syslog.conf, periodic.conf, etc, before the first boot. Go ahead and do that, I'll wait...

OK, now you can quit the livefs shell, and exit the installation, remove the livefs CD and attempt to reboot into your FreeBSD partition. If all goes well, everything should run smoothly. Hopefully you haven't forgotten your GELI password...

Part IV - Troubleshooting

Q. Initial boot complains about "No UFS".
A. It is trying to access the sXa slice which is either encrypted or doesn't actually have a UFS filesystem (did you forget to put the / partition on sXd? Did you forget to do a newfs?)

Q. The GELI password doesn't work.
A. Did you type it in correctly? Did you save the key file to the /b/boot/keyfile ?

Q. I'm never prompted for the password on boot.
A. Did you forget the geom_eli_load="YES" in the loader.conf?

Q. The loader works, and the kernel boots, the password takes, and it all works until it can't find the root filesystem.
A. You can type ? to see a list of potential root devices. Try specify something like ufs:/dev/adXsYd.eli and then you will need to fix the vfs.root.mountfrom variable in your loader.conf to the one that works.