HOWTO: GELI+ZFS for whole system inc. root with boot from USB stick
I got interested in this setup the other day and I'll try to explain how I did it so that others can try it out and give feedback. Most of this is probably already known and tested but I couldn't find any complete howto for the whole process. You setup and install everything from the FreeBSD install disk, no need for a second harddrive, temporary partitions or anything like that. Everything you need is one or more internal hard drives, an install CD/DVD and a USB stick for booting.
Before trying this method make sure your box and bios is able to boot from a USB stick. Also make sure that the USB stick you have is bootable. Mine worked at first try so I don't really know of any good way to test this.
In the end my box the system will have:
* All internal hard drives will be encrypted with GELI and ZFS will be used for everything, including / (root) running on top of GELI.
* All internal hard drives will be completely encrypted with GELI, no need for an unencrypted /boot/ since we use a USB stick for boot and GELI keys.
* Swap will be encrypted with GELI with one time key.
* On boot the system will load kernel and modules from the USB stick and you'll be asked for passphrases to the GELI disks before the system will run.
* It's only possible to boot from the USB stick, unencrypted of course, containing /boot/. The GELI encryption keys and a loader.conf for the boot loader will be placed at the stick. The USB stick is only needed at boot time, when the system has booted up you can safely remove this and store it in a secure location and nothing on the system will be bootable or accessible without this stick and your passphrases.
The method I describe can be used in different setups and configurations. This is just how I setup my box. Instead of a raid0 you could setup ZFS in mirror or raid5 or whatever you want your setup to be.
My setup consists of:
Installation and setup
The steps:
1. Boot install disk and drop to Fixit shell
2. Setup the Fixit shell
3. Setup partitions/slices on the internal disks
4. Setup GELI on the disks.
5. Create the ZFS pool
6. Mount ZFS in the right place
7. Back in sysinstall change install location and do a custom Distribution install
8. Back to Fixit shell and setup the USB stick and some config files.
9. Reboot and done
First off download and boot the system with a FreeBSD install disk. I used the FreeBSD 7.1 DVD but I think that the CD disk1 will work too.
At the install menu the first thing you'll do is to drop to the Fixit shell. Most of the work will be done there. You'll find it at the main menu of sysinstall. Choose option number 2 with livefs from CD/DVD.
Before starting out make sure you've backed up all your disks. Everything on the disks will be wiped.
You can do almost everything from the Fixit shell but it needs some setting up in order to do what we want. A few symlinks is needed in order to load modules and to use some applications.
Setup network (this is not necessary but it's much easier to just scp in the config files than to edit them live from the Fixit shell).
I use a local dhcp server to get networking set up but you could probably do this just as fine manually with ifconfig etc.
Create /var/db/ wich is needed for dhclient to run. Then run dhclient on your interface.
If you want to be able to use scp to copy in configs and backup keyfiles you also need to create a symlink for ssh.
Now we need to load the GELI and ZFS module. In order to do this we need some symlinks from the CD/DVD.
This step is optional but it's always a good idea to clean out all the old stuff from the disks. For security, easy of mind etc.
Here I write random data to all my internal disks and to the USB stick.
This step is optional too but it makes the fixit shell a lot easier to work with.
Tips: Put this in a file and scp it in to the shell and then use source file to load it.
Here you're switching shell to tcsh and setting it up. As I said this is completely optional but makes the shell a little more friendly.
I split my first disk (ad0) with 4 GB for swap space and the rest for ZFS.
This tells fdisk to use the whole disk, don't worry about the "Geom not found" error. Then write and edit the bsdlabels. I changed size for a: to 4G, offset to 0 and fstype to swap as this will be my 4 GB swap space. I then added a new line with b: * * unused wich tells bsdlabels that b should take all the rest of the disk.
This gives me 4 GB of swap space (a) and the rest of the disk for GELI and ZFS (b).
We now need a temporary place to store our key files for GELI and to generate the key files.
This is the key files wich we'll use for GELI.
Initialize GELI for the disks. -b for passphrase on boot, -K keyfile, -s blocksize and -l keylen
Enter your secret passphrase twice for each geli init, this is needed at boot time in order to use the disks.
Now we attach them in order to use them.
If you check /dev/ you'll se that two new devices just showed up. /dev/ad0s1b.eli and /dev/ad4.eli in my case. This is the devices we'll use for ZFS.
We now need to create /boot/zfs/ because the zpool.cache is need on the USB stick when we boot. I learned this the hard way. Without this file ZFS won't work at boot and the system can't mount root.
We only create this dir for now. ZFS will place a cache file there wich we later copy to the USB stick.
Now we can setup ZFS. As I said earlier my setup was just two disks in a raid0. Read more about ZFS on the FreeBSD wiki.
You can verify that the zpool got created with zpool status. It should show that it's using our .eli GELI disks. Don't forget the .eli extensions when setting up the zpool.
Now change mountpoint to legacy for our zfs tank. We'll mount ZFS manually.
Create the installation dir, mount my tank/zpool, create var tmp and usr (for mount options later like noexec etc) and mount them too.
Continued in next post.....
I got interested in this setup the other day and I'll try to explain how I did it so that others can try it out and give feedback. Most of this is probably already known and tested but I couldn't find any complete howto for the whole process. You setup and install everything from the FreeBSD install disk, no need for a second harddrive, temporary partitions or anything like that. Everything you need is one or more internal hard drives, an install CD/DVD and a USB stick for booting.
Before trying this method make sure your box and bios is able to boot from a USB stick. Also make sure that the USB stick you have is bootable. Mine worked at first try so I don't really know of any good way to test this.
In the end my box the system will have:
* All internal hard drives will be encrypted with GELI and ZFS will be used for everything, including / (root) running on top of GELI.
* All internal hard drives will be completely encrypted with GELI, no need for an unencrypted /boot/ since we use a USB stick for boot and GELI keys.
* Swap will be encrypted with GELI with one time key.
* On boot the system will load kernel and modules from the USB stick and you'll be asked for passphrases to the GELI disks before the system will run.
* It's only possible to boot from the USB stick, unencrypted of course, containing /boot/. The GELI encryption keys and a loader.conf for the boot loader will be placed at the stick. The USB stick is only needed at boot time, when the system has booted up you can safely remove this and store it in a secure location and nothing on the system will be bootable or accessible without this stick and your passphrases.
The method I describe can be used in different setups and configurations. This is just how I setup my box. Instead of a raid0 you could setup ZFS in mirror or raid5 or whatever you want your setup to be.
My setup consists of:
- ad0 320 GB - Will be split in two with a 4 GB ad0s1a for swap and the rest, ad0s1b for ZFS.
- ad4 73 GB - The whole disk will be added to the zpool.
- da0 2 GB USB stick - This is the usb stick I use for booting and key files.
Installation and setup
The steps:
1. Boot install disk and drop to Fixit shell
2. Setup the Fixit shell
3. Setup partitions/slices on the internal disks
4. Setup GELI on the disks.
5. Create the ZFS pool
6. Mount ZFS in the right place
7. Back in sysinstall change install location and do a custom Distribution install
8. Back to Fixit shell and setup the USB stick and some config files.
9. Reboot and done
First off download and boot the system with a FreeBSD install disk. I used the FreeBSD 7.1 DVD but I think that the CD disk1 will work too.
At the install menu the first thing you'll do is to drop to the Fixit shell. Most of the work will be done there. You'll find it at the main menu of sysinstall. Choose option number 2 with livefs from CD/DVD.
Before starting out make sure you've backed up all your disks. Everything on the disks will be wiped.
You can do almost everything from the Fixit shell but it needs some setting up in order to do what we want. A few symlinks is needed in order to load modules and to use some applications.
Setup network (this is not necessary but it's much easier to just scp in the config files than to edit them live from the Fixit shell).
I use a local dhcp server to get networking set up but you could probably do this just as fine manually with ifconfig etc.
Code:
mkdir /var/db/
dhclient em0
If you want to be able to use scp to copy in configs and backup keyfiles you also need to create a symlink for ssh.
Code:
mkdir /usr/bin/
ln -s /dist/usr/bin/ssh /usr/bin/ssh
Now we need to load the GELI and ZFS module. In order to do this we need some symlinks from the CD/DVD.
Code:
ln -s /dist/boot/kernel /boot/kernel
ln -s /dist/lib /lib
kldload geom_eli
kldload zfs
This step is optional but it's always a good idea to clean out all the old stuff from the disks. For security, easy of mind etc.
Code:
dd if=/dev/urandom of=/dev/ad0
dd if=/dev/urandom of=/dev/ad4
dd if=/dev/urandom of=/dev/da0
This step is optional too but it makes the fixit shell a lot easier to work with.
Tips: Put this in a file and scp it in to the shell and then use source file to load it.
Code:
tcsh
setenv LANG "en_US.UTF-8"
setenv HISTCONTROL "ignoredups"
setenv PAGER "less"
setenv PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/mnt2/usr/local/sbin:/mnt2/usr/local/bin:/mnt2/usr/sbin:/mnt2/usr/bin:/mnt2/sbin:/mnt2/bin"
set autolist
set nobeep
set prompt="[%n@%m:%/]%# "
alias ls "ls -G -A -F"
I split my first disk (ad0) with 4 GB for swap space and the rest for ZFS.
Code:
fdisk -I /dev/ad0
bsdlabel -w /dev/ad0s1
bsdlabel -e /dev/ad0s1
Code:
a: 4G 0 swap
b: * * unused 0 0
c: (don't touch or edit)
We now need a temporary place to store our key files for GELI and to generate the key files.
Code:
mkdir -p /root/keys
dd if=/dev/random of=/root/keys/ad0s1b.key bs=128k count=1
dd if=/dev/random of=/root/keys/ad4.key bs=128k count=1
Initialize GELI for the disks. -b for passphrase on boot, -K keyfile, -s blocksize and -l keylen
Code:
geli init -b -K /root/keys/ad0s1b.key -s 4096 -l 256 /dev/ad0s1b
geli init -b -K /root/keys/ad4.key -s 4096 -l 256 /dev/ad4
Now we attach them in order to use them.
Code:
geli attach -k /root/keys/ad0s1b.key /dev/ad0s1b
geli attach -k /root/keys/ad4.key /dev/ad4
We now need to create /boot/zfs/ because the zpool.cache is need on the USB stick when we boot. I learned this the hard way. Without this file ZFS won't work at boot and the system can't mount root.
Code:
mkdir /boot/zfs/
Now we can setup ZFS. As I said earlier my setup was just two disks in a raid0. Read more about ZFS on the FreeBSD wiki.
Code:
zpool create tank ad0s1b.eli ad4.eli
Now change mountpoint to legacy for our zfs tank. We'll mount ZFS manually.
Code:
zfs set mountpoint=legacy tank
Create the installation dir, mount my tank/zpool, create var tmp and usr (for mount options later like noexec etc) and mount them too.
Code:
mkdir /mnt/install/
mount -t zfs tank /mnt/install
cd /mnt/install/
mkdir var tmp usr
zfs create tank/var
zfs create tank/tmp
zfs create tank/usr
mount -t zfs tank/var /mnt/install/var
mount -t zfs tank/tmp /mnt/install/tmp
mount -t zfs tank/usr /mnt/install/usr
Continued in next post.....