Skip to main content.

Automatic, unattended OpenBSD installs with PXE


Live demo in BSD Now Episode 032 | Originally written by TJ for | Last updated: 2014/12/16

NOTE: the author/maintainer of the tutorial(s) is no longer with the show, so the information below may be outdated or incorrect.

Since version 5.5, OpenBSD has supported an "autoinstall" feature in the installer. It uses DHCP and PXE booting to download an "answer" file that tells the installer what options to choose. For the easiest experience possible, I recommend running OpenBSD on your router. All the tools we need are in the base system. A bit of preparation is needed before we can do the actual installation. This guide assumes you have a router running on that hands out addresses via DHCP and has a webserver running on it, with the document root being /var/www/htdocs. It's not required to host the install files on the router, but it saves a lot of time and bandwidth if you have it somewhere on the LAN. The commands, although mostly generic, are all being run on OpenBSD, so adjust them to other systems if that's not what you're running. In order to boot with PXE, the DHCP server needs a few options to tell it what files to use.

# vi /etc/dhcpd.conf

We want something like this:

option domain-name-servers;
subnet netmask {
    option routers;
    filename "auto_install";
[..other stuff..]

See the previously-mentioned OpenBSD router tutorial for more information. The "filename" and "next-server" lines are the important parts here. The "filename" line tells it the name of the file to boot from over TFTP. In this case, we're going to be using a symlink to "pxeboot" called "auto_install" for booting. The "next-server" line tells it the address of our webserver, from which we'll fetch the installation instructions and sets. Be sure to restart dhcpd after making changes.

# /etc/rc.d/dhcpd restart

Now we'll set up tfpd to serve the initial files for PXE booting. It listens on UDP port 69 by default, so be sure your firewall allows that for the LAN.

# mkdir /tftp

In the directory we just made, we'll want to have two files: bsd and auto_install. In my case, I symlinked auto_install from the pxeboot file and renamed bsd.rd to bsd. Get the two files from FTP, installation media or create them yourself.

# cd /tfp
# ln -s pxeboot auto_install
# mv bsd.rd bsd
# echo 'tftpd_flags="-4 /tftp"' >> /etc/rc.conf.local
# /etc/rc.d/tftpd start
# ls -l /tftp

total 12896
lrwxr-xr-x  1 root  wheel        7 Feb 22 21:37 auto_install -> pxeboot
-rw-r--r--  1 root  wheel  6501415 Feb 22 12:49 bsd
-rw-r--r--  1 root  wheel    80524 Feb 22 12:50 pxeboot

If you need any non-standard options, you'll also need a /tftp/etc/boot.conf file. If you want to install over serial, for example, you'll need some special options for that. It's also possible to automatically install your configuration files with a "siteXX" set. Next we set up a webserver. To keep things simple, I'm just going to use OpenBSD's built-in httpd. Anything will work. We need to put the sets in /var/www/htdocs, but adhere to the standard OpenBSD release directory structure.

# ls /var/www/htdocs/pub/OpenBSD/5.5/i386/

SHA256       bsd          comp55.tgz   index.txt    xetc55.tgz   xshare55.tgz
SHA256.sig       etc55.tgz    man55.tgz    xfont55.tgz
base55.tgz   bsd.rd       game55.tgz   xbase55.tgz  xserv55.tgz

Replace "5.5" and "i386" with whatever version and architecture you're going to be using. Be sure you have all of those files and that the "index.txt" matches.

# vi /etc/httpd.conf

Add the following:

server "default" {
        listen on egress port 80
        root "/htdocs"
        directory auto index

Replace "egress" with an internal IP address if you only want it open to the LAN. Start up the webserver.

# echo 'httpd_flags=""' >> /etc/rc.conf.local
# /etc/rc.d/httpd start

Be sure to allow TCP port 80 in your firewall for the LAN. We also need a file called "install.conf" in the document root of the webserver. It answers some (or all) of the installer's questions for us. In my case, that would be something like:

# cat /var/www/htdocs/install.conf

System hostname =
Password for root = ThePlaceToBe...SD
Network interfaces = em0
IPv4 address for em0 = dhcp
Setup a user = puffy
Password for user = whywasibornasafish
What timezone are you in = US/Eastern
Location of sets = http
Server =

Most of the variables are self-explanatory. This isn't a complete list of all the customizable options, just a brief one to get you started. Now you're ready to boot your client system(s) over PXE. How you do that will vary greatly depending on the hardware. The system should get all the information it needs from the DHCP server, boot from PXE and load all the files it needs. It will automatically reboot once the installation is finished. Here's a sample installation log from one of the developers of autoinstall:

>> OpenBSD/amd64 PXEBOOT 3.22
com0: changing speed to 115200 baud in 5 seconds, change your terminal to match!

com0: 115200 baud
loadrandom: tftp:/etc/random.seed
cannot open tftp:/etc/random.seed
loadrandom: error -1
booting tftp:/bsd: 4168740+961652+2905792+0+520528 [100+338448+219658]=0xcb2918
entry point at 0x10001e0 [7205c766, 34000004, 24448b12, c588a304]
Copyright (c) 1982, 1986, 1989, 1991, 1993
        The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2014 OpenBSD. All rights reserved.

OpenBSD 5.4-current (RAMDISK_CD) #6: Thu Jan  9 01:18:28 CET 2014
real mem = 116465664 (111MB)
avail mem = 108597248 (103MB)
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xf1640 (10 entries)
bios0: vendor Bochs version "Bochs" date 01/01/2011
bios0: Bochs Bochs
acpi0 at bios0: rev 0
acpi0: sleep states S3 S4 S5
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
acpiprt0 at acpi0: bus 0 (PCI0)
mpbios at bios0 not configured
cpu0 at mainbus0: (uniprocessor)
cpu0: QEMU Virtual CPU version 1.7.0, 3183.88 MHz
cpu0: 64KB 64b/line 2-way I-cache, 64KB 64b/line 2-way D-cache, 512KB 64b/line 16-way L2 cache
cpu0: ITLB 255 4KB entries direct-mapped, 255 4MB entries direct-mapped
cpu0: DTLB 255 4KB entries direct-mapped, 255 4MB entries direct-mapped
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
"Intel 82371SB ISA" rev 0x00 at pci0 dev 1 function 0 not configured
pciide0 at pci0 dev 1 function 1 "Intel 82371SB IDE" rev 0x00: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0:
wd0: 16-sector PIO, LBA48, 2048MB, 4194304 sectors
wd1 at pciide0 channel 0 drive 1:
wd1: 16-sector PIO, LBA48, 2048MB, 4194304 sectors
wd0(pciide0:0:0): using PIO mode 4, DMA mode 2
wd1(pciide0:0:1): using PIO mode 4, DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus0 at atapiscsi0: 2 targets
cd0 at scsibus0 targ 0 lun 0:  ATAPI 5/cdrom removable
cd0(pciide0:1:0): using PIO mode 4, DMA mode 2
"Intel 82371AB Power" rev 0x03 at pci0 dev 1 function 3 not configured
vga1 at pci0 dev 2 function 0 "Cirrus Logic CL-GD5446" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
em0 at pci0 dev 3 function 0 "Intel 82540EM" rev 0x03: irq 11, address 52:54:00:12:34:56
em1 at pci0 dev 4 function 0 "Intel 82540EM" rev 0x03: irq 11, address 52:54:00:12:34:57
isa0 at mainbus0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: console
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
softraid0 at root
scsibus1 at softraid0: 256 targets
PXE boot MAC address 52:54:00:12:34:56, interface em0
root on rd0a swap on rd0b dump on rd0b
erase ^?, werase ^W, kill ^U, intr ^C, status ^T

Welcome to the OpenBSD/amd64 5.4 installation program.
Starting non-interactive mode in 5 seconds...
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell?

DHCPDISCOVER on em0 to port 67 interval 3
DHCPOFFER from (52:55:0a:00:02:02)
DHCPREQUEST on em0 to port 67
DHCPACK from (52:55:0a:00:02:02)
bound to -- renewal in 43200 seconds.
ftp: Error retrieving file: 404 Not Found
1749 bytes received in 0.00 seconds (4.57 MB/s)
Performing non-interactive install...Terminal type? [vt220] vt220
System hostname? (short form, e.g. 'foo') test1

Available network interfaces are: em0 em1 vlan0.
Which network interface do you wish to configure? (or 'done') [em0] em0
IPv4 address for em0? (or 'dhcp' or 'none') [dhcp] dhcp
Issuing hostname-associated DHCP request for em0.
DHCPREQUEST on em0 to port 67
DHCPACK from (52:55:0a:00:02:02)
bound to -- renewal in 43200 seconds.
IPv6 address for em0? (or 'rtsol' or 'none') [none] none
Available network interfaces are: em0 em1 vlan0.
Which network interface do you wish to configure? (or 'done') [done] done
Using DNS domainname my.domain
Using DNS nameservers at

Password for root account?
Public ssh key for root account? [none] none
Start sshd(8) by default? [yes] yes
Start ntpd(8) by default? [no] no
Do you expect to run the X Window System? [yes] yes
Do you want the X Window System to be started by xdm(1)? [no] no
Change the default console to com0? [no] yes
Available speeds are: 9600 19200 38400 57600 115200.
Which speed should com0 use? (or 'done') [115200] 115200
Setup a user? (enter a lower-case loginname, or 'no') [no] no
What timezone are you in? ('?' for list) [Europe/Vienna] Europe/Vienna

Available disks are: wd0 wd1.
Which disk is the root disk? ('?' for details) [wd0] wd0
Use DUIDs rather than device names in fstab? [yes] yes
Disk: wd0       geometry: 520/128/63 [4194304 Sectors]
Offset: 0       Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
 0: 00      0   0   0 -      0   0   0 [           0:           0 ] unused      
 1: 00      0   0   0 -      0   0   0 [           0:           0 ] unused      
 2: 00      0   0   0 -      0   0   0 [           0:           0 ] unused      
*3: A6      0   1   2 -    519 127  63 [          64:     4193216 ] OpenBSD     
Use (W)hole disk, use the (O)penBSD area, or (E)dit the MBR? [OpenBSD] OpenBSD
The auto-allocated layout for wd0 is:
#                size           offset  fstype [fsize bsize  cpg]
  a:           800.6M               64  4.2BSD   2048 16384    1 # /
  b:            81.1M          1639616    swap                   
  c:          2048.0M                0  unused                   
  d:           908.9M          1805824  4.2BSD   2048 16384    1 # /usr
  e:           256.8M          3667232  4.2BSD   2048 16384    1 # /home
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] a
/dev/rwd0a: 800.6MB in 1639552 sectors of 512 bytes
4 cylinder groups of 200.14MB, 12809 blocks, 25728 inodes each
newfs: reduced number of fragments per cylinder group from 32872 to 32736 to enlarge last cylinder group
/dev/rwd0e: 256.8MB in 525984 sectors of 512 bytes
5 cylinder groups of 63.94MB, 4092 blocks, 8192 inodes each
/dev/rwd0d: 908.9MB in 1861408 sectors of 512 bytes
5 cylinder groups of 202.47MB, 12958 blocks, 25984 inodes each
Available disks are: wd1.
Which disk do you wish to initialize? (or 'done') [done] done
/dev/wd0a (c95f7901f279d69d.a) on /mnt type ffs (rw, asynchronous, local)
/dev/wd0e (c95f7901f279d69d.e) on /mnt/home type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/wd0d (c95f7901f279d69d.d) on /mnt/usr type ffs (rw, asynchronous, local, nodev)

Let's install the sets!
Location of sets? (cd disk ftp http or 'done') [http] http
HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none] none
Server? (hostname, list#, 'done' or '?') []
Server directory? [ftp/pub/OpenBSD/snapshots/amd64] ftp/pub/OpenBSD/snapshots/amd64

Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-' to the set name, file name pattern or 'all'. Selected
sets are labelled '[X]'.
    [X] bsd           [X] etc54.tgz     [X] xbase54.tgz   [X] xserv54.tgz
    [X] bsd.rd        [X] comp54.tgz    [X] xetc54.tgz
    [ ]        [X] man54.tgz     [X] xshare54.tgz
    [X] base54.tgz    [X] game54.tgz    [X] xfont54.tgz
Set name(s)? (or 'abort' or 'done') [done] done
bsd          100% |*************************************| 10995 KB    00:02    
bsd.rd       100% |*************************************|  8397 KB    00:02    
base54.tgz   100% |*************************************| 62511 KB    00:33    
etc54.tgz    100% |*************************************|   513 KB    00:00
comp54.tgz   100% |*************************************| 53855 KB    00:37    
man54.tgz    100% |*************************************|  9822 KB    00:06    
game54.tgz   100% |*************************************|  2717 KB    00:01    
xbase54.tgz  100% |*************************************| 13671 KB    00:06    
xetc54.tgz   100% |*************************************| 64874       00:00    
xshare54.tgz 100% |*************************************|  4297 KB    00:04    
xfont54.tgz  100% |*************************************| 38994 KB    00:18    
xserv54.tgz  100% |*************************************| 23879 KB    00:11    
Saving configuration files...Making all device nodes...done.

CONGRATULATIONS! Your OpenBSD install has been successfully completed!
To boot the new system, enter 'reboot' at the command prompt.
When you login to your new system the first time, please read your mail
using the 'mail' command.
syncing disks... done

Didn't even need to touch a keyboard!

Latest News

New announcement


We understand that Michael Dexter, Brad Davis, and George Rosamond think there should be more real news....

Two Year Anniversary


We're quickly approaching our two-year anniversary, which will be on episode 105. To celebrate, we've created a unique t-shirt design, available for purchase until the end of August. Shirts will be shipped out around September 1st. Most of the proceeds will support the show, and specifically allow us to buy...

New discussion segment


We're thinking about adding a new segment to the show where we discuss a topic that the listeners suggest. It's meant to be informative like a tutorial, but more of a "free discussion" format. If you have any subjects you want us to explore, or even just a good name...

How did you get into BSD?


We've got a fun idea for the holidays this year: just like we ask during the interviews, we want to hear how all the viewers and listeners first got into BSD. Email us your story, either written or a video version, and we'll read and play some of them for...

Episode 281: EPYC Server battle


Direct Download:MP3 AudioVideo Headlines scp client multiple vulnerabilities Overview SCP clients from multiple vendors are susceptible to a malicious scp server performing unauthorized changes to target directory and/or client output manipulation. Description Many scp clients fail to verify if the objects returned by the scp server match those it asked for. This issue dates back to 1983 and...

Episode 280: FOSS clothing


Direct Download:MP3 AudioVideo Headlines A EULA in FOSS clothing? There was a tremendous amount of reaction to and discussion about my blog entry on the midlife crisis in open source. As part of this discussion on HN, Jay Kreps of Confluent took the time to write a detailed response — which...

Episode 279: Future of ZFS


Direct Download:MP3 AudioVideo Headlines The future of ZFS in FreeBSD The sources for FreeBSD's ZFS support are currently taken directly from Illumos with local ifdefs to support the peculiarities of FreeBSD where the Solaris Portability Layer (SPL) shims fall short. FreeBSD has regularly pulled changes from Illumos and tried to push...

Episode 278: The real McCoy


Direct Download:MP3 AudioVideo Interview - Kirk McKusick - 25 years of FreeBSD How Kirk got started in BSD, at the very beginning Predicting the Future How the code and community grew The leadership of the project, and how it changed over time UFS over the years (reading disks from 1982 in 2018) Conferences The rise and fall of...