This article will tell you how to fully encrypt your hard disk in FreeBSD 9.x. When I say ‘fully’, I mean as close as possible. It will leave the bootloader and /boot folder unencrypted, but everything else will be encrypted (including your swap space). Basically, all your data is encrypted and that’s the point…
Boot from any FreeBSD 9 install medium (except bootonly), and choose Live CD at the installer menu.
For this article, I will assume you’re using the /dev/ada0 disk, a 10GB /boot, a 4GB swap and remaining disk encrypted. The contents will be encrypted using AES-XTS 256-bit encryption with a 4 kilobit random data partial key and a passphrase (required to type on boot). This method requires no external data (no USB sticks, no bootable CDs to boot the OS) – but does not offer two factor authentication which is better than this method. For general encryption needs, this method is more than sufficient.
Note that more recent CPUs support AESNI flag for offloading. As GELI uses the crypto(4) framework, the OS will utilise this function of your CPU to assist the encryption to decrease CPU load.
First, we need to remove any existing GPT or MBR partition tables on the disk – ignore any ‘invalid argument’ messages you get at this stage:
gpart destroy -F ada0
Now we need to initialise a new GPT partition table, as follows:
gpart create -s gpt ada0
We will now create a 64kb boot partition (this contains the boot loader only, so is safe and required to be unencrypted):
gpart add -s 128 -t freebsd-boot ada0
Next, we will create the /boot partition – you can adjust the sizes here if you need, but i’d suggest not shrinking it too much or you’ll get into problems when doing OS upgrades later…
gpart add -s 10G -t freebsd-ufs ada0
Now for a swap partition. Again, you can adjust the size if needed. This will be encrypted during boot with a one-time 256bit key.
gpart add -s 4G -t freebsd-swap ada0
Finally, we assign the remaining data to a partition. This will form the entire disk (excluding /boot) and will be encrypted shortly.
gpart add -t freebsd-ufs ada0
OK, so we’ve created… ada0p1 (bootloader), adap2 (unencrypted /boot partition), adap3 (swap partition) and adap4 (encrypted disk partition). We need to write the boot loader to the disk now:
gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada0
Now we need to format the /boot partition:
newfs -O2 -U -m 0 -j /dev/ada0p2
And temporarily mount it as /mnt:
mount /dev/ada0p2 /mnt
Now we will create a 4kb random data file that will form part of the encryption key:
dd if=/dev/random of=/mnt/encryption.key bs=4096 count=1
Now we’re in a position to encrypt the main disk. This part will ask for a passphrase twice to complete:
kldload geom_eli
geli init -a HMAC/SHA256 -b -B /mnt/ada0p4.eli -e AES-XTS -K /mnt/encryption.key -l 256 -s 4096 /dev/ada0p4
geli attach -k /mnt/encryption.key /dev/ada0p4
You will receive some messages on the console about checksum mismatches – this is normal and please ignore them.
If you have time, I recommend writing the entire disk with random data to initialise the checksums. This is a VERY time consuming step – you can skip it if you wish, but it is recommended:
dd if=/dev/random of=/dev/ada0p4.eli bs=1m
Next we will unmount the old parition so we can mount the new “root” after formatting (and re-mount the /boot partition too):
umount /mnt
newfs -O2 -U -j -m 6 /dev/ada0p4.eli
mount /dev/ada0p4.eli /mnt
mkdir /mnt/bootdir
mount /dev/ada0p2 /mnt/bootdir
OK, we’re ready to install the OS files onto the disk now… We will install the base, kernel, src and ports tarballs as follows:
cd /mnt
unxz -c /usr/freebsd-dist/base.txz | tar xpf –
unxz -c /usr/freebsd-dist/kernel.txz | tar xpf –
unxz -c /usr/freebsd-dist/src.txz | tar xpf –
unxz -c /usr/freebsd-dist/ports.txz | tar xpf –
Note: this can take a while (especially the ports extraction) so please be patient. If you’d like to see some kind of progress, change the “xpf” to “xvpf” and it will scroll the files to the screen as they are extracted.
Now we have to move the /boot folder to the unencrypted partition (it’s really not much use if it’s encrypted!) – we will also move the keyfile and backup file into the /boot folder:
mv boot bootdir/
ln -fs bootdir/boot
mv encryption.key ada0p4.eli bootdir/boot/
Now we need to prepare a few things in the installed OS – so we will chroot into the folder:
chroot /mnt
We need to tell the boot loader to load kernel modules for decryption, and also tell it about the keyfile for the partition… edit the file /boot/loader.conf and enter the following:
vfs.root.mountfrom=”ufs:/dev/ada0p4.eli”
aesni_load=”YES”
geom_eli_load=”YES”
geli_ada0p4_keyfile0_load=”YES”
geli_ada0p4_keyfile0_type=”ada0p4:geli_keyfile0″
geli_ada0p4_keyfile0_name=”/boot/encryption.key”
Now we need to tell the system to encrypt our swap space using a one-time key on each boot (note: this prevents system dumps from working)… edit /etc/rc.conf and enter:
geli_swap_flags=”-e AES-XTS -l 256 -s 4096 -d”
Next we need to tell the system our mountpoints… edit the file /etc/fstab and enter:
# Device Mountpoint FStype Options Dump Pass#
/dev/ada0p4.eli / ufs rw 0 0
/dev/ada0p2 /bootdir ufs rw 1 1
/dev/ada0p3.eli none swap sw 0 0
Now we need to initialise a few things… let’s start by setting the root password:
passwd root
And configuring your timezone:
tzsetup
And initialise the sendmail aliases file:
cd /etc/mail
make aliases
You can do any other system setup you need now, such as adding users, configuring SSH or networking… when you’re done:
exit
Now we’re done, we can reboot…
reboot
On boot, you will see a prompt for:
Enter passphrase for ada0p4:
Note, however, that devices are still being detected while this occurs so it may scroll off the screen (usually while detecting USB devices) – this doesn’t affect your ability to enter the passphrase, but can be confusing if you’re not expecting it!
Once the system is up and running, you can use it as normal.
The only point to note is that when you do an OS upgrade, during the “mergemaster” stage, it will complain that /boot is a symlink not a directory. Simply tell it to ignore/do nothing and it will install the files as normal.
Thanks for the nice how to. However, it should be noted that the command to format the ada0p4.eli partition be as follows: newfs -O2 -U -m 6 -j /dev/ada0p4.eli . Otherwise, you’ll keep getting an error and the process will abort (in FreeBSD 9.0 Release).
I cannot boot I get this error
gptboot: No /boot/loader on 0:ad(0p2)
,,,
FreeBSD/x86 boot
Default: 0:ad(0p2)/boot/kernel/kernel
Boot:
This error sounds like you haven’t installed the boot files into ada0p2.
Double-check that you followed every command exactly.
The error is saying that /boot/loader and /boot/kernel/kernel are not present on the small 10GB unencrypted partition (ada0p2) – this is the partition that is eventually mounted as /bootdir and contains a boot folder.
I did follow all commands exactly.
I am using FreeBSD 9 Release CDROM i386.
The only command that i didnt follow is the geli init
when I use HMAC I cannot mount my newfs I only use
%geli init -bl 256
is it ada or just ad?
It worked fine now. I just logged in again using the boot CD and fixed loader.conf. Also, on my 1st attempted I forgot to copy the boot partition over.
Thanks!
When making new FS on encrypted partition (performing newfs -O2 -U -j -m 6 /dev/ada0p4.eli) I get strange error:
GEOM_ELI: da0p4.eli: 8192 bytes corrupted at offset 8192.
newfs: can’t read old UFS1 superblock: read error from block device: Inavlid argumens
…
hmm the corrupted message is normal if you skipped over the long ‘dd’ write section of the page, but the newfs error is unusual… not really sure what’s up there.
Nice instructions. Wonder, should this also work for a virtual host? Have tried this instruction with 9.0-Release and after rebooting I get error 19 and end up in mountroot> prompt. Any idea?
The OS doesn’t care what hardware it is (physical or virtual) – it should work the same either way.
If you’re getting a mountroot> prompt, you may have missed a step of the installation perhaps.
“You will receive some messages on the console about checksum mismatches – this is normal and please ignore them.”
Why is it normal? I mean, if everything is going right, why are such warning being issued?
What filesystem will be installed this way?
Thanks.
It’s normal because you haven’t generated the checksums on the disk yet.
To do so, you need to write the entire disk once which is a time consuming task (depending on the size of the disk).
If you run the command I mention as being time consuming in the post (which is recommended) then you will not get any checksum errors as you will have written a full disk of data and therefore generated all checksums.
It’s simply there for people who want the quick method (a lot of people are impatient) – I included the recommendation to run the ‘dd’ command to generate them so it should please both sets of people!
For a more technical description… when you try to partition the disk, it looks for entries at various points on the drive. The checksums fail as it is trying to read an area of the disk that has not been written to yet (so has no checksums). This means the checksums are mismatched (or nonexistent).
Thank you for clarifying.
You didn’t tell what filesystem will be installed this way, but I guess it will be UFS.
The Handbook advises against manual partitioning for beginners. What would change if a beginner user chose the automatic partition layout (“Auto Defaults” in the FreeBSD partition editor) instead?
It uses a UFS2 with journalled soft-updates filesystem (with space optimisation on the unencrypted boot filesystem, and time optimisation on the encrypted filesystem – it also reserves only 6% of space compared to the default of 8%).
There is no way to do encryption in FreeBSD for beginners. You have to skip the installer entirely so there’s no way to choose the automatic partition layout.
The installer supports only standard installations and can’t currently support encryption or other technologies like raid or ZFS.
Thanks. Then the issue would be only about the size of the swap partition. You used 4GB for how much system RAM?
Also, any pointers to continue the installation for a desktop with a window manager? All the tutorials I’ve seen show installation via bsdinstall, but since it cannot be used here…
long gone are the days when swap should be relative to your system ram in FreeBSD… 4GB should be more than enough for any system these days – if anything probably larger than needed.
I have a post on here for installing xorg+gnome for a desktop from either ports or packages.
You can always use bsdinstall post-install to set options or install packages as normal. You just can’t use it to do the initial install due to the disk configuration.
I’ve found your post about Xorg + Gnome, thanks. So, bsdinstall can be run later… I didn’t know that. Should I choose the “Install” option then? If so, I guess I will have to choose the Manual partitioning, and just press Finish because the partitions are already in place, right?
I am getting an error (after reboot) with this quide using FreeBSD 9 as guest OS with KVM ->
“mounting from ufs:/dev/label/eee.elia failed with error 19”
I did by the instructions and double checked for mistakes. Any ideas?
You can’t use labels as they will not work. You have to use the raw device names (e.g. /dev/da0p2.eli)
Never mind, I’ve found a guide to create the encrypted partitions in the context of bsdinstall: http://namor.userpage.fu-berlin.de/howto_fbsd9_encrypted_ufs.html
Thank you for the assistance.
Hi,could you tell me how to encrypt a ramdisk?
I have build a kernel with “options MD_ROOT, options MD_ROOT_SIZE=53248”
and make a mfsroot file includ some codes.
Then put the mfsroot file into kernel.
But I want encrypt the mfsroot file first and won’t to input “boot password”(just like: On boot, you will see a prompt for:Enter passphrase for ada0p4:)
Could you help me? Sorry for my pool English.
Thanks.
MR_Micah@126.com
As far as I know, you can’t encrypt a ramdisk for booting.
how about encrypt kernel?
It is not possible to encrypt the kernel (nor should it be required as there’s nothing sensitive in the kernel) – the contents of the /boot folder must be left unencrypted.
When I get to extracting the src.txz on FreeBSD 9.1 the disk fills up, I get “Write to restore size failed” I have been following the commands exactly as stated here 3-4 times. /mnt has ada0p4.eli mounted and a capacity of 881M and /mnt/bootdir is 10G with ada0p2 mounted.
if ada0p4.eli is only 881MB, you need a bigger disk! You will be filling up the encrypted partition with the base OS.
Figured it out, not enough disk space. Leave more free space for the last partition. No need to publish these comments. Thanks for the guide!
Oh you already answered me, I did not see that before posting again. Thanks 🙂
This worked great for me a few months ago and have zfs jails running over the top.
How would I go about changing the device name? Due to a hardware change the device name is changing and I can’t figure out where to change it, have changed in loader.conf but does not mount. Is there something in the GELI metadata or if it fully controlled by loader.conf?
It should all be in loader.conf – but you should be more worried about why the device names are changing!
Ohh… have also changed in fstab.conf, forgot to mention in above.
Thanks for your documentation, I wonder if you feel the encryption when you use your computer (like slower).
I thinking to use encryption on my laptop, and for I don’t known why each time I use a little CPU (launching flash, starting building some ports) the fan start immedialty. So I’m little afraid about cpu comsuption when using encrypted disk, if my cpu load is always high that’s going to make me very sad.
Thanks again
I’ve always used it on laptops and not noticed a significant increase in CPU usage… of course it depends on just how much disk activity you do.
But generally so long as your CPU isn’t really slow to begin with, you should be fine.
Thanks for this great “how to” :). Work like a charm under FreeBSD 9.1 x64.
i’m fairly certain
dd if=/dev/random of=/dev/ada0p4.eli bs=1m
should actually be
dd if=/dev/random of=/dev/ada0p4 bs=1m
nope, it’s definitely /dev/ada0p4.eli 🙂
By writing to the .eli device, you’re forcing an encrypted write of the entire disk which stops annoying messages to syslog/screen about mismatched checksums on random reads.
nope, nevermind. I’m stupid and broke something. Ignore the above
Hi,
I did everything like in tutorial and it worked fine, I rebooted my home server many times… But once I got electricity off period, and after that when I boot I always get incorrect password… I tried with debug=3 and showpassword=1 in loader.conf but no luck?
Do i need to restore with ada0p4.eli backup file or smth?
Regards.
Hi. Tnx about your article.
i wan’t to find any way to crypt my hard, but don’t ask any password in startup, and limit my os to motherboard HWID ?
Unfortunately, I don’t think you can do that within FreeBSD at the moment.
Hi Dan, great article. I’ve set up two machines this way. I noticed that both machines are yelling “WARNING: / was not dismounted properly” on every reboot. Is this “normal” behaviour? I don’t see any problems so far, so I ignored this message.
Hmm no, it should never say that unless you don’t shutdown the computer correctly.
It’s unlikely to cause you an issue as that partition isn’t written to unless you update/upgrade the kernel – but still it shouldn’t be doing it.