Add a post about NetBSD installation with CGD in UEFI
Also, edit the header and footer to make it a bit cleaner
This commit is contained in:
parent
8b258ec276
commit
bdffa42684
3 changed files with 409 additions and 6 deletions
405
content/posts/uefi-full-disk-encryption.md
Normal file
405
content/posts/uefi-full-disk-encryption.md
Normal file
|
@ -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.
|
|
@ -5,4 +5,5 @@
|
||||||
<a href="{{ .URL }}"><b>{{ .Name }}</b></a>;
|
<a href="{{ .URL }}"><b>{{ .Name }}</b></a>;
|
||||||
{{- end }}
|
{{- end }}
|
||||||
</p>
|
</p>
|
||||||
|
<img src="/apollo.jpg"/>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
<header>
|
<header>
|
||||||
<img src="/apollo.jpg"/>
|
you@<a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>:~ $ ls .<br>
|
||||||
you@<a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>:~ $ ls .;<br>
|
|
||||||
<div style="float: right;"><span style="color:red">❌ ERROR: </span>{{ .Site.Params.subtitle }}</div><br>
|
<div style="float: right;"><span style="color:red">❌ ERROR: </span>{{ .Site.Params.subtitle }}</div><br>
|
||||||
<p>
|
<p>
|
||||||
<nav>
|
you@<a href="{{ $.Site.BaseURL }}">{{ $.Site.Title }}</a>:~ $
|
||||||
{{ with .Site.Menus.main }}
|
{{ with .Site.Menus.main }}
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
you@<a href="{{ $.Site.BaseURL }}">{{ $.Site.Title }}</a>:~ $ <a href="{{ .URL | relURL }}"><b> {{ .Name }}</b></a>;
|
<a href="{{ .URL | relURL }}"><b> {{ .Name }}</b></a>;
|
||||||
<br/>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</nav>
|
|
||||||
</p>
|
</p>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
|
|
Loading…
Reference in a new issue