December 4, 2022

OpenBSD: Full encryption and dual/triple boot with gnu/linux and windows

Intro

It is possible to fully encrypt your OpenBSD partition if you are dual-booting, which I am. I have a small gnu/linux partition to use for blobs like skype, zoom etc. You can also have a third partition for windows (which I need because my university has decided to rely 100% on Microsoft and “teams”).

 

Strategy

I have these friends telling me “you should use this and that linux distro because …” The point is that I have grown bored with linux. I really could not care less which “flavour” is better or worse. The only usable OS that I know of is OpenBSD.

That being said, I am using (mate) ubuntu for my gnu/linux partition for the blob things. It supports LUKS during installation, which is good but there is a main problem – gnu/linux has adopted the “let me think for you” approach of Microsoft, and that leads to problems. They assume that (a) you only want gnu/linux on your laptop, (b) you might want to keep windows on it and (c) if you decide to encrypt your gnu/linux partition, it should occupy all of the disc.

I however want

  1. One small encrypted gnu/linux partition
  2. One small windows partition
  3. A lot of space for OpenBSD

For this you need to do this (in order):

  • Install windows
  • Install ubuntu with encryption (but there is a problem, see next paragraph)
  • Resize windows
  • Install OpenBSD

When I say that there is a problem, it’s that the LUKS option seemingly does not exist for your installation if you choose to install ubuntu with windows (first option here in this picture).

However, this is not so. There’s a workaround to have a small ubuntu partition encrypted with LUKS alongside with windows and OpenBSD. For that, you need to

  1. Choose into the second option and choose “Erase disk and install Ubuntu” (which of course we won’t, since windows is already there).
  2. Got to the “Advanced features…” option, and select “Use LVM and encryption”, and then OK to close it.
  3. Then choose “Install Ubuntu alongside Windows Boot Manager”.

Now the option you wanted, install ubuntu alongside with windows, will have kept the encryption option for ubuntu.

Note that you don’t have to keep windows. It’s just a way to confine ubuntu to a small partition. If you try to install it on an empty disc without windows you won’t be able and will end up in therapy.

So, make a small partition and leave the rest of the disc to windows. After the installation boot into ubuntu and resize windows to something small, so that you have plenty of room for OpenBSD, or delete windows altogether, as I have mentioned. In any case, windows needs to be there as a placeholder to fence in the size of ubuntu, even if after the installation you decide to delete it.

It took me a full day to come up with this idea.

For some reason, the ubuntu people do not seem to think that we might want to have empty space on our drive left untouched. Anyway, this is the fix (my fix).

The easy part: Installation of OpenBSD with full disc encryption

From gnu/linux launch gparted and format the space you want to use for OpenBSD to anything you want. Then, from the terminal, toggle the partition destined for OpenBSD to “openbsd data” using fdisk:

# fdisk /dev/nvme0n1
nvme0n1    nvme0n1p1  nvme0n1p2  nvme0n1p3  nvme0n1p4  
root@amphyction:/home/pau# fdisk /dev/nvme0n1

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help):

Here you choose “t” for toggle and change the labeling of the partition where you want to install OpenBSD to 226 or so (it used to be a6 in the past)

Command (m for help): t
Partition number (1-7, default 4): 7
Hex code or alias (type L to list all): 203

Note that gnu/linux keeps changing the mapping, so that it might be a different number for you.

Boot from the OpenBSD iso usb stick

We then reboot into the OpenBSD install iso live usb that you have created (you did, right?).

Now The important thing is to identify which part of the disc corresponds to the OpenBSD partition. We can achieve this with disklabel -E on the drive. Usually the installation programme will figure out which one is it but anyway, you can also run from the shell the following:

# disklabel -E sd0

If you have toggled the partition with linux’ fdisk to “openbsd data” it will be easy to identify it and the installer will know exactly at what cylinder it stars and where it ends. Very helpful.

disklabel will show you the partitions containing linux and the uefi files (ext2fs and MSDOS, respectively).

Add a new partition taking the rest of the space. Check that the offset corresponds to what disklabel is showing you in the “OpenBSD area” line. It should be the same number of cylinder. Otherwise, you will be overwritting other partitions. I do not populate the partition with random data, but you could do it with

sd0> a a
offset: [82225152]
size: [917989376]
FS type: [4.2BSD] RAID
sd0*> w
sd0> q
No label changes.

Random data and encryption

Now that we have a partition for OpenBSD, we can write random data to the drive first. Note the “rsd0a” part of the command.

# dd if=/dev/urandom of=/dev/rsd0a bs=1m

After a few hours it will be full. We now change it and declare “a” to be of RAID type. In my case, it looked like this:

sd0> a a
offset: [82225152]
size: [917989376]
FS type: [4.2BSD] RAID
sd0*> w
sd0> q
No label changes.

Now build the encrypted device on our “a” partition.

# bioctl -c C -l sd0a softraid0

If everything goes well, you will get the name of your new device:

softraid0: CRYPTO volume attached as sd2

Create it

# cd /dev && sh MAKEDEV sd2

Overwrite the first megabyte

# dd if=/dev/zero of=/dev/rsd2c bs=1m count=1

Type exit to return to the main installer and choose sd2 as the device for the installation.

Do the usual installation. If you are doing it from a USB drive, in my case it was sd1 and it was not mounted.

After this the laptop will boot.

The gnu/linux nightmare is not over: grub syntax

We will now find out how to tell grub (actually grub2) in linux where OpenBSD is and how to boot it.

First, download the OpenBSD UEFI file from your closest mirror. In my case it is under snapshots, amd64, and it is called “BOOTX64.EFI”.

Place it at exactly this location on your gnu/linux installation and rename it to whatever you want, for instance openbsdx64.efi:

# mv BOOTX64.EFI /boot/efi/EFI/BOOT/openbsdx64.efi

Then edit /etc/grub.d/40_custom to add OpenBSD.

In my case, the real path (pwd) for the efi file is

/boot/efi/EFI/openbsd/openbsdx64.efi

and the /etc/grub.d/40_custom looks like this:

#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.

menuentry "OpenBSD" {
set root='(hd0,gpt3)'
chainloader (hd0,gpt1)/EFI/openbsd/openbsdx64.efi
}

And then update grub,

# update-grub

That syntax shows that my OpenBSD partition is installed on partition number three starting from the natural number 0 (ZERO), which means that it is number four starting from the left on this is a snapshot of what gparted is showing.

As you can see, the efi files are on partition p1 of my disc (fat32, efi), which is what you need to tell chainloader about, using this time the natural number 1 (ONE) as the first one. I am not sure why this is the case.

By the way, be careful with the quotes in the root entry. It turns out that, for some obscure reason, ubuntu is NOT using sh but dash

amphyction% ls -lrt /usr/bin/sh
lrwxrwxrwx 1 root root 4 Mar 23  2022 /usr/bin/sh -> dash

and dash is retarded when it comes to parenthesis. You can look for it in the internet. If you find this kind of error,

Syntax error: word unexpected (expecting ")")

this is the reason. You forgot to escape the parenthesis with quotes.

Updating your bios

This will screw up grub big time. The way to recover it is to follow these steps. I have four partitions on my drive

aemonius# disklabel -E /dev/sd0c
Label editor (enter '?' for help at any prompt)
/dev/sd0c
OpenBSD area: 82225152-1000214528; size: 917989376; free: 0
# size offset fstype [fsize bsize cpg]
a: 917989376 82225152 RAID
c: 1000215216 0 unused
i: 192512 2048 MSDOS
j: 3905536 194560 ext2fs
k: 78125056 4100096 ext2fs

The first partition of about 200M is for efi business, the second one is the linux unencrypted, /boot, the third one is an ubuntu LUKS volume and the fourth one the whole OpenBSD system.

To recover the ubuntu grub installation, I followed these steps (stolen from here). I booted from a live usb drive and then did this:

    • If the directory /sys/firmware/efi/efivars is empty, you need to boot the rescue system including the kernel option “efi=runtime” and mount the EFI variables before proceeding:
      # mount -t efivarfs none /sys/firmware/efi/efivars

       

    • Mount the broken system somewhere into the running filesystem.

      For my system with an EFI partition on /dev/nvme0n1p1, an unencrypted /boot partition on /dev/nvme0n1p2, and a LUKS-encrypted / partition on /dev/nvme0n1p3, do:

      # cryptsetup luksOpen /dev/nvme0n1p3 crypt
      # mount /dev/mapper/crypt /mnt
      # mount /dev/nvme0n1p2 /mnt/boot
      # mount /dev/nvme0n1p1 /mnt/boot/efi
      
      Bind mount various virtual filesystems:
      # for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount -B $i /mnt$i; done
    • Chroot into the broken system:
      # chroot /mnt
    • Chroot into the broken system:
      # chroot /mnt
    • Reinstall GRUB to the appropriate disk (without partition number):
      # grub-install /dev/nvme0n1
    • Generate the GRUB configuration file:
      # update-grub
    • Exit the chroot environment (<CTRL>-D).
    • If everything worked, reboot.