DIY Server Part 1: Installation

Posted on 2020-02-24

This is a step-by-step guide on the process of setting up a basic, solid OpenBSD 6.6 installation, optionally with full-disk-encryption. This will be the first in a series of guides on setting up a server of your own for a website, or for web applications and services such as Nextcloud. Come and follow along!

Before you read

If you are experienced with servers, a lot of this information may seem redundant to you. I promise though, to a lot of other people it is not, so just skip the parts that you already know about!

Why OpenBSD?

Yes, you could also use a Linux distribution like Debian, but I chose to work with OpenBSD because it is fairly simple and easy to understand by comparison. After installing, you end up with a simpler system with fewer moving parts that is easier to grasp and manage. OpenBSD also comes with sensible defaults for many of its applications and good documentation.

I have worked with Debian and use it on my personal laptop, but I found OpenBSD significantly less confusing, which is why I decided to focus on learning to work with that instead. Your experience may vary, and thankfully there are countless guides for Debian made by others already which you are free to read instead. :)

What do "$" and "#" mean?

A command that starts with "#" is run as root, a command starting with "$" is run as regular user. As this is merely done for visual clarity, do not actually type these characters, just the command that follows! (And don't worry if you do not understand all the fancy words yet, just follow along with each command and you will be okay)

What you need

Before we get to the steps, we need to talk about what we are working with:

In the case of this site, it is running on a VPS (Virtual Private Server) by 1fire Hosting, but if you have some hardware at home like an old laptop or a single board computer (SBC, example) and an internet connection that would enable you to reach your hardware from the outside world, then you might want to use that instead. To prepare for the rest of the guide, you should go through the following steps (but read them all before you start!):

1. Make sure your server can run OpenBSD

You might only know this for sure once you actually try to boot it up, but you should at least make sure that your device platform is supported by OpenBSD.

2. Make sure you can reach your server from the outside world

VPS usually come with a static IP address, but in the case of having hardware at home, things are less straightforward. Domestic internet providers often do not hand out static IP addresses, so you might have a dynamic (periodically changing) IP address which you will need to account for in your domain setup. This process is beyond the scope of this article though and can depend on where you bought your domain. If you would like to learn more about this, search online for the keyword "Dynamic DNS".

3. Obtain OpenBSD

This process differs depending on whether you are using a VPS or a physically accessible server.

In the case of a VPS:

Make sure that you have root access on your server, which allows you to do whatever you want to the (virtual) disks. It would be best if you are able to mount ISO files as CD drives through the management interface (as in our case with 1fire Hosting); if you do not have this, make sure there is some sort of minimal rescue system that would allow you to download the necessary files and write them to the disk(s). In either case, obtain the full ("installXX") or mini ("cdXX") ISO file for your architecture from here. Either mount it through your management interface, or if you just have a rescue system availible, do the following after booting into it:

First, download the ISO file. At the time of writing this article, the most recent version of OpenBSD is 6.6. Please adjust the URL to the most recent version for your architecture linked on the OpenBSD site! In this case I am using the smaller "cd" version since rescue systems often don't have much space availible:

wget https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/cd66.iso

Then check for the disk that you will flash the ISO file to. If this does not work for some reason, try to figure out how to show all disks for your rescue system by contacting your VPS provider!

lsblk

This will have made a list of stuff show up on screen. By looking at the sizes of the disks, you can likely figure out which of them is the system's main disk. Note down the name (eg. "vda" or something similar), because that is the device you will write the ISO file to:

dd if=<name_of_the_file_you_downloaded>.iso of=/dev/<the_name_you_noted_down> bs=1M status=progress

The above command takes the file you downloaded as the input file ("if") and writes its contents to the output file ("of"), in this case your disk. Hint: If you are not sure about the name of the file you downloaded, use the ls command!

In the case of a physical device:

You can download the most recent version of OpenBSD and write it to an USB stick or SD card that you can boot up on your hardware. If you are on Windows, you can use a graphical tool like Rufus; if you are on Linux, you can use the inbuilt dd command. First, open a terminal, then go through the following:

Navigate to the place where you downloaded the ISO file

cd /home/my_username/Downloads

Determine the USB drive or SD card you want to write the file to:

lsblk

This will have made a list of stuff show up on screen. By looking at the sizes of the disks, you can likely figure out which of them is your USB or SD card. Note down the name (eg. "sdb" or something like that), because that is the device you will write the ISO file to. Make sure you get this right, this will erase the data on that device!

sudo dd if=<name_of_the_file_you_downloaded>.iso of=/dev/<name_of_device_you_noted_down> bs=1M status=progress && sudo sync

When that is done, just remove your USB/SD and insert it in the server!

Now that we are done with that, it's finally time to start up OpenBSD!

4. Boot OpenBSD

Now with your USB/SD card attached to your device or your ISO mounted/written to a drive on your VPS, you need to start it up and boot from the device that contains OpenBSD. For this purpose there may be a boot screen that allows you to select a boot device. Once everything has loaded up, you should arrive at a prompt asking you whether you want to install, upgrade, autoinstall or open a shell.

If you do not get to this prompt and instead end up with a black screen, OpenBSD either failed to boot on your device or does not have the graphics driver required to use your video output. The latter was the case for a SBC I had tried, which forced me to use a USB serial cable instead. On an old laptop of mine it worked just fine though, so your results may vary here.

If OpenBSD does not boot at all, this could be down to not properly following the previous steps, or because there are additional steps necessary (eg. with my OLinuXino Lime2 SBC which needs additional steps due to U-Boot). Since I can't possibly cover all cases in this guide, please try to search online or just contact me if you are stuck here.

Installing OpenBSD

You managed to boot OpenBSD, so it will only get easier from here onwards!

When installing OpenBSD, you might want to install the system to a fully encrypted partition of your disk. This may be valuable for some cases, but the protection provided by full disk encryption is not absolute. Here are some things to consider when choosing whether you want or need this:

But there are cases in which it may protect you, such as when your server gets stolen or confiscated and gets powered down in the process, since the attacker will have to unlock the system before gaining access to your data.

Since full disk encryption can thus be a useful protection in home server setups, I will explain how to set up full-disk-encryption on OpenBSD in the following section. If you are not interested in encrypting your disk, just skip ahead to the main installation!

Full Disk Encryption

The following is largely copied (but partially adapted) from the official OpenBSD FAQ (which by the way is a great resource for more information).

At the install prompt that you booted to, type "s" for "Shell" and press enter to get a shell. To make things easier, I like to first set the right locale for my keyboard, as I do not use the US layout. You can list the availible keyboard layouts with kbd -l; if the list is too big for your screen you can pipe the output into less, like so:

# kbd -l | less

You can scroll this view with the arrow buttons and quit by pressing "q" on your keyboard. Once you have determined the correct keyboard layout, you can set it with kbd <layout_name>, in my case the German layout with no dead keys:

# kbd de.nodead

Now we can set up the device nodes (don't worry, you don't need to understand this at this point):

# cd /dev && sh MAKEDEV sd0

You may want to write random data to the disk first with something like the following:

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

Depending on your CPU speed and disk speed and size, this can take a long time. So grab some food, go out for a walk, you probably need a break now anyway. :)

Once all that is done, we can initialize the disk and set up the softraid partition that will be encrypted:

# fdisk -iy sd0

# disklabel -E sd0
Label editor (enter '?' for help at any prompt)
sd0> a a			
offset: [64]
size: [39825135] *
FS type: [4.2BSD] RAID
sd0> w
sd0> q
No label changes.

Now we can build the encrypted device on our "a" partition. When prompted, type in your super long and secure yet memorable passphrase. This will be the passphrase used to decrypt the encrypted partition at boot!

# bioctl -c C -r auto -l sd0a softraid0
New passphrase:
Re-type passphrase:
sd1 at scsibus2 targ 1 lun 0: <OPENBSD, SR CRYPTO, 005> SCSI2 0/direct fixed
sd1: 19445MB, 512 bytes/sector, 39824607 sectors
softraid0: CRYPTO volume attached as sd1

As the last line states, our encrypted volume is now attached as sd1, so let's make sure we can use it:

# cd /dev && sh MAKEDEV sd1

I don't understand this part myself, but the OpenBSD FAQ says to do this, so let's overwrite the first megabyte of our new partition with zeros:

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

And we are done! Now you can type exit, which will bring you back to the installation prompt, from where we will finally begin the installation!

Main Installation

Throughout the installation I will show most of the prompt and my answer, with a short description of what it means and what you should put there.

First, we are at the initial prompt after booting up, where we will enter i to install:

Welcome to the OpenBSD/amd64 6.6 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? i

Then we get to pick our keyboard layout, in my case de.nodead:

Choose your keyboard layout ('?' or 'L' for list) [default] L
Availible layouts: ...
Choose your keyboard layout ('?' or 'L' for list) [default] de.nodead

Now we pick our system hostname. This is a short name you assign to your machine; when setting up a mail server you may call it "mail", when setting up a blog you may call it "blog", when setting up a cloud you can call it "cloud", you get the idea.

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

Now we get to configure our network interfaces, usually the default that OpenBSD detects is the one you want to configure. If you do not have/want an IPv6 address, leave that at none. Since I use IPv6, I type autoconf at the IPv6 prompt:

Available network interfaces are: em0 vlan0.
Which network interface do you wish to configure? (or 'done') [em0]
IPv4 address for em0? (or 'dhcp' or 'none') [dhcp]
em0: 123.456.543.210 lease accepted from blah blah
IPv6 address for em0? (or 'autoconf' or 'none') [none] autoconf
Which network interface do you wish to configure? (or 'done') [done]

Now we get to pick our DNS domain name. This should be the domain name you own, in my case earthroot.city:

DNS domain name? (e.g. 'example.com') [my.domain] earthroot.city
Using DNS nameservers at blah blah

We will then set up our accounts, starting with root, which we will disable later:

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

Now we let the SSH daemon start by default, which will allow us to connect to our system remotely once it is unlocked. Since we are just running a server, we will not run the X Window System. We will set up a user, in my case I call it admin since the user will in practice be the admin account of the server. You can name it whatever you want though. :)

Start sshd(8) by default? [yes]
Do you expect to run the X Window System? [yes] no
Setup a user? (enter a lower-case loginname, or 'no') [no] admin
Full name for user admin? [admin]
Password and stuff

We will disable root ssh login, since we will only be using the user account we just created to manage the system:

WARNING: root is targeted by password guessing attacks, pubkeys are safer.
Allow root ssh login? (yes, no, prohibit-password) [no]
What timezone are you in? [Europe/Berlin]

Now we move on to installing the system. If you previously created an encrypted partition, you should see it and type its name here! The name is the mountpoint of the CRYPTO volume mentioned earlier, in my example from earlier it was sd1!

Available disks are: sd0
Which disk is the root disk? ('?' for details) [sd0]
No valid MBR or GPT.
Use (W)hole disk MBR, whole disk (G)PT or (E)dit? [whole]
Setting OpenBSD MBR partition to whole sd0...done.
The auto-allocated layout for sd0 is:
.
.
. (too lazy to type all this)

At this point we need to make one change, because the automatic layout has a relatively large /home partition while having a comparatively small var partition. Since our /var partition will be where our website (and potentially Nextcloud etc.) is, we want to switch these two around, as we will need the space in /var. There is probably a more elegant solution to this, but I am not very familiar with BSD partitioning, so I will literally just switch the two mount points around:

Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] e
sd0> 

Now we will first pick a different mountpoint for the e partition that is currently /var, so that we can set the k partition to be /var instead and then set e to be /home(I know, took me a second too):

sd0> n e
mount point: [/var] /butt
sd0> n k
mount point: [/home] /var
sd0> n e
mount point: [/butt] /home
sd0> w
sd0> q

Now even the installer is getting enthusiastic! The "sets" mentioned contain all the system applications, libraries and manual pages. We will install the sets from HTTP since some of us may have had to download the minimal ISO that does not include them. You can list all mirrors and pick one in your region:

Let's install the sets!
Location of sets? (cd0 disk http nfs or 'done') [cd0] http
HTTP proxy URL? [none]
HTTP Server? (hostname, list#, 'done' or '?') ?
...
HTTP Server? (blah blah) 18
HTTP Server? (blah blah) [mirror.hs-esslingen.de]
Server directory? [pub/OpenBSD/6.6/amd64]

...

Set name(s)? (or 'abort' or 'done') [done]

...and everything is getting downloaded and installed. Now all that is separating you from a running server is (hopefully) just a few minutes!

.
.
.
Installing blah blah 100%
Location of sets? (cd0 disk http nfs or 'done') [done]
Time appears wrong. Set to 'blah blah'? [yes]
.
.
.
CONGRATULATIONS! Your OpenBSD install has been successfully completed!
...
Exit to (S)hell, (H)alt or (R)eboot? [reboot]

At this point (if applicable) unplug your USB stick or other installation media and your system will reboot into a brand new install of OpenBSD!

First Steps for a Solid System

All that is left for us to do is finishing touches now:

First, we need to set up doas, which is the OpenBSD equivalent to sudo on other systems. doas allows us to execute commands with root privileges or get into a root shell without actually being logged in as root, which is generally good for security. The example configuration at /etc/examples/doas.conf already offers a secure setup, so we will just copy it to the right place:

# cp /etc/examples/doas.conf /etc

To test whether this worked, we can SSH into our user account and use doas to get into a root shell.

First, from your home computer or laptop, use SSH to log in (of course replace username and IP address with the username we created during installation and the IP address of your server):

home$ ssh admin@123.456.543.210

After Trusting the fingerprint you will need to enter the password for the user, and you will be logged in. Now we will enter a root shell:

$ doas -s
doas (admin@your.domain.here) password:
# 

Great, it worked! Now we will just disable the root account and apply security patches and then we are done for today!

# usermod -p'*' root
# syspatch
# reboot

If you would like, you can use your keys to log into your server instead of typing your password every time. The key of your laptop can be installed to the server by running the following:

home$ ssh-copy-id admin@123.456.543.210

After going through the procedure, you should now be able to securely log in without a password by using ssh admin@123.456.543.210.

That's all!

If you want to search the manual pages to learn more about commands, you can use man -k <search_term>. It may for example be worth reading through man afterboot for a start! Or maybe man man if you want to read the manual about how to use the manual first ;)

If you have any questions or suggestions, you can email me here.