Skip to main content

Installing OpenBSD 6.9 on a laptop

Lately, I've been looking into some old laptops which I could spend my upcoming college years with. I wanted something cheap, but also good enough that I could use it for basic university related work. Of couse I could just buy a new low-end Windows laptop and be happy, but that would be a waste of money. Instead, I searched through used market for an old ThinkPad, T500 in particular. If you are a bit confused or haven't heard of Lenovo's ThinkPads and why they have a special place among many, I recommend you check out this guide. There are many newer models than the 2009's T500, however T500 seems to be the last "Librebootable" 15" ThinkPad. Flashing Libreboot is something I would love to do as well, but currently don't have the right tools to complete the process documented on the Libreboot wiki here. After T500 there are still a couple of pretty decent ThinkPad models, altough it is not possible to install completely Libre firmware on them.

Downloading OpenBSD

Downloading OpenBSD is pretty straightforward, just prepare two USB drives – one which we will boot the installer from and the other for our encryption key.

Head over to the download page and click on minirootXX.img

image-1630068858200.png

If you have a 64-bit machine, which the T500 is, select amd64. This will be a minimal intallation and we will only download file sets that we want during the install. If you do not care about this, you can pick one with the file sets already included.

For those unfortunate people who still use Windows on their main machine like me, you may use utility like Rufus to burn the image to a USB. Just pick the file and drive, make sure to choose the right one, this will overwrite all data on the USB drive.

image-1630068789500.png

Once we have the USB ready, we can plug it into the T500, press F12 and choose to boot from it. We will be greeted by this screen:

image-1630246255900.jpg

Installing OpenBSD

Full disk encryption with key (FDE)

I'm using a laptop, so it would be advisable to implement some sort of encryption in case it gets lost or someone steals it. We will follow the official guide here (with a little modification) and setup FDE with a USB drive for convenience, so that we don't have to type the encryption password every time and instead rely on the possesion of the USB drive.

Jump out of the installer into the shell by typing S

Begin the proces by creating a device node. You may be familiar with the naming convetion from Linux. sd is essentially SCSI disk driver.

# cd /dev && sh MAKEDEV sd0

We may also want to write some random data to the device, this is a fairly time consuming process, so get some coffee and do some work while it does it's thing. The bigger the drive, the longer this will take. The computer's speed also plays a big role. Wait, what is rsd0c? Haven't we just typed in sd0? Why are we writing something to rsd0c? I had the same questions, but the explanation if quite simple. R in the beginning stands for raw, as it is a raw (character) device. sd0 was already explained above (first SCSI driver device), but why c at the end? According to disklabel(5) "The ‘c’ partition is reserved for the entire physical disk". So there we have it, rsd0c points to the whole raw first hdd handled by the SCSI driver, to which we are currently writing random data.

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

Since we have a crap load of time before it finishes, let's dissect the command a little further. dd is a well known utility from the world of Linux and other UNIX-like operating systems. It can be used to copy standard input (stdin) to standard output (stdout). These two aforementioned terms usually mean "what you type" and "what you get" to/from the terminal. In this case we are using the if and of options of dd which replace stdin and stdout with files. Basically copying the contents of /dev/urandom to /dev/rsd0c. As you can tell by the fact that urandom resides in /dev, it is some kind of a device, but not a physical one. Together with random, urandom is a data source device which provides high quality pseudo-random data. Why is it called pseudo-random? Well, computers can't actually produce truly random data (but they can use realisitcally random sources), instead, the kernel utilizes all sorts of different things that are happeing at any given moment (system activity, network, hadware output) and through some programming and math trickery output seemingly random data. It is important to make sure that the same data cannot be generated again, because that could lead to security issues, since actions like generating SSH key pairs use these pseudo-random data sources. (Imagine you generate an SSH key pair and someone finds a way to get the same pseudo-random output that you got, which will result in the same SSH key pair being generated, even though I'm sure there are reasons why this isn't realistically possible). The last option bs specifies the block size (how large the blocks of data will be)

As far as I know, the T500 doesn't support UEFI, so we'll have to use MBR partitioning table. Use fdisk to initialize MBR.

  • -i uses default MBR
  • -y avoids unnecessary yes/no questions.
# fdisk -iy sd0

If you have an UEFI device, use this command:

# fdisk -iy -g -b 960 sd0

To create a partition layout, we need to enter disklabel's label editor with the -E option and name of the device we want to edit.

# disklabel -E sd0

In the Label editor, enter the following commands (// respresent comments, don't type that into the terminal)

#sd0> a a // "a" to add partition and name it "a"
offset: [64] // press enter
size: [488391056] * // "*" and enter
FS type: [4.2BSD] RAID // default is 4.2BSD, but we want to create RAID volume
sd0*> w // write changes to the disk
sd0> q // quit the editor
No label changes.

Let's stop for a moment and let me explain the naming and structure. The device that we are now working with is sd0. We have just created an a parition on sd0, which resulted in sd0a RAID type filesystem that spans across the entire disk. Now we will use RAID management interface called bioctl to create a CRYPTO volume on sd0a. This encrypted volume will appear as another device, but it's just an encryption layer on the same physical device. Afterwards we can create volumes and file systems how we want, just like with a regular OpenBSD install without encryption.

If you are using a regular passphrase, the new encrypted device will become sd1. However, since we want a keydrive, we have to account for the other USB drive. Connect the USB that you want to use to unlock your laptop/PC and note the assigned name. In my case, it got recognized as sd2. This is important, becuase now our encrypted volume won't be sd1, but sd3.

Assume the key drive is sd2 and our initial parition is still sd0.

  • -c sets the RAID level, but we just want an encryption layer, so we will use "C" which stands for CRYPTO
  • -k use key disk device sd2a
  • -l create volume on sd0a with software raid

This part took me a long time, because I got stuck on the -r option which specifies number of iterations for the KDF algorithm. What got me thinking was this article, which goes in depth into the encryption of OpenBSD. What confused me the most is that according to the bioctl man page, the default number of rounds is 16, however the author of the article mentions "The interesting part is the number of iterations which directly impact the resistance to brute force attacks. On OpenBSD, it is set to the hard-coded value of 8192. As discussed previously, this may be changed using bioctl options." If we are talking about the same thing, why the man page mentions 16 and he says 8192? Also "On my home install, my LUKS volume is configured for about 400,000 iterations, which is significantly higher than the OpenBSD default.". His closing thoughts are "If using OpenBSD on a recent computer, bump up the number of PBKDF2 iterations when creating the volume." What does bump up mean in this case? More than 10 000? 100 000? Anyway, take what you want from this, I will try 50 000 and see what happens.

# bioctl -c C -r 50000 -k sd2a -l sd0a softraid0

Well, this happened.

bioctl: could not open sd2a: No such file or directory

Of course, we don't have any sd2x devices in /dev, which we can confirm by ls /dev/. Correct that by issuing

cd /dev
sh MAKEDEV sd2

Aaaand, again we fail because:

bioctl: could not open sd2a: Device not configured

Sure, even though our key drive showed up as sd2, we haven't touched it with fdisk like we did with our sd0. If I could read, I would know since the guide clearly mentions it "Initialize your keydisk with fdisk(8), then use disklabel(8) to create a 1 MB RAID partition for the key data"

I grouped all the commands we need into the following block:

# dd if=/dev/urandom of=/dev/rsd2c bs=1m // rsd2c - our raw sd2 key drive
# fdisk -iy sd2
# disklabel -E sd2
sd2> a a // create "a" partition
offset: [64] // accept default with enter
size: [7984241] 1M // we only need a small 1M partition
FS type: [4.2BSD] RAID // again, create RAID type partition

// we can confirm that everything is ok
> p
#      size  offset  fstype [fsize bsize   cpg]
a:    16001      64    RAID
c:  7987200       0  unused

sd2*> w // write changes
sd2*> q // quit

Now we can run bioctl again

# bioctl -c C -r 50000 -k sd2a -l sd0a softraid0

You should see similar output:

image-1630246283300.jpg

Please note the volume which was created, in this case sd3, you will need it later!

This is everything we had to do in order to setup encryption. What follows is only the installation process described bellow.

Installation script

Type I to begin the installer. The system will ask you some basic information, stuff in [] is default when you press enter.

You can pick a different keyboard layout, but I will stick with the default one

Choose your keyboard layout ('?' or 'L' for list) [default]

Pick a hostname that you like

System hostname? (short form, e.g. 'foo')

We are using a minimal image file, therefore we will need internet connection to download all required file sets, so it makes sense to configure network interface. I will just connect cable to the on board LAN (em0) and let DHCP give it lease. Unless you want to configure IPv6 stick to default none

Available network interfaces are: em0 iwn0 vlan0.
Which network interface do you wish to configure? (or 'done') [em0]
IPv4 address form em0? (or 'dhcp' or 'none') [dhcp]
em0: no link...got link
em0: no lease......got lease
em0: 10.5.51.122 lease accepted from 10.1.4.1 (mac address)
IPv6 address for em0 (or 'autoconf' or 'none') [none]
Which network interface do you wish to configure? (or 'done') [done]
Using DNS domainname your.server
Using DNS nameservers at 10.6.8.77

Enter you root account, make sure it is a strong password and store it in a secure place. You will mostly interact with the system using a regular user and doas to elevate privileges. It is not a good security practice to log in with root!

Password for root account? (will not echo)
Password for root account? (again)

This isn't going to be a server, so type no to SSH

Start sshd(8) by default? [yes] no

I personally had some troubles with xenodm, but they mostly came down to me being incopetent. Using xenodm is a recommended security practice, instead of starting with startx. Not entirely sure why it's not default

Do you want the X Window System to be started by xenodm(1)? [no] yes

Setup a user that you will login with

Setup a user? (enter a lower-case loginname, or 'no') [no] user

Timezone settings. If the correct timezone wasn't selected automatically, press ? and pick a correct one and type it into the installer.

What timezone are you in? ('?' for list) [Europe/Prague]

Now make sure you install into the right volume – in our case, sd3 because it's the crypto volume.

Available disks are: sd0 sd1 sd2 sd3
Which disk is the root disk? ('?' for details) [sd0] sd3

We have a MBR machine, so pick MBR

No valid MBR or GPT
Use (W)whole disk MBR, whole disk (G)PT or (E)dit? [whole]
Setting OpenBSD MBR partition to whole sd3...done.

OpenBSD partitioning is something we will leave for another time. This time I'm going with the default which is surprisingly sane.

 

image-1630246344600.jpg

We are using a minimal instalation file, therefore we need to download required file sets from the internet - http option. We aren't using any proxy servers, so leave that at default. You can also pick a server that is closer to you or that you prefer.

Let's install the sets!
Location of sets (cd0 disk http nfs or 'done') [http]
HTTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]
HTTP Server? (hostname, list#, 'done' or '?') [ftp.eu.openbsd.org]
Server direcotry? [pub/OpenBSD/6.9/amd64]

When it comes to file sets, most of the time it is easiest to just install them all. On a headless server installation, you certainly won't need any sets beginning with x, but we are running a laptop which will need X packages for GUI. I usually leave out game69.tgz and comp69.tgz, but if you aren't constrained by limited disk space available, just leave it at default. To read more about what these file sets are, check out OpenBSD FAQ.

image-1630246400300.jpg

It will take some time to download all the file sets, but after that's done, you should see a similar screen:

image-1630246419000.jpg

Just press enter to reboot. When it shuts down, remove the installation USB drive, but keep the key drive in, otherwise it won't boot.

You will be presented this very elegant login screen.

image-1630246479300.jpg

What comes next looks even better, doesn't it?

image-1630246666100.jpg