From bdffa42684c2275271c65c58f0b2d60d67fcd833 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roddy=20Gonz=C3=A1lez?=
Date: Thu, 6 Jun 2024 22:50:18 +0200
Subject: [PATCH] Add a post about NetBSD installation with CGD in UEFI
Also, edit the header and footer to make it a bit cleaner
---
content/posts/uefi-full-disk-encryption.md | 405 +++++++++++++++++++++
layouts/partials/footer.html | 1 +
layouts/partials/header.html | 9 +-
3 files changed, 409 insertions(+), 6 deletions(-)
create mode 100644 content/posts/uefi-full-disk-encryption.md
diff --git a/content/posts/uefi-full-disk-encryption.md b/content/posts/uefi-full-disk-encryption.md
new file mode 100644
index 0000000..93f59f0
--- /dev/null
+++ b/content/posts/uefi-full-disk-encryption.md
@@ -0,0 +1,405 @@
+---
+title: "NetBSD - UEFI installation with Full Disk Encryption"
+date: 2024-05-27T22:54:45+02:00
+slug: 2024-05-27-uefi-full-disk-encryption
+type: posts
+draft: false
+summary: |
+ This is the method I use to install a semi-full disk encrypted NetBSD system.
+ I may add RAID devices, LVM, multiple disks, etc.
+ Then mount everything under `/targetroot` and extract the sets.
+
+categories:
+ - NetBSD
+tags:
+ - NetBSD
+ - UEFI
+ - encryption
+ - installation
+---
+
+I've been trying to teach myself NetBSD.
+It has been a painful experience, full of bugs and kernel panics.
+I've post some of them in the Fediverse.
+Like [here](https://mastodon.bsd.cafe/@release_candidate/112520904317829098) and [here](https://mastodon.bsd.cafe/@release_candidate/112128737628556050).
+
+One of the weakest point that I've seen in NetBSD is the installer.
+If you need a simple installation it just works ™.
+But as soon as you need some complex setup, like RAID mixed with encrypted partitions, or something similar, the installer is subpar.
+You will face some segfault from the installer, a kernel panic or another surprise.
+
+
+I've forced myself to use NetBSD as a daily driver in my laptop.
+Since it's a laptop it needs full disk encryption.
+A mobile computer can be stolen at anytime, specially if you live in the [Lawlessness](https://en.wikipedia.org/wiki/Latin_America).
+So I had to make a "special way" to install NetBSD with encryption.
+
+Now, even today I have no idea how to have actual full disk encryption with NetBSD.
+[CGD devices](https://www.netbsd.org/docs/guide/en/chap-cgd.html), the virtual block devices that implements encryption, require metadata in `/etc/cgd`.
+I've seen [a wonderful tutorial for full-disk encryption for MBR-based systems](https://www.unitedbsd.com/d/461-netbsd-full-disk-encryption-with-cgd), but not for UEFI.
+And my laptop doesn't really like to boot in old MBR mode.
+
+Following the [documentation of CGD drives](https://www.netbsd.org/docs/guide/en/chap-cgd.html#chap-cgd-example) and [the documentation on UEFI installations](https://wiki.netbsd.org/Installation_on_UEFI_systems/), I have a semi-full disk encryption.
+With plain-text root file-system, and encrypted `/home`, `/usr`, `/var` and swap.
+
+So, without further complaints, this is the way I have some disk encryption in UEFI systems with NetBSD.
+
+# Boot the installer image
+
+I wrote this post with a virtual machine to reproduce all the steps.
+In such environment it may be useful to use the serial port as a terminal instead the virtual monitor.
+So, as soon as the boot options are presented, I press option `3`.
+Then, I instruct the boot-loader to use `com0` as the terminal.
+
+```
+consdev com0
+boot
+```
+
+# Use a shell
+
+Once the installer system is up, I avoid the installer and use a shell.
+Select `Utility menu`, then `Run /bin/sh`.
+
+# Disks
+
+Now that I'm in a shell I can look what disks I have.
+
+
+```
+# systolic hw.disknames
+hw.disknames = cd0 wd0
+```
+
+In this example `wd0` is the drive where the system should be installed.
+Since I want to boot with UEFI, it needs GPT partitions.
+
+
+```
+# gpt destroy wd0
+# gpt create wd0
+# gpt add -a 2m -s 128m -t efi -l EFI wd0
+# gpt add -a 2m -l NetBSD -t ffs -s 8g wd0
+# gpt add -a 2m -t cgd -l syscgd wd0
+```
+
+First, I destroy some pre-existing GPT partitions.
+This will destroy the drive data, so be careful.
+
+These commands create three GPT partitions.
+One EFI partition with 128MB, one for the rootfs with 8GB and other for CGD with the rest of the disk.
+
+These are the sizes I use.
+Root file-system will require less than 8GB anyways, but I avoid the risk.
+
+Now disk should have three wedges.
+
+```
+# dkctl wd0 listwedges
+/dev/rwd0: 3 wedges:
+dk0: EFI, 262144 blocks at 4096, type: msdos
+dk1: NetBSD, 16777216 blocks at 266240, type: ffs
+dk2: syscgd, 24895488 blocks at 17043456, type: cgd
+
+```
+
+In this example, `/dev/dk0` is the EFI partition, `/dev/dk1` is the root partition, and `/dev/dk2` is the encrypted partition.
+You may also run:
+
+```
+# gpt show wd0
+ start size index contents
+ 0 1 PMBR
+ 1 1 Pri GPT header
+ 2 32 Pri GPT table
+ 34 4062 Unused
+ 4096 262144 1 GPT part - EFI System
+ 266240 16777216 2 GPT part - NetBSD FFSv1/FFSv2
+ 17043456 24895488 3 GPT part - NetBSD Cryptographic Disk
+ 41938944 4063 Unused
+ 41943007 32 Sec GPT table
+ 41943039 1 Sec GPT header
+```
+
+Now, I create a file-system for boot EFI partition.
+Its type is FAT.
+
+```
+# newfs_msdos /dev/rdk0
+```
+
+Then, I mount it and copy the `.efi` boot entries.
+
+```
+# mount /dev/dk0 /mnt
+# mkdir -p /mnt/EFI/boot
+# cp -v /usr/mdec/*.efi /mnt/EFI/boot
+/usr/mdec/bootia32.efi -> /mnt/EFI/boot/bootia32.efi
+/usr/mdec/bootx64.efi -> /mnt/EFI/boot/bootx64.efi
+# umount /mnt
+```
+
+Then, I format NetBSD root partition.
+The `-O 2` flag means that it will use FFv2 file-system.
+
+```
+newfs -O 2 dk1
+```
+
+Now I can mount the future root file-system.
+The installer uses `/targetroot` directory to install.
+So, I'll do the same.
+
+```
+# mount /dev/dk1 /targetroot
+```
+
+Next, I create CGD config file.
+And I place it in the future `/etc/cgd/` directory.
+
+```
+# mkdir -p /targetroot/etc/cgd/
+# cgdconfig -g -V disklabel -o /targetroot/etc/cgd/syscgd aes-xts 512
+```
+
+Now it's time to create the CGD drive.
+
+```
+# cgdconfig -V re-enter cgd0 NAME=syscgd /targetroot/etc/cgd/syscgd
+```
+
+Here, the `-V re-enter` flag is needed to validate the encrypted drive without the disklabel, which doesn't exist yet.
+Once the CGD drive is configured it is possible to create the disklabel for it.
+
+In this example, I use `cgd0a` for `/var`, `cgd0b` for swap, `cgd0e` for `/usr`, and finally `cgd0f` for `/home`.
+Partitions `c` and `d` have a special meaning in NetBSD, so I'm not using them.
+
+
+Because this is a example virtual machine I use very humble values of 3 and 4GB.
+
+```
+# disklabel -Ii cgd0
+Enter '?' for help
+partition>a
+Filesystem type [4.2BSD]:
+Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: 3G
+Partition size ('$' for all remaining) [12156c, 24895488s, 12156M]: ^C
+# disklabel -Ii cgd0
+Enter '?' for help
+partition>a
+Filesystem type [4.2BSD]:
+Start offset ('x' to start after partition 'x') [0c, 0s, 0M]:
+Partition size ('$' for all remaining) [12156c, 24895488s, 12156M]: 3G
+ a: 6291456 0 4.2BSD 0 0 0 # (Cyl. 0 - 3071)
+partition>b
+Filesystem type [unused]: swap
+Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: a
+Partition size ('$' for all remaining) [0c, 0s, 0M]: 2G
+ b: 4194304 6291456 swap # (Cyl. 3072 - 5119)
+partition>e
+Filesystem type [unused]: 4.2BSD
+Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: b
+Partition size ('$' for all remaining) [0c, 0s, 0M]: 3G
+ e: 6291456 10485760 4.2BSD 0 0 0 # (Cyl. 5120 - 8191)
+partition>f
+Filesystem type [unused]: 4.2BSD
+Start offset ('x' to start after partition 'x') [0c, 0s, 0M]: e
+Partition size ('$' for all remaining) [0c, 0s, 0M]: $
+ f: 8118272 16777216 4.2BSD 0 0 0 # (Cyl. 8192 - 12155)
+partition>W
+Label disk [n]?y
+Label written
+partition>Q
+
+```
+
+Let's add CGD config file to the future root file-system.
+
+```
+# echo 'cgd0 NAME=syscgd /etc/cgd/syscgd' > /targetroot/etc/cgd/cgd.conf
+
+```
+
+Now it's time to check if the CGD drive is working as expected.
+I unconfigure and re-configure it, then print the disklabel.
+
+```
+# cgdconfig -u cgd0
+# cgdconfig cgd0 NAME=syscgd /targetroot/etc/cgd/syscgd
+# disklabel cgd0
+```
+
+The new partitions need to be formatted and mounted in their places.
+
+```
+# newfs -O 2 cgd0a
+# newfs -O 2 cgd0e
+# newfs -O 2 cgd0f
+# mkdir /targetroot/var /targetroot/usr /targetroot/home
+# mount /dev/cgd0a /targetroot/var
+# mount /dev/cgd0e /targetroot/usr
+# mount /dev/cgd0f /targetroot/home
+
+```
+
+At this time, the system should look like this:
+
+```
+# mount
+root_device on / type cd9660 (read-only, local)
+tmpfs on /dev type tmpfs (union, local)
+tmpfs on /tmp type tmpfs (local)
+tmpfs on /var type tmpfs (local)
+tmpfs on /etc type tmpfs (union, local)
+/dev/dk1 on /targetroot type ffs (local)
+/dev/cgd0a on /targetroot/var type ffs (local)
+/dev/cgd0e on /targetroot/usr type ffs (local)
+/dev/cgd0f on /targetroot/home type ffs (local)
+
+```
+# Installation of the sets
+
+The new system is composed of sets.
+I usually install these, but your requirements may be different.
+
+The tar flag `p` is very important, since these files need to preserve their owners and mode.
+
+
+```
+# cd /amd64/binary/sets
+# tar xvzpf base.tar.xz -C /targetroot
+# tar xvzpf comp.tar.xz -C /targetroot
+# tar xvzpf etc.tar.xz -C /targetroot
+# tar xvzpf games.tar.xz -C /targetroot
+# tar xvzpf gpufw.tar.xz -C /targetroot
+# tar xvzpf kern-GENERIC.tar.xz -C /targetroot
+# tar xvzpf man.tar.xz -C /targetroot
+# tar xvzpf misc.tar.xz -C /targetroot
+# tar xvzpf modules.tar.xz -C /targetroot
+# tar xvzpf text.tar.xz -C /targetroot
+# tar xvzpf xbase.tar.xz -C /targetroot
+# tar xvzpf xcomp.tar.xz -C /targetroot
+# tar xvzpf xetc.tar.xz -C /targetroot
+# tar xvzpf xfont.tar.xz -C /targetroot
+# tar xvzpf xserver.tar.xz -C /targetroot
+# cd /
+```
+
+Then I chroot to the new system, and make the `dev`ices.
+
+```
+# chroot /targetroot
+# cd dev
+# ./MAKEDEV all
+exit
+```
+
+
+Now I edit fstab to mount the CGD partitions.
+
+```
+# vi /targetroot/etc/fstab
+
+# cat /targetroot/etc/fstab
+# NetBSD /etc/fstab
+# See /usr/share/examples/fstab/ for more examples.
+NAME=NetBSD / ffs rw 1 1
+kernfs /kern kernfs rw
+ptyfs /dev/pts ptyfs rw
+procfs /proc procfs rw
+/dev/cd0a /cdrom cd9660 ro,noauto
+tmpfs /var/shm tmpfs rw,-m1777,-sram%25
+
+# Encrypted file-systems
+/dev/cgd0a /var ffs rw 1 2
+/dev/cgd0b none swap sw
+/dev/cgd0e /usr ffs rw 1 2
+/dev/cgd0f /home ffs rw 1 2
+```
+
+
+The file rc.confg also needs to be edited
+
+```
+# vi /targetroot/etc/rc.conf
+
+
+rc_configured=YES
+
+# Add local overrides below.
+#
+dhcpcd=YES
+dhcpcd_flags="-qM wm0"
+hostname=marte.local
+dhcpcd=YES
+dhcpcd_flags="-qM wm0"
+sshd=YES
+wscons=YES
+```
+
+`rc_configured=YES` is important, otherwise the system will always boot in single-user mode.
+
+These are the variables I use for a new system.
+For example, my network device is `wm0`,
+Your network card and requirements may be different.
+
+# Unmount and reboot
+
+Umount the new system:
+
+```
+# umount /targetroot/home
+# umount /targetroot/var
+# umount /targetroot/usr
+# umount /targetroot/
+```
+
+Then shutdown or reboot:
+
+```
+# shutdown -p now
+```
+
+Fun fact. Sometimes at this point I experience a kernel panic.
+I have no idea why.
+It's very unpredictable.
+Sometimes it happens, sometimes don't.
+
+# The new system
+
+In the new system you may need to change root password:
+
+```
+# passwd
+```
+
+Install pkgin:
+
+```
+PATH="/usr/pkg/sbin:/usr/pkg/bin:$PATH"
+PKG_PATH="http://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/amd64/10.0/All/"
+# export PATH
+# export PKG_PATH
+# pkg_add pkgin
+```
+
+And add a new user:
+
+
+```
+# useradd -m -G wheel -k /etc/skel vsis
+```
+
+And, of course RTFM:
+
+```
+# man afterboot
+```
+
+# Conclusion
+
+This is the method I use to install a semi-full disk encrypted NetBSD system.
+I may add RAID devices, LVM, multiple disks, etc.
+Then mount everything under `/targetroot` and extract the sets.
+
+I may be biased by [the Arch way](https://wiki.archlinux.org/title/installation_guide) to install the system, but I find this method better than the installer.
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
index 5232b53..bb45371 100644
--- a/layouts/partials/footer.html
+++ b/layouts/partials/footer.html
@@ -5,4 +5,5 @@
{{ .Name }};
{{- end }}
+
diff --git a/layouts/partials/header.html b/layouts/partials/header.html
index c57b538..d213ed4 100644
--- a/layouts/partials/header.html
+++ b/layouts/partials/header.html
@@ -1,15 +1,12 @@