Run an outdated cluster with diskless OpenBSD and cute little green boxes (part 3)

In the previous part, we set up DHCP, TFTP and RARP servers and successfully booted the OpenBSD ramdisk install kernel on old Soekris hardware over the network from a repurposed Cisco IDS. In the last part of this series, we will add NFS shares to the mix and install OpenBSD to them, making our PXE clients fully functional and then set up a minimal router and a caching DNS to provide our clients with working internet access.

To set up NFS, we must first figure out where we want our shares to be located. Contrary to today’s common practices, OpenBSD still uses a multitude of partitions for different parts of the root filesystem, so we first need to figure out where the most space is available.

To do that, connect to the IDS at 9600 baud, log in as root and run “df -h”

OpenBSD/i386 (delta.Home) (tty00)
login: root
Last login: Mon Dec 31 18:30:15 on tty00
OpenBSD 6.4 (GENERIC) #926: Thu Oct 11 13:43:06 MDT 2018
Welcome to OpenBSD: The proactively secure Unix-like operating system.
Please use the sendbug(1) utility to report bugs in the system.
Before reporting a bug, please try to reproduce it with the latest
version of the code. With bug reports, please try to ensure that
enough information to reproduce the problem is enclosed, and if a
known fix for it exists, include that as well.
You have new mail.
delta# df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/wd0a 1005M 57.3M 897M 6% /
/dev/wd0k 72.6G 2.0K 69.0G 0% /home
/dev/wd0d 3.9G 10.0K 3.7G 0% /tmp
/dev/wd0f 2.0G 606M 1.3G 32% /usr
/dev/wd0g 1005M 164M 790M 17% /usr/X11R6
/dev/wd0h 16.0G 5.7M 15.2G 0% /usr/local
/dev/wd0j 5.9G 2.0K 5.6G 0% /usr/obj
/dev/wd0i 2.0G 2.0K 1.9G 0% /usr/src
/dev/wd0e 4.9G 26.0M 4.6G 1% /var

It is clear that the biggest partition available is mounted at /home, which is usualy used for users’ home directories. As this is a server environment, there are currently no users (besides root, of course), so we will make use of the /home partitions to house our NFS shares.

We will start by making three directories under /home, named after our client’s hostnames: earth, wind and fire. Then, we will change their file permissions to 777 (anybody can do anything) just to make sure that clients don’t get denied access to their root filesystem.

delta# cd /home
delta# mkdir earth wind fire
delta# ls -l
total 12
drwxr-xr-x 2 root wheel 512 Jan 2 15:01 earth
drwxr-xr-x 2 root wheel 512 Jan 2 15:01 fire
drwxr-xr-x 2 root wheel 512 Jan 2 15:01 wind
delta# chmod -R 777 *
delta# ls -l
total 12
drwxrwxrwx 2 root wheel 512 Jan 2 15:01 earth
drwxrwxrwx 2 root wheel 512 Jan 2 15:01 fire
drwxrwxrwx 2 root wheel 512 Jan 2 15:01 wind

The next file that we need to modify is /etc/exports. This file configures the NFS server to serve or ‘export’ the created folders. Edit the file to look like this:

/home/earth -maproot=root -alldirs earth
/home/wind -maproot=root -alldirs wind
/home/fire -maproot=root -alldirs fire

Next file on our list is /etc/bootparams, which configures the bootparamd server. This server is somewhat undocumented in my opinion, but is crucial to the boot process because it points the freshly-booted kernel to its NFS share.

earth root=
wind root=
fire root=

Installing OpenBSD into the NFS shares

There is no official way of installing OpenBSD into a NFS share, so we will have to improvise by dissecting and manually executing tasks that the installer usually does for us.

Downloading and installing the packages

The simplest and most straightforward step when installing OpenBSD is downloading the tarball packages available at the mirrors and extracting them into the root directory. To simplify the process, I have written a shell script named (Net Root GENerator) that downloads the required packages and installs them into the current directory. Paste it into a file named and then copy it into the separate root directories:

delta# ls
earth fire wind
delta# pwd
delta# cat >

# nrgen - NFS Root Generator
# This program generates a new diskless filesystem for OpenBSD
# This shell script was written by Kristjan Komlosi
# Released under 3-clause BSD License

ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/base*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/comp*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/man*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/xbase*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/xshare*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/xfont*.tgz"
ftp -V "${FTPSERVER}:${FTPATH}/${VERSION}/${ARCH}/bsd"

for i in *.tgz
echo -n "Processing $i..."
tar -xzpf $i
rm $i
echo 'Done!'


echo -n "Copying tgzs from var/sysmerge..."
cp /var/sysmerge/*.tgz .
echo 'Done!'
for i in *.tgz
echo -n "Processing $i..."
tar -xzpf $i
echo 'Done!'
rm $i
cd dev
cd ..

delta# chmod +x
delta# cp earth/
delta# cp wind/
delta# cp fire/

Then go into the first directory and run the script.

delta# cd earth
delta# ./
base64.tgz 100% |*************************************| 152 MB 00:19
comp64.tgz 100% |*************************************| 59013 KB 00:08
man64.tgz 100% |*************************************| 7087 KB 00:01
xbase64.tgz 100% |*************************************| 16481 KB 00:03
xshare64.tgz 100% |*************************************| 4432 KB 00:01
xfont64.tgz 100% |*************************************| 39342 KB 00:06
bsd 100% |*************************************| 12978 KB 00:02
Processing base64.tgz...Done!
Processing comp64.tgz...Done!
Processing man64.tgz...Done!
Processing xbase64.tgz...Done!
Processing xfont64.tgz...Done!
Processing xshare64.tgz...Done!
Copying tgzs from var/sysmerge...Done!
Processing etc.tgz...Done!
Processing xetc.tgz...Done!

With that, the programs and the main portion of OpenBSD are installed. However, this is not the end…

Configuring the system

Before our system becomes functional, we need to configure the crucial configuration files in /etc. So cd to etc and start editing the config files:

delta# pwd
delta# cd etc
delta# ls
X11 group monthly rc.d
acme hotplug motd rmt
acme-client.conf iked mtree rpc
amd isakmpd netstart services
authpf ksh.kshrc newsyslog.conf shells
changelist ldap npppd signify
daily localtime ntpd.conf skel
disktab locate.rc passwd spwd.db
dumpdates login.conf pf.conf ssh
examples magic pf.os ssl
fbtab mail ppp syslog.conf
firmware mail.rc protocols termcap
fonts mailer.conf pwd.db ttys
ftpusers master.passwd rc weekly
gettytab moduli rc.conf
delta# echo earth > myname
delta# echo > mygate
delta# echo dhcp > hostname.sis0

These commands set the system hostname, the gateway’s IP, and configure the network interface to use DHCP for IP configuration.

The next file to configure is /etc/ttys, where we enable serial console login. Search for the line

tty00   "/usr/libexec/getty std.9600"   unknown off

And change it to read:

tty00   "/usr/libexec/getty std.19200"  vt220   on  secure

The last file to edit is /etc/fstab, where we configure the NFS mount point. / nfs rw 0 0

Rinse and Repeat

Now that earth is configured, you must repeat the same steps for wind and fire. Pay attention to the file contents and modify hostnames and paths to match the host you’re working on. My recommendation is that you copy the files from the first, finished root and modify myname and fstab.

Boot time!

Edit  /var/tftpboot/etc/boot.conf to read:

stty com0 19200
set tty com0
boot bsd

Then enable the servers:

delta# rcctl enable bootparamd portmap nfsd mountd
delta# rcctl enable dhcpd tftpd
delta# rcctl set mountd flags /etc/exports

And reboot the server. After it reboots, turn a client on:

comBIOS ver. 1.28  20050527  Copyright (C) 2000-2005 Soekris Engineering.


0064 Mbyte Memory CPU 80486 133 Mhz

Slot Vend Dev ClassRev Cmd Stat CL LT HT Base1 Base2 Int
0:00:0 1022 3000 06000000 0006 2280 00 00 00 00000000 00000000
0:18:0 100B 0020 02000000 0107 0290 00 3F 00 0000E001 A0000000 10

1 Seconds to automatic boot. Press Ctrl-P for entering Monitor.

NSC DP83815/DP83816 Fast Ethernet UNDI, v1.03
Copyright (C) 2002, 2003 National Semiconductor Corporation
All rights reserved.

Pre-boot eXecution Environment PXE-2.0 (build 082)
Copyright (C) 1997-2000 Intel Corporation

CLIENT MAC ADDR: 00 00 24 C4 55 78
probing: pc0 com0 com1 pci pxe![2.1] mem[639K 63M a20=on]
net: mac 00:00:24:c4:55:78, ip, server
>> OpenBSD/i386 PXEBOOT 3.30
>> OpenBSD/i386 PXEBOOT 3.30
booting tftp:bsd: 9116159+2212868+188424+0+1097728 [708033+98+519392+539880]=0xdb9a04
entry point at 0x2000d4

[ using 1767940 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
Copyright (c) 1995-2018 OpenBSD. All rights reserved.

OpenBSD 6.4 (GENERIC) #926: Thu Oct 11 13:43:06 MDT 2018
real mem = 66600960 (63MB)
avail mem = 50388992 (48MB)
warning: no entropy supplied by boot loader
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: date 20/50/27, BIOS32 rev. 0 @ 0xf7840
pcibios0 at bios0: rev 2.0 @ 0xf0000/0x10000
pcibios0: pcibios_get_intr_routing - function not supported
pcibios0: PCI IRQ Routing information unavailable.
pcibios0: PCI bus #0 is the last bus
bios0: ROM list: 0xc8000/0x9000
cpu0 at mainbus0: (uniprocessor)
cpu0: AMD Am486DX4 W/B or Am5x86 W/B 150 ("AuthenticAMD" 486-class), 04-09-04
cpu0: FPU
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
elansc0 at pci0 dev 0 function 0 "AMD ElanSC520 PCI" rev 0x00: product 0 stepping 1.1, CPU clock 133MHz, reset 0
gpio0 at elansc0: 32 pins
sis0 at pci0 dev 18 function 0 "NS DP83815 10/100" rev 0x00, DP83816A: irq 10, address 00:00:24:c4:55:78
nsphyter0 at sis0 phy 0: DP83815 10/100 PHY, rev. 1
isa0 at mainbus0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: console
com1 at isa0 port 0x2f8/8 irq 3: ns16550a, 16 byte fifo
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard
wdc1 at isa0 port 0x170/8 irq 15
wd0 at wdc1 channel 0 drive 0: <064MB ATA Flash Disk>
wd0: 1-sector PIO, LBA, 61MB, 125056 sectors
wd0(wdc1:0:0): using BIOS timings
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
scsibus2 at softraid0: 256 targets
PXE boot MAC address 00:00:24:c4:55:78, interface sis0
nfs_boot: using interface sis0, with revarp & bootparams
nfs_boot: client_addr=
nfs_boot: server_addr= hostname=earth
root on
WARNING: clock time much less than file system time
WARNING: using file system time
nfs_boot: bootparam get swap: 60
WARNING: no swap
Automatic boot in progress: starting file system checks.
setting tty flags
pf enabled
starting network
WARNING: /etc/hostname.sis0 is insecure, fixing permissions.
sis0: bound to from (00:1a:a2:a4:64:bb)
dd: /var/db/host.random: No such file or directory
chmod: /var/db/host.random: No such file or directory
openssl: generating isakmpd/iked RSA keys... done.
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
starting early daemons: syslogd pflogd ntpd.
starting RPC daemons:.
savecore: no core dump (no dumpdev)
acpidump: Can't find ACPI information
checking quotas: done.
clearing /tmp
kern.securelevel: 0 -> 1
creating runtime link editor directory cache.
preserving editor files.
starting network daemons: sshd smtpd sndiod.
starting local daemons: cron.
Wed Jan 2 09:10:07 MST 2019

OpenBSD/i386 (earth) (tty00)

Perfect! The client boots! Log in as root and leave password blank.

After boot

There are some recommended maintenance steps that you should do after logging into a newly installed machine, and that is to change the root password and allow root SSH login, since you won’t be able to access your computer from the network otherwise, because root is the only user on it.

earth# passwd root
Changing password for root.
New password:
Retype new password:
earth# echo PermitRootLogin yes >> /etc/ssh/sshd_config

After that, your client is ready to do whatever you want!

Just add internet!

For clients to use the internet, we need to configure Unbound the DNS server and add it to DHCP, and enable routing. First: /var/unbound/etc/unbound.conf. Edit the interface line to say


and change the line to say

access-control: allow

enable and start unbound:

rcctl enable unbound
rcctl start unbound

Edit /etc/dhcpd.conf to say:

subnet netmask {
group {
filename "pxeboot";
option routers;
option domain-name-servers;

host earth {
hardware ethernet 00:00:24:C4:55:78;

host wind {
hardware ethernet 00:00:24:C4:56:18;

host fire {

and restart dhcpd

rcctl restart dhcpd

edit /etc/pf.conf and add to the end of the file

pass out on egress from (fxp1:network) to any nat-to egress

And enable forwarding with:

echo net.inet.ip.forwarding=1 > sysctl.conf

Reboot and the cluster master shall also become a complete gateway for the clients.

Where to next?

Now that everything works in order, we can put these small servers to work. I found out that they work surprisingly well as small HTTP servers or wireless access points. However, the processing capabilities are very weak for today’s standards, so don’t count on anything complicated.

One way or another, I love breathing new life into deprecated hardware and I hope that somebody finds this guide useful, as I have initially experienced many problems with diskless OpenBSD, and I definitely know the feel of having to get things done without a proper tutorial or even some guidelines. Anyways, I hope that you’ve enjoyed this series as much as I have and stay tuned for other posts.


Author: kristjank

I run this site!

Leave a Reply

Your email address will not be published. Required fields are marked *