23 May 2009

Encrypted FreeBSD 7.2 (and 8.0) system using geli

A BIT OF HISTORY AND CAUTION
==========================


Caution
As of FreeBSD 8.0 "dangerously dedicated" mode has been removed. What does this mean for setups like this? I don't know... seriously. There is a large discussion about this on the FreeBSD mailing lists so I suggest you educate yourself there and decide if this is really what you want to do. You have been cautioned.

Update 2010
This updated guide was originally written in 2009 for FreeBSD 7.2, but now being 2010 and with FreeBSD 8.0 being released I thought I'd touch it up again (Couldn't wait for 8.2). The process is pretty much the same. Any differences are slight and will be pointed out. Keep in mind that the links pointing to the manpages are for the FreeBSD 7.2-RELEASE manuals.

This guide explains how to install an encrypted system using geli (8), with an unencrypted /boot parition placed on a usb-stick, which will also contain a keyfile that, aswell as a password, is required to boot into the system. Additionally a bootable CD can be used which is covered in the previous 6.2 guide (If it still works... That section hasn't been touched for almost 3 years!).

One final note: This is WAY too much effort if you ask me...

SETUP
======

FreeBSD installation DVD (which contains the live fs)
A system/drive to install FreeBSD onto /dev/ad0
A usb-stick /dev/da0

Make sure not to confuse /dev/ad0 with /dev/da0 like I've done in the past!

Boot from the FreeBSD install dvd. At the install screen choose the Fixit option, and select:

Use the "live" filesystem CDROM/DVD

You will see something like:

blah blah blah
more blah blah
even more blah
...
Good Luck!

Fixit#


PREPARING THE DRIVES
====================

Sanitising
This step is optional, as the sanitation process can literally take days depending on how large the drive is. The disk will be wiped with random data to make previous data difficult to recover. I personally prefer to use dban and leave it running overnight, or you could go the BSD route. You can also sanitise the usb-stick here too if you want.

# dd if=/dev/random of=/dev/ad0 bs=1M

Later on when you edit files you'll be presented with vi (8), an extremely powerful editor. Otherwise, for something more user friendly you can use ee (8).

# setenv EDITOR=ee

Creating and editing the partitions on the usb-stick:
Now fdisk (8) and bsdlabel (8) will be used to setup the bootable usb-stick.

# fdisk -BI /dev/da0
# bsdlabel -Bw /dev/da0s1
# bsdlabel -e /dev/da0s1

You will see something like the following:
> # /dev/da0s1
> 8 partitions:
> # size offset fstype [fsize bsize bps/cpg]
> a: 1001936 16 unused 0 0
> c: 1234567 0 unused 0 0 # "raw" part, don't edit
In the a: entry, used for our root partition, change "unused" to "4.2BSD"
> #     size   offset   fstype     [fsize bsize bps/cpg]
> a: 1001936 16 4.2BSD 0 0
Creating the filesystem and keyfile
We are now going to construct a filesystem on the usb-stick using newfs (8), then we will mount (8) it, then using dd (1) we are going to create a 256KB keyfile filled with random data.
# newfs /dev/da0s1a
# mkdir /usb && mount /dev/da0s1a /usb
# dd if=/dev/random of=/usb/ad0.key bs=256K count=1
They keyfile can be any length you want it to be.

MOULDING THE SYSTEM WITH GELI
=============================

Get it? No? Nevermind...

Geli isn't enabled by default with the livefs. So we'll have to create a couple symlinks with ln (1), then load the geom_eli module with kldload (8).

# ln -s /dist/boot/kernel /boot/kernel
# ln -s /dist/lib /lib
# kldload geom_eli

Initialising the drive [8.0 Users note below]
Now we are going to initialise the system drive /dev/ad0 with geli (8).The default encryption algorithm is AES, which was designed to only accept key sizes of 128, 192 or 256 bit. You try and set another keylength and you'll get an error at this stage.

Note the uppercase and lowercase letter k's
# geli init -b -l 256 -s 4096 -K /usb/ad0.key /dev/ad0
Enter new passphrase:
Reenter new passphrase:
# geli attach -k /usb/ad0.key /dev/ad0
Enter passphrase:
On FreeBSD 8.0, geli (8) now contains the "-B" (UPPERCASE) flag to backup the metadata stored in /var/backups/ by default. Therefore you first have to create a /var/backups directory or define where you want the backup to go, if you want one at all, otherwise you'll get a lovely error message.

Creating and editing the partitions and filesystems on the system drive
Now we are going to prepare the system drive as we did the usb-stick
# bsdlabel -w /dev/ad0.eli
# bsdlabel -e /dev/ad0.eli
Like before you'll see something like the following:
> # /dev/ad0s1
> 8 partitions:
> # size offset fstype [fsize bsize bps/cpg]
> a: 1001936 16 unused 0 0
> c: 1234567 0 unused 0 0 # "raw" part, don't edit
I like to add other partitions such as /home, /var, /tmp and /usr so that my partition layout looks something like the following mess:
> # /dev/ad0s1
> 8 partitions:
> # size offset fstype [fsize bsize bps/cpg]
> a: 300M 16 4.2BSD 0 0 # /
> b: 512M * swap
> c: 1234567 0 unused 0 0 # "raw" part, don't edit
> d: 512M * 4.2BSD # /home
> e: 512M * 4.2BSD # /tmp
> f: 2046M * 4.2BSD # /var
> g: * * 4.2BSD # /usr
There's no need to enter in values for fsize, bsize and bps/cpg as they're filled in automatically when you write the partition layout. # bsdlabel -e /dev/ad0.eli again to see what I mean. I wouldn't change the default values anyway as the newfs (8) manpage explains. (And if you can actually understand the explanation then you're a smarter person than I am).

Also, instead of M for Megabytes in the size column you can use G for Gigabytes. What the asterisks * in the offset column do is to tell newfs (8) to automagically determine the offset, where the partition should begin, based on where the previous partition ended. NICE!

Now construct the filesystems:
# newfs /dev/ad0.elia
# newfs /dev/ad0.elid
etc...
Mount, mount, and more mount
Now we are going to create mountpoints for the partitions and re-mount the usb-stick. The reason being, is that later on we are going to create a chroot (8) at /tmp/fixed, and we want the usb-stick accessible within the chroot.
# mkdir /tmp/fixed && cd/tmp/fixed
# mount /dev/ad0.elia .
# mkdir home tmp var usr usb
# mount /dev/ad0.elid home
# mount /dev/ad0.elie tmp
# mount /dev/ad0.elif var
# mount /dev/ad0.elig usr
# umount /usb && mount /dev/da0s1a /tmp/fixed/usb
Installing base and the kernel
Now we are going to actually install something... Can I get a "YAY!" But first we need to setup some variables so that things are installed to the right places.

# export DESTDIR=/tmp/fixed

I prefer to only install base and build a custom kernel. If it all works properly I can just install whatever I want later via sysinstall (8). Obviously for 8.0 users change the numbers accordingly.
# cd /dist/7.2-RELEASE
# cd base && ./install.sh

You are about to extract the base distribution into /tmp/fixed - are you SURE you want to do this over your installed system (y/n)? y

# cd ../src && ./install.sh sys base

Sources for sys and base were installed so that a custom kernel could be compiled. Should you want the GENERIC kernel instead, forget about installing the sources and skip the "Configuring/Compiling the kernel" sections and just install the GENERIC kernel:

# cd /dist/7.2-RELEASE/kernels && ./install.sh GENERIC

[ NOTE: The original reason given for configuring and compiling a custom kernel was that in the 6.2-RELEASE kbdmux (8) would interfere when trying to enter in the passphrase for geli at boot. Whether or not the original problem still exists is unknown, but now its just something I like to do.

Either way, as it states in the handbook, "If you do not plan to use more than one keyboard on the system, you can safely remove that line" from the GENERIC kernel.]

Kernel configuration
We need a devfs in the chroot to enable us to compile everything. Then we're going to chroot /tmp/fixed, edit a custom kernel and compile away.
# mount -t devfs devfs /tmp/fixed/dev
# chroot /tmp/fixed
Perform a # pwd and you'll see that you're at the root directory, which is really /tmp/fixed
# cd /usr/src/sys/i386/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/CUSTOM
# ln -s /root/kernels/CUSTOM
# vi CUSTOM
Check out the handbook if you never compiled a kernel before, in particular sections 8.5 and 8.6. One thing to note, I always include the following in my custom kernel config file, for inbuilt support for GELI devices:
options GEOM_ELI
device crypto
Compiling the kernel
# export MAKEOBJDIRPREFIX=/usr/obj2 && export DESTDIR=/
# cd /usr/src
# make buildkernel KERNCONF=CUSTOM
# make installkernel KERNCONF=CUSTOM

THE FINAL STAGES
===============

Boot to boot
Now /boot is to be copied to the usb-stick. There's a couple ways of doing this, the convoluted and complicated method (my personal favourite) or the simple method that just takes a little longer to process. Then the fstab (5) files will be configured. Firstly, I like to gzip (1) the kernel as this helps speed up boot time and decreases the file size to copy over.

# cd /boot/kernel && gzip kernel

[ convoluted method 1 ]
If you configured and compiled a kernel and built in support for geom_eli, then you don't need to copy over the geom_eli.ko module, otherwise copy over geom_eli.ko aswell. On my simple system all I needed was the kernel, though YMMV.
[WATCH YOUR SPACING]
# mkdir /usb/boot
NB: I split this command up into two lines as it wasn't completely
showing the whole command otherwise

# (cd /boot && tar --exclude "kernel*" -cf - .) | \
(cd /usb/boot && tar -xf -)
# cd /boot/kernel && mkdir /usb/boot/kernel
# cp geom_eli.ko kernel.gz /usb/boot/kernel
The above uses tar (8) to create an archive of the /boot directory, excluding the kernel directories (kernel and kernel.old) and extracts the contents to the /usb/boot directory. Then you just copy over the required files needed for boot to /usb/boot. All in all, roughly 3MB in total copied over.

[ easy method 2 ]
This method takes longer to process as all the kernel modules are copied over, which on my system totalled more than 100MB

# cp -Rpv /boot /usb

Usb configuration files
Given up yet?

Now for the last part of the last stretch. Configuring the config files.
The geom_eli_load="YES" line may be omitted if you enabled GEOM_ELI support in the CUSTOM kernel, assuming you made one.

# vi /usb/boot/loader.conf
> geom_eli_load="YES"
> geli_ad0_keyfile0_load="YES"
> geli_ad0_keyfile0_type="ad0:geli_keyfile0"
> geli_ad0_keyfile0_name="/ad0.key"

Now for the fstab (5) files. First we need to create an etc/fstab on the usb stick to mount the root partition.

# mkdir /usb/etc && \
echo "/dev/ad0.elia / ufs rw 1 1" >> /usb/etc/fstab

Now we create an etc/fstab on the system-drive, so that once the root partition is loaded the rest of the partitions can be loaded.
# vi /etc/fstab
> # Device Mountpoint FStype Options Dump Pass#
> /dev/ad0.elib none swap sw 0 0
> /dev/ad0.elid /home ufs rw 2 2
> /dev/ad0.elie /tmp ufs rw 2 2
> /dev/ad0.elif /var ufs rw 2 2
> /dev/ad0.elig /usr ufs rw 2 2
And that should be it. If you want to create a bootable cd then have a look at my previous guide. Note that mkisofs isn't included in the base system so you'll need access to another BSD system.

************************
EXTREMELY IMPORTANT
************************

Before you reboot, you MUST unmount everything! So exit the chroot, umount (8) your mounted partitions, and detach the geli (8) device.

# exit
# cd /tmp/fixed
# umount dev home tmp var usr usb
# cd .. && umount fixed
# geli detach /dev/ad0

Now you can reboot. When you reboot into your wonderful newly encrypted system, you can use sysinstall (8) to install other packages and configure your gear. So, happy hunting.

NOTE: When you do finally boot into your system, you may see the normal boot process scroll by and then all of a sudden it'll seem to have stopped when its detected the usb stick (da0). You may be wondering where the password prompt to attach the geli device is... most likely its about 10 or so lines up... yeah, its confusing. But it'll still work.

References
==========

FreeBSD forums
http://forums.freebsd.org/archive/index.php/t-434.html

"Complete Hard Disk Encryption with FreeBSD" - Marc Schiesser
22nd Chaos Communication Congress, 29 December 2005

FreeBSD-Geom Mailing List Archives
http://lists.freebsd.org/pipermail/freebsd-geom/

bootable FreeBSD on USB-Flash-Drive [Solution]
http://lists.freebsd.org/pipermail/freebsd-questions/2006-March/117738.html

FreeBSD Handbook, Chapter 18.6 - Creating and Using Optical Media(CDs)
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/creating-cds.html

FreeBSD Handbook, Configuring the FreeBSD Kernel
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html

Marc Fritsche, marc [at] proportion [dot] ch
http://www.proportion.ch/index.php?page=31

And a few people on #freebsd on irc.freenode.net. Sorry, can't remember your names...

09 September 2007

Creating a Full Disk Encryption system with FreeBSD 6. 2

These are the actual steps I took to create a full disk encryption system with FreeBSD 6.2. As it was a great personal exercise in patience and sanity, I hope that this guide will help others save a few more hair strings.

In this guide I will be creating a system that uses a keyfile filled with random data, that also prompts for a passphrase during boot. The /boot partition needs to remain unencrypted so it will be placed on either a usb pendrive or a bootable cd-rom.

The target audience for this guide is a beginner(ie myself) to intermediate user of FreeBSD. But I think even a seasoned veteran may find something useful in here.

WARNING!! BACKUP ANY IMPORTANT DATA BEFORE YOU PROCEED!!

MY SETUP
========

Two computers
- comp_A : which will have its hard drive (/dev/ad0) sanitised then encrypted, which has two physical cd-rom drives attached. One drive used to boot the FreeSBIE cd, the other to copy the 6.2-RELEASE files.
-comp_B : with an existing FreeBSD system.

- live cd (freesbie.org), comp_A
- disc1 of the FreeBSD 6.2 RELEASE installation CDs, comp_A
- USB pendrive

- A working internet connection to obtain all the sources, or a copy of an up to date /usr/src tree

METHOD
=======


Preparing the system

Boot with the freesbie cd, then su to root.

# su root

Sanitise hard drive (/dev/ad0) that we'll later encrypt.

# dd if=/dev/random of=/dev/ad0

Create a keyfile (ad0.key) filled with 64bytes of random data. Then initialise the disk with geli(8) with a keylength of 256 bits (default is AES, 128bit).
-b; prompts us for the passphrase at boot
-l ; sets the key length of the cryptographic algorithm
-s ; sets the sector size to 4096
-K; uppercase K, path to save the keyfile data

# dd if=/dev/random of=/tmp/ad0.key0 bs=64 count=1
# geli init -b -l 256 -s 4096 -K /tmp/ad0.key0 /dev/ad0
> Enter new passphrase:
> Reenter new passphrase:


!!COPY THIS KEYFILE STRAIGHT AWAY TO SOME PLACE SAFE!! eg a backup usb pendrive. If you lose the keyfile, you will be unable to decrypt your geli drive.

Attach the encrypted device. Notice the lowercase k

#geli attach -k /path-to/ad0.key0 /dev/ado
> Enter passphrase:
> GEOM_ELI: Device ad0.eli created.
> GEOM_ELI: Encryption: AES-CBC 256
> GEOM_ELI: Crypto: software

From now on we will be working with /dev/ad0.eli, not /dev/ad0.
Write and Edit the disk label for our encrypted device.

Note: The default editor is set to vi. If you're not familiar with vi a simple Google Search will bring up some basic tutorials. If you'd rather use another editor, such as ee;

# setenv EDITOR ee

will bring up ee whenever a command brings up something for you to edit.

# bsdlabel -w /dev/ad0.eli
# bsdlabel -e /dev/ad0.eli

You will then be presented with something similar to:

> #/dev/ad0:
> 8 partitions:
> #     size   offset   fstype   [fsize bsize bps/cpg]
> a: 1001936        2    unused       0    0     0
> c: 1001952        0    unused       0    0     0 # "raw" part, don't edit

In the a: entry, used for our root partition, change "unused" to "4.2BSD"

> #     size   offset   fstype   [fsize bsize bps/cpg]
> a: 1001936        2    4.2BSD       0    0     0


In my setup I also created swap, /home, /tmp, /var, and /usr partitions.

> #/dev/ad0:
> 8 partitions:
> #     size   offset   fstype   [fsize bsize bps/cpg]
> a: 1001936        2    4.2BSD       0    0     0
> b:   1024M        *      swap
> c: 1001952        0    unused       0    0     0 # "raw" part, don't edit
> d:    500M        *    4.2BSD       0    0     0 # /home
> e:    500M        *    4.2BSD       0    0     0 # /tmp
> f:   2046M        *    4.2BSD       0    0     0 # /var
> g:       *        *    4.2BSD       0    0     0 # /usr


In all honesty, you can leave [fsize bsize bps/cpg] blank. newfs(8) and bsdlabel(8) will figure out the correct values for you.

Each line takes 6-7 values.
- #; the partition entry, a-g in my case. DO NOT touch the c: partition entry as that applies to the whole disk.
- size; number followed by K, M or G for Kilo, Mega or Gigabytes.
- offset; the asterisk * lets newfs(8) figure out the offset automagically, otherwise it is the sector value of the end of the previous partition, plus one (ignoring c:)
- fstype; file system type, in our case 4.2BSD with "swap" for the swap partition.
- [fsize]; fragment size, set to zero to let newfs(8) sort it out.
- [bsize]; block size, set to zero to let newfs(8) sort it out
- [bps/cpg]; beats the hell out of me... set to zero to let newfs(8) sort it out.

Check the bsdlabel(8) and newfs(8) manpages if you want more info. The asterisk under the size column in the g: partition entry tells newfs to set the size of the partition to whatever space is left over.

Then save and quit.

Now we are going to create the file system on our partition. Repeat for other partitions created.

# newfs /dev/ad0.elia
# newfs /dev/ad0.elid

etc..

Note .eli[a,d-g] as we are creating filesystems on those partitions. No filesystem will be created for the swap partiton.

Now mount the 6.2-RELEASE.disc1 CD, from which the base installation and manpages will be copied. The reason I didn't boot with 6.2-RELEASE.disc1 CD is because GELI wouldn't allow me to attach a device.

# mkdir /tmp/cdrom
# mount_cd9660 /dev/iso9660/FreeBSD_Install /tmp/cdrom

Now we are going to work with the encrypted drive. The root partition will be mounted under /tmp/fixed

# mkdir /tmp/fixed
# mount /dev/ad0.elia /tmp/fixed

We will also mount the other partitions, so we need to create directories for their mount points too.

# cd /tmp/fixed
# mkdir home tmp var usr
# mount /dev/ad0.elid home
# mount /dev/ad0.elie tmp
# mount /dev/ad0.elif var
# mount /dev/ad0.elig usr

Installing the base system

Now we are going to install the base system. I also like to install the manpages and catpages.

# sentenv DESTDIR /tmp/fixed
# cd /tmp/cdrom/6.2-RELEASE/base && ./install.sh
# cd ../manpages && ./install.sh
# cd ../catpages && ./install.sh

Repeat for other distributions you choose to install.

Alternatively, you can drop to an sh(8) shell and run a for-loop to do the same

# /bin/sh
# export DESTDIR=/tmp/fixed
# cd /tmp/cdrom/6.2-RELEASE
# for i in base manpages catpages
# do
# cd $i; ./install.sh; cd..;
# done

Installing an up to date source tree

We are now going to create a usr/src tree.

Note: The following requires an internet connection, so hopefully you're behind a nicely configured firewall. Though if you aren't, the only service listening [#sockstat -46l] on the FreeSBIE live-cd is syslog so in all honesty you should be fine.

In my setup I used csup but it may be possible to use another copy of an up to date src tree if available.

[It may be possible to do the following in a chroot, though I haven't tried it]

Copy the stable-supfile to /root on the encrypted drive.

# cp /usr/share/examples/cvsup/stable-supfile /tmp/fixed/root/

Edit the stable-supfile and change a few lines to reflect the following

> *default host=CVSUP-SERVER-NEAREST-TO-YOU.FreeBSD.org
> *default base=/tmp/fixed/var/db
> *default prefix=/tmp/fixed/usr
> *default tag=RELENG_6_2

Now before you can run csup you need to make sure that a sup directory exists in var/db/sup

# mkdir /tmp/fixed/var/db/sup
# csup -L2 stable-supfile

Your usr/src directory should now be populated with an up to date source tree. Note: if you plan to use that supfile again after successfully setting your system up, remove the /tmp/fixed prefix from the base= and prefix= lines.

[I would like to know if the following works or not:
#cd /path-to/6.2-RELEASE/src && cat s*.?? | tar -zxvf - -C /usr/src/
I honestly don't know..]

Configuring, Building and Installing a Kernel

The /dev filesystem needs to be mounted as that will be needed to compile the kernel.

# mount_devfs devfs /tmp/fixed/devfs

From now on we will work in a chroot as that will be alot easier.

# chroot /tmp/fixed

Create a copy of the GENERIC kernel. Of course you can replace CUSTOM with whatever you decide to name your new kernel. What the following does is create a copy of GENERIC called CUSTOM placed in /root/kernels/, then creates a symbolic link from /usr/src/sys/i386/conf/CUSTOM -> /root/kernels/CUSTOM

# cd /usr/src/sys/i386/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/CUSTOM
# ln -s /root/kernels/CUSTOM

If you've never installed a custom kernel before, I suggest reading the FreeBSD handbook, especially the chapters on Kernel Configuration and Building and Installing a Custom Kernel.

If you know the system that you are installing to well enough, then you can edit your own customisations here also.

# vi CUSTOM

Two things to note:
- Change the ident value to the name of your new kernel
- Remove the "device kbdmux" line

Set up a couple of environment variables, then build and install the kernel.

# setenv MAKEOBJDIRPREFIX /usr/obj2 && setenv DESTDIR /
# cd /usr/src
# make buildkernel KERNCONF=CUSTOM
# make installkernel KERNCONF=CUSTOM

Check to see if (/tmp/fixed)/boot/kernel is populated. If all goes well, you've just installed yourself a functional FreeBSD 6.2 system, albeit with no way of booting into it yet as the drive is encrypted.
NOTE
From the handbook: "By default, when you build a custom kernel, all kernel modules will be rebuilt as well. If you want to update a kernel faster or to build only custom modules, you should edit /etc/make.conf before starting to build the kernel."
[This is why we populated the usr/src tree]

Preparing the boot media

An unencrypted /boot partition is necessary to load the geli module during startup so that it can decrypt the encrypted geli drive. If you haven't done so by now, exit out of the chroot(8). We will be placing /boot on either a bootable usb pendrive or a bootable cd-rom drive, either works fine.

First we will go through the steps to create a bootable usb pendrive. Following silimar steps done with the encrypted drive, we will create slice table and edit the partition table on the usb pendrive (/dev/da0).

!! BE CAREFUL NOT TO CONFUSE /dev/ad0 WITH /dev/da0 AS I HAVE DONE A COUPLE OF TIMES. YOU HAVE BEEN WARNED !!


# fdisk -BI /dev/da0
# bsdlabel -B -w /dev/da0s1
# bsdlabel -e /dev/da0s1

Similar to the encrypted drive, you will be presented with something similar to the following:

> #/dev/da0s1:
> 8 partitions:
> #     size   offset   fstype   [fsize bsize bps/cpg]
> a: 1001936        2    unused       0    0     0
> c: 1001952        0    unused       0    0     0 # "raw" part, don't edit

Change "unused" to "4.2BSD" in the a: partition entry.

> #     size   offset   fstype   [fsize bsize bps/cpg]
> a: 1001936        2    4.2BSD       0    0     0

Create a new file system on the drive.

# newfs /dev/da0s1

Mount the usb pendrive.

# mkdir /tmp/usb
# mount /dev/da0s1a /tmp/usb

Copy the encrypted /boot partition to the usb pendrive

# cp -Rpv /tmp/fixed/boot /tmp/usb

Copy the keyfile we created earlier (/tmp/ad0.key) to the usb pendrive.

# mkdir /tmp/usb/boot/keys
# cp /tmp/ad0.key0 /tmp/usb/boot/keys/

If you compiled GEOM_ELI support into the kernel, you needn't enter the geom_eli_load="YES" line. Otherwise, the following is what should be in boot/loader.conf so that the GEOM_ELI module and the keyfile are loaded during boot.

> geom_eli_load="YES"
> geli_ad0_keyfile0_load="YES"
> geli_ad0_keyfile0_type="da0:geli_keyfile0"
> geli_ad0_keyfile0_name="/boot/keys/ad0.key0"

We will now create a etc/fstab file so that geli knows where to mount the root partition.

# cd /tmp/usb
# mkdir etc && cd etc
# echo "/dev/ad0.elia / ufs rw 1 1" >> fstab

We will also need to create a etc/fstab on the encrypted drive so that the other partitions are mounted at boot also. I like to do it this way as it leaves less information unencrypted.

# vi /tmp/fixed/etc/fstab
> # Device        Mountpoint FStype Options Dump Pass#
> /dev/ad0.elib   none       swap   sw      0    0
> /dev/ad0.elid   /home      ufs    rw      2    2
> /dev/ad0.elie   /tmp       ufs    rw      2    2
> /dev/ad0.elif   /var       ufs    rw      2    2
> /dev/ad0.elig   /usr       ufs    rw      2    2

If your system supports booting from USB pendrives, then you should be able reboot and test it out.

IMPORTANT - BEFORE YOU REBOOT:
- unmount all the partitions and filesystems mounted
# cd /tmp/fixed && umount home var tmp usr devfs
# cd .. && umount /tmp/fixed
# umount /tmp/usb
# geli detach /dev/ad0

- Remove both the FreeSBIE cd and the 6.2-RELEASE discs
- Check to see in the BIOS that the usb pendrive is the first boot device

If all goes well.. CONGRATULATIONS!

Steps to creating a bootable CD

If your system doesn't support booting from a usb pendrive, then you will need access to another FreeBSD system in which you can mount the usb pendrive.

I used mkisofs(8) to create an iso image containing the contents of the usb pendrive.

# mount /dev/da0s1a /mnt && cd /mnt
# mkisofs -R -no-emul-boot -b boot/cdboot -o bootable.iso .

- R; use the Rock Ridge protocol to enable extended file names
- no-emul-boot; necessary as image is not of a floppy image
- b; boot image to use. [Afaik, this refers to /boot/cdboot]
- o; /path-to/output_file.iso
- .; last argument refers to directory to make iso image of

The full path to the new iso image should be /mnt/bootable.iso

I used cdrecord(8), part of the cdrtools package to burn the iso to a cd.

# cdrecord dev=X,X,X /tmp/usb/bootable.iso

To find the values of X,X,X run `cdrecord -scanbus` and scroll down the list to find the values of your CD recorder/burner.

Alternatively, you may be able to take the iso and burn it under another OS if that is easier for your situation.

And that... hopefully, should be it. Dont forget to unmount and detach your geli drive before you restart, otherwise you'll get errors about a dirty dismount.

Additional:
===========
To check if your iso image turned out correctly, mount and check contents:

# mdconfig -a -t vnode -f bootable.iso
> md%
# mount_cd9660 /dev/md% /cdrom

In Closing
==========
Personally, I ended up burning and throwing away about 7 cds before I got my setup right. Hopefully you won't have as many problems as I did, and on that note, I'll leave the rest of the system configuration up to you.

Criticisms, corrections (I'm sure there's plenty) and/or comments are welcome.
t41pad [at] gmail [dot] com

References
==========

"Complete Hard Disk Encryption with FreeBSD" - Marc Schiesser
22nd Chaos Communication Congress, 29 December 2005

FreeBSD-Geom Mailing List Archives
http://lists.freebsd.org/pipermail/freebsd-geom/

bootable FreeBSD on USB-Flash-Drive [Solution]
http://lists.freebsd.org/pipermail/freebsd-questions/2006-March/117738.html

FreeBSD Handbook, Chapter 18.6 - Creating and Using Optical Media(CDs)
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/creating-cds.html

FreeBSD Handbook, Chapter 8.3 - Building and Installing a Custom Kernel
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-building.html

Marc Fritsche, marc [at] proportion [dot] ch
http://www.proportion.ch/index.php?page=31

And a few people on #freebsd on irc.freenode.net. Sorry, can't remember your names...