neubaer The promised guide.
EDIT 2021-04-18: This guide has been moved into its own Wiki post here and will be kept updated there.
Assumptions
Legacy/BIOS boot, GPT-formatted disk, NetBSD 9.1, you're starting out from an empty disk.
But see the Endnotes for tips on adapting this to alternative configurations.
Security Notice
The bootloader and kernel are still stored on an unencrypted partition. Depending on your threat model this may pose a problem, so take care with mitigating physical access risks.
Likewise, the encryption parameters for the encrypted volume are stored out in the open. If you care about plausible deniability, you may want to think really hard about this fact.
Acknowledgements
This guide is in part based on other excellent guides found here and on the NetBSD site.
GPT/UEFI Installation by JuvenalUrbino
Root Filesystem Encryption on NetBSD Wiki
Installation on UEFI systems on NetBSD Wiki
The CGD Driver chapter from NetBSD Handbook
Booting
Well you have to boot from something, don't you? I used the CD.
After getting to the main installer menu, drop into shell with Utility menu -> Run /bin/sh.
You may want to switch to a more user-friendly shell as well, like /bin/ksh.
GPT Partitioning
Check your disk names with sysctl hw.disknames
. Mine is called "wd0", which is the first IDE/SATA disk.
Create a new GPT table and two partitions.
The boot partition is labeled "cgd.conf" because that's how the unlock script picks it out.
The second partition can be labeled whatever you wish, as long as you remember it, and as long as it's not "cgdroot" (see Endnotes for details).
Due to how BIOS booting works, we have to mark the boot partition as bootable.
gpt create -f wd0
gpt add -a 2m -s 128m -t ffs -l cgd.conf wd0
gpt add -a 2m -t cgd -l syscgd wd0
gpt biosboot -i 1 wd0
Along with creating the partitions, you probably got green kernel messages stating some dk* wedges got created as well. On NetBSD, each GPT partition has a corresponding dk wedge that's used to address it - compare with the "wd0e" naming of the MBR/disklabel scheme.
You can check what wedges you have with the same sysctl command, or dkctl wd0 listwedges
. Mine are dk0 and dk1 for the boot and encrypted partitions, respectively.
CGD Setup
First a small tangent. We have to format and mount the boot partition because that's where the encryption parameters will be stored. So create a new FFSv2 filesystem and mount it to /etc/cgd, because that's where cgdconfig expects it to be.
newfs -O 2 dk0
mount /dev/dk0 /etc/cgd
Now the actual encrypted volume setup. The volume will contain a disklabel so we're using that as verification method. I like the aes-xts encryption with a 512-bit key, but you can choose whatever you want. The following command merely saves the parameters into a file for later use.
cgdconfig -g -V disklabel -o /etc/cgd/syscgd aes-xts 512
Since the volume does not contain the disklabel yet, we have to override it for the moment. NAME is the label that you chose when you created the GPT partition. Mine is "syscgd".
cgdconfig -V re-enter cgd0 NAME=syscgd /etc/cgd/syscgd
The passphrase you just got asked for (twice) is how you'll be unlocking the volume from this point on, so I really hope you selected a good one.
And now create the actual disklabel.
disklabel -Ii cgd0
The -i
option starts an interactive mode that's easy to use (and you can get help with "?").
To edit the "a" partition enter "a" and so on.
Valid partitions are a-p, and remember that the first four have a special meaning:
- "a" is the root partition, and in fact gets mounted as / by the unlock script.
- "b" is traditionally the swap partition, so use it as such. Partition type is "swap".
- "c" is the space addressed by the MBR table on x86 and AMD64. Not present here because we don't have an MBR table on the CGD volume. On other architectures this is the whole disk.
- "d" is the whole disk on x86/AMD64. You better leave this one alone.
- The rest doesn't have any special meaninig. I usually use e-h as /usr, /var, /tmp, and /home. Partition type is "4.2BSD" just like "a".
After you're happy with your edits, write the label with "W" and exit with "Q".
Now we're going to check if the CGD volume is configured correctly. First unconfigure (that means close) the cgd0 volume:
cgdconfig -u cgd0
Next the cgd0 volume, its dk wedge, and the encryption parameters are added to the cgd configuration. (Again, substitute "syscgd" for however you labeled your encrypted wedge.)
echo 'cgd0 NAME=syscgd /etc/cgd/syscgd' > /etc/cgd/cgd.conf
And now we open it just how the unlock script would and hope for the best.
cgdconfig -C
If everything went well, you should have the cgd0 volume open and the disklabel you created is visible with disklabel cgd0
.
NetBSD Installation
We'll let the installer take care of the boring parts - that is extracting sets and configuring the various minutiae of the system.
Exit the shell and start the installation like you normally would.
Select the cgd0 volume for installation, and Use existing disklabel partitions.
Fill out the mountpoints for the various partitions, and switch FFS to FFS2 where you can for better performance. You also have to check the newfs and mount options and I think.
When asked about bootblocks, select Use existing bootblocks.
Select full installation, and after the sets get unpacked configure the timezone, and the network, and all the other stuff.
When that's done and you're back in the main installer menu, drop back into shell with Utility menu -> Run /bin/sh.
Kernel and Bootloader
The last part of the configuration.
Mount root back to /mnt and copy the boot.cfg config file and the netbsd kernel to the boot partition (hopefully) still mounted on /etc/cgd.
mount /dev/cgd0a /mnt
cp -p /mnt/boot.cfg /mnt/netbsd /etc/cgd
Next copy over the kernel module that contains the initial ramdisk. (Substitute amd64 for whatever other architecture you're using.)
cp /amd64/installation/miniroot/cgdroot.kmod /etc/cgd
Finally, copy over the second-stage bootloader as well.
cp -p /usr/mdec/boot /etc/cgd
The only thing left now is to install the primary bootloader into the boot partition and adjust the configuration so the module gets loaded first. (Note that the first-stage bootloader name depends on which filesystem the second stage is stored on - in our case it's FFSv2. Also this step is very architecture-specific.)
installboot -v -o timeout=5 /dev/rdk0 /usr/mdec/bootxx_ffsv2
In /etc/cgd/boot.cfg edit the first menu entry so that it has "load cgdroot.kmod" before the boot command. It should look something like this:
menu=Boot normally:rndseed /etc/entropy-file;load cgdroot.kmod;boot
And that's it, you're done!
If you want to do some light cleanup then unmount /mnt and /etc/cgd, and unconfigure the encrypted volume with cgdconfig -u cgd0
.
Then exit the shell and reboot.
If everything went well you should be asked for your passphrase during the boot and then the init continues until you get a login screen.
Endnotes
- On CURRENT the unlock script is a bit more intelligent, and tries to mount root from a "cgdroot" labeled dk wedge. That means you can nest another GPT table inside of the cgd0 volume if you don't like disklabels for some reason.
- Even on 9.1, the unlock script tries to mount the boot partition from wd0a and ld0a in case it doesn't find a dk wedge labeled "cgd.conf". This means you can use a MBR/disklabel partitioning scheme on the physical disk, if you're into that sort of thing.
- UEFI looks like it should work, but who knows really. With UEFI you never know for sure. In any case, the bootloader installation will differ, but it seems possible to use the EFI partition as the unencrypted boot partition with kernel, ramdisk, and cgd config. Something, something, future work.
- You can see the unlock script here. 1.4 is the version in NetBSD 9.1, and 1.5 is in CURRENT.