Eric Radman : a Journal

OpenBSD Auto-install

One of the features that may be underutilized is OpenBSD's uncomplicated auto-installer. I do not mean that all of the mechanisms that need to be in place for a real-world use case are simple, but the OpenBSD parts are simple.


The first task of booting via PXE is to hand out an address and name the file to fetch over TFTP

# /etc/dhcpd.conf
subnet netmask {
    option routers;

    # T4300
    host pxe-client {
            hardware ethernet 00:1e:c9:4c:69:59;
            filename "auto_install"

The filename auto_install is not arbitrary, this causes the install script in bsd.rd to start the automated install by pulling configuration over HTTP. The complete layout for /tftpboot might look like this:

drwxr-xr-x   2 root  eradman      512 May 16 15:54 .
drwxr-xr-x  16 root  wheel       1024 May 13 01:26 ..
lrwxr-xr-x   1 root  eradman       13 May 16 15:52 auto_install -> pxeboot.amd64
lrwxr-xr-x   1 root  eradman       12 May 16 15:54 bsd -> bsd.rd.amd64
-rw-r--r--   1 root  eradman  7763412 May 13 10:07 bsd.rd.amd64
-rw-r--r--   1 root  eradman    82300 May 13 10:07 pxeboot.amd64

Per-Host Install Options

The next-server entry specified by the DHCP server points to the path where answers file can be found:

default - - [16/May/2016:15:55:54 -0400]
  "GET /00:1e:c9:4c:69:59-install.conf?path=5.9/amd64 HTTP/1.0" 200 314

The answers file contains strings which match the questions from the installer

# /var/www/htdocs/00:1e:c9:4c:69:59-install.conf
System hostname = t3400
Password for root = 123456
Network interfaces = bge0
IPv4 address for bge0 = dhcp
Setup a user = eradman
Password for user = 123456
Public ssh key for user = ssh-ed25519 XYZ123...
What timezone are you in = US/Eastern
Location of sets = http
Server =
Server directory = pub/OpenBSD/5.9/amd64

If you don't specify a line then a default will be used. If more options are available you can make further choices:

Which disk is the root disk = sd1


To make this mechanism portable I run these services from my laptop. Here is how. First I enable the hotplug daemon

# rcctl enable hotplugd

Next I create /etc/hotplug/attach to assign an address to my USB-to-Ethernet adapter when plugged in



case $DEVCLASS in
    ifconfig axe0
    daemon_flags="$DEVNAME" /etc/rc.d/dhcpd -f start
    daemon_flags="/tftp" /etc/rc.d/tftpd -f start

DEVCLASS 3 is a network interface. Similarly, /etc/hotplug/detach disables these services using the opposite actions.

Custom Sets

OpenBSD allows for custom software to be installed by adding a site-specific tgz file. If index.txt includs the new file it will appear in the menu; we only need to select the new package in *install.conf

Set name(s) = site59.tgz

To make this easy I am allowing for this one package to be installed without being signed.

Checksum test for site59.tgz failed. Continue anyway = yes
Unverified sets: site59.tgz. Continue without verification = yes


One of the most interesting files that can be installed with siteNN.tgz is /etc/rc.firsttime. This is executed the first time a system boots up in multi-user mode, and is a very convenient way to make sure some bits of essential post-install configuration occur. This example fetches and installs ports on first boot

ftp -o - | tar -zxf - -C /usr

Handling the installation of packages could be handled similarly.

Last updated on January 31, 2017