OpenBSD Handbook

    Theme
    • Part I. Install & Configure
      • Introduction
      • Installing OpenBSD
      • The X Window System
      • Networking
      • System Configuration
      • OpenBSD Basics
      • Managing Software: Packages and Ports
    • Part II. Daily Operations
      • Graphical Environments
      • Multimedia
      • Printing
      • Linux Compatibility
      • Windows Compatibility
      • Games
    • Part III. System Administration
      • Virtualization
      • Storage and File Systems
      • Updating and Upgrading
      • Localization
      • The OpenBSD Boot Process
      • Security
    • Part IV. Networking & Daemons
      • Services
        • Database
          • MariaDB
          • PostgreSQL
          • Redis
          • memcached
        • Directory
          • YP (NIS)
          • LDAP
        • File
          • NFS
          • Samba
        • FTP Services
          • ftpd
          • ProFTPD
          • vsftpd
          • Pure-FTPd
          • TFTP
        • Mail
          • smtpd
          • Dovecot
          • Postfix
          • Exim
          • Rspamd
        • Name
          • Unbound
          • NSD
          • BIND
        • Networking
          • OpenBGPD
          • rad
          • DHCP
          • slaacd
        • Web
          • Apache
          • nginx
          • httpd
          • relayd
        • Logging
          • syslogd
        • Monitoring
          • SNMP
        • Remote Access
          • Audit OpenSSH
          • sshd
        • File Synchronization
          • rsync
        • Messaging
          • RabbitMQ
        • Time
          • NTP
      • PF
        • pfctl cheat sheet
        • PF Anchors
        • PF Filter Rules
        • PF Forwarding
        • PF Lists and Macros
        • PF Load Balancing
        • PF Logging
        • PF NAT
        • PF Options
        • PF Policies
        • PF Shortcuts
        • PF Tables
      • Advanced Networking
        • High Availability and State Replication
        • Multi-WAN and Policy-Based Routing
        • VPN and Cryptographic Tunneling
        • Classic and Lightweight Tunnels
        • IPv6 at Scale
        • QoS and Traffic Shaping
        • MPLS and Label Distribution
        • Network Services at Scale
        • Virtualization and Host Networking
        • Large-Scale L2 and L3 Design
        • Telemetry, Logging, and Flow Export
        • Hardening and Operational Safety
        • Reference Architectures
        • Troubleshooting Playbooks
      • Serial Communication
    • Part V. Miscellaneous
      • Virtualization Cheat Sheet
      • OpenBSD Cheatsheet
      • How-to Guides
        • Complete the First 30 Minutes After Installation
        • Check Hardware Compatibility Before Installing
        • Bootstrap Wi-Fi Firmware Without Ethernet
        • Set Up OpenBSD as a Laptop or Workstation
        • Configure Laptop Power Management
        • Run OpenBSD as a Virtual Machine Guest
        • Install OpenBSD on a VPS or Cloud Server
        • Install OpenBSD with Full-Disk Encryption
        • Troubleshoot Web Browsers on OpenBSD
        • Create an Administrator Account with doas and SSH Keys
        • Establish a Conservative Security Baseline
        • Manage OpenBSD with Ansible
        • Recover Access and Reset the Root Password
        • Collect OpenBSD Diagnostic Evidence
        • Configure Secure Remote Access with OpenSSH
        • Set Up WordPress
        • Build Third-Party Software from Ports
        • Use FIDO Security Keys with OpenSSH
        • Build OpenBSD from Source
        • Configure Wi-Fi Roaming and Wired Failover
        • Dual-Boot OpenBSD on a UEFI System
        • Troubleshoot PF, NAT, and Routing
        • Automate OpenBSD Installation with Autoinstall and PXE
        • Route Multiple VLANs with PF
        • Configure a Road-Warrior WireGuard VPN
        • Troubleshoot Package Installation and Update Failures
        • Route IPv6 Networks without NAT
        • Schedule Recurring Maintenance
        • Plan a Docker Workload Migration to OpenBSD
        • Build a Mail Server with OpenSMTPD, Dovecot, and Rspamd
        • Build a Simple Router and Firewall
        • Monitor an OpenBSD System
        • Back Up and Restore an OpenBSD System
        • Configure softraid RAID1
        • Recover an OpenBSD System That Does Not Boot
        • Install Z shell (zsh)
      • OpenBSD for Linux Users
      • OpenBSD for FreeBSD Users
      • OpenBSD for macOS Users
    • OpenBSD FAQ
    • Package Search
      • Synopsis
      • Define the Provisioning Boundary
      • Obtain and Verify the Boot Files
      • Prepare TFTP
      • Publish the Response File through HTTP
      • Create a Host-Specific Response File
      • Configure the PXE Client Record
      • Restrict Provisioning Traffic with PF
      • Perform a Staged Installation
      • Validate and Retire Provisioning Access

      Automate OpenBSD Installation with Autoinstall and PXE

      Synopsis #

      autoinstall(8) answers installer questions from a response file. A network-booted amd64 client normally obtains an address and boot metadata through DHCP, loads pxeboot and bsd.rd through TFTP, and retrieves a host-specific or generic response file through HTTP.

      An unattended installer can erase a disk and a response file can contain authentication material. Build this workflow only on a controlled provisioning network, identify every client by verified hardware information, and retain console access until the installed system has been validated.

      Define the Provisioning Boundary #

      This example uses an OpenBSD provisioning server at 192.0.2.10 and one amd64 client with MAC address 00:11:22:33:44:55. The documentation address must be replaced with an address on an isolated deployment network.

      The provisioning server provides:

      • DHCP metadata that selects the client and names auto_install;
      • TFTP access to pxeboot, bsd.rd, and the auto_install link;
      • HTTP access to a response file;
      • optional access to release sets or a site79.tgz file.

      Do not expose the response service to the Internet or to an untrusted user network. Remove or disable provisioning records after the installation window.

      Obtain and Verify the Boot Files #

      Use the release directory that matches the intended architecture and obtain SHA256.sig, bsd.rd, and the architecture’s PXE boot program. Verify the signed file list with signify(1) before publishing any boot file.

      For OpenBSD 7.9, the installed release key is named openbsd-79-base.pub. The version shortcodes are not expanded inside code blocks, so replace XX below with the current two-digit release token:

      $ ftp https://cdn.openbsd.org/pub/OpenBSD/RELEASE/amd64/SHA256.sig
        # Fetch the signed file list for the selected release
      $ ftp https://cdn.openbsd.org/pub/OpenBSD/RELEASE/amd64/bsd.rd
        # Fetch the installer kernel
      $ ftp https://cdn.openbsd.org/pub/OpenBSD/RELEASE/amd64/pxeboot
        # Fetch the amd64 PXE bootstrap
      $ signify -C -p /etc/signify/openbsd-XX-base.pub -x SHA256.sig bsd.rd pxeboot
        # Verify both files before publishing them
      

      RELEASE and XX are placeholders. Do not combine files from different releases or architectures.

      Prepare TFTP #

      Create the TFTP root, install the verified files, and create the special link described by autoinstall(8):

      # install -d -o root -g wheel -m 755 /tftpboot
        # Create the TFTP root
      # install -o root -g wheel -m 644 bsd.rd pxeboot /tftpboot/
        # Publish the verified installer and boot program
      # ln -s pxeboot /tftpboot/auto_install
        # Make the DHCP filename invoke autoinstall after PXE boot
      # install -d -o root -g wheel -m 755 /tftpboot/etc
        # Create the boot-loader configuration directory
      # printf '%s\n' 'boot tftp:bsd.rd' > /tftpboot/etc/boot.conf
        # Make pxeboot load the installer kernel rather than its default bsd path
      # chmod 644 /tftpboot/etc/boot.conf
        # Make the configuration publicly readable through TFTP
      

      Current OpenBSD runs tftpd(8) as a persistent daemon. Bind it to the provisioning address and make /tftpboot its served directory:

      # rcctl set tftpd flags -l 192.0.2.10 /tftpboot
        # Restrict TFTP to the provisioning address and directory
      # rcctl enable tftpd
        # Enable the dedicated service for the installation window
      # rcctl start tftpd
        # Start the configured service
      # rcctl check tftpd
        # Confirm that it remains running
      

      TFTP has no authentication and serves publicly readable files to every reachable client. Publish only the required boot files, keep uploads disabled, and enforce the provisioning boundary with PF.

      This pxeboot path requires client firmware capable of loading the amd64 PXE bootstrap. UEFI-only network boot uses a different firmware and boot-file workflow and is outside this guide.

      Publish the Response File through HTTP #

      Create a dedicated document root within the httpd(8) chroot:

      # install -d -o root -g www -m 750 /var/www/autoinstall
      

      Use a server block restricted to the provisioning address:

      server "autoinstall" {
          listen on 192.0.2.10 port 80
          root "/autoinstall"
          log access "autoinstall-access.log"
          log error "autoinstall-error.log"
      }
      

      Parse the complete httpd.conf(5) file before reloading it:

      # httpd -n
        # Validate the complete configuration
      # rcctl enable httpd
        # Enable httpd for the controlled installation window
      # rcctl start httpd
        # Start the validated service
      

      Create a Host-Specific Response File #

      When DHCP supplies filename "auto_install", autoinstall tries the MAC-address-specific file, the hostname-specific file, and then install.conf, in that order. Prefer a host-specific response file so one client cannot silently inherit another client’s disk or identity policy.

      For the example client, create /var/www/autoinstall/00:11:22:33:44:55-install.conf with mode 640, owned by root:www, so the www account can serve it without making it readable to unrelated local accounts. The following identity and set-source fragment is not a complete deployment response and must not be booted unmodified:

      System hostname = node1
      Password for root = *************
      Setup a user = admin
      Password for user = *************
      Public ssh key for user = ssh-ed25519 REPLACE_WITH_ADMIN_PUBLIC_KEY
      Allow root ssh login = no
      What timezone are you in = Europe/Amsterdam
      Location of sets = http
      HTTP Server = cdn.openbsd.org
      

      Thirteen asterisks disable password login for the corresponding account. Replace the public-key placeholder before deployment and verify that a separate recovery method exists. If password hashes are used instead, generate them with encrypt(1) ; never publish plaintext passwords.

      The response file uses defaults for unanswered questions. That behavior is convenient but unsafe for an unverified disk choice. Run an attended installation in the same lab first, capture the current questions, and add every answer needed to make the target disk and layout unambiguous before making the PXE record active.

      Configure the PXE Client Record #

      Add a host declaration to the provisioning server’s dhcpd.conf(5) :

      host node1 {
          hardware ethernet 00:11:22:33:44:55;
          fixed-address 192.0.2.20;
          next-server 192.0.2.10;
          filename "auto_install";
          option host-name "node1";
      }
      

      The surrounding subnet declaration must supply the correct mask, router, and resolver for the isolated network. Check the full DHCP configuration with the validation mode documented by the installed dhcpd(8) before reloading it.

      Replace PROVISIONING_INTERFACE with the verified interface name, then validate and start DHCP only on that interface:

      # dhcpd -n
        # Parse /etc/dhcpd.conf without starting the daemon
      # rcctl set dhcpd flags PROVISIONING_INTERFACE
        # Restrict DHCP broadcasts to the provisioning interface
      # rcctl enable dhcpd
        # Enable the service for the installation window
      # rcctl start dhcpd
        # Start the validated configuration
      

      When an existing DHCP service is already active, change its interface or configuration only through a separately planned maintenance event and restart it as required by dhcpd(8) .

      On amd64, auto_install must resolve through TFTP to the expected pxeboot program. Other architectures have different network boot programs and firmware requirements. Do not reuse this amd64 recipe for another architecture.

      Restrict Provisioning Traffic with PF #

      The daemon bindings prevent wildcard listeners, but PF must also admit the required traffic only on the controlled interface. Merge an equivalent policy into the complete ruleset, replacing the example network and interface:

      provision_if = "em1"
      provision_net = "192.0.2.0/24"
      
      pass in on $provision_if inet proto udp from any port bootpc \
          to any port bootps
      pass out on $provision_if inet proto udp from ($provision_if) port bootps \
          to any port bootpc
      pass in on $provision_if inet proto udp from $provision_net \
          to ($provision_if) port tftp
      pass in on $provision_if inet proto tcp from $provision_net \
          to ($provision_if) port http
      

      These rules do not authorize routing from the provisioning network to other networks. Parse the complete pf.conf(5) file with pfctl -nf /etc/pf.conf before loading it. Verify DHCP, TFTP, and HTTP from the allowed network and confirm that the services are unreachable from a denied network.

      Perform a Staged Installation #

      Keep the client console visible and boot it from the provisioning network. Confirm the following sequence before allowing the installer to write a disk:

      1. DHCP assigns the expected address and identifies the correct server.
      2. TFTP loads auto_install and bsd.rd.
      3. The installer selects autoinstall after its short timeout.
      4. HTTP requests the expected host-specific response file.
      5. The displayed hostname, interface, target disk, and set source match the plan.

      If the response file is not found, autoinstall asks for a URL or local path. Stop and diagnose DHCP, TFTP, HTTP logs, file names, permissions, and the client MAC address rather than entering secrets at an unexplained prompt.

      Validate and Retire Provisioning Access #

      After the first boot:

      • verify console and named-account SSH access;
      • verify the installed disk layout, network configuration, and hostname;
      • apply the normal first-install baseline ;
      • review the install log and server access logs;
      • remove the client’s PXE boot directive or disable network boot;
      • remove response files that are no longer required;
      • rotate any secret that was exposed beyond its intended host;
      • retain a redacted response template in configuration management.

      On the dedicated server in this example, stop and disable all three provisioning services after the installation window:

      # rcctl stop dhcpd
        # Stop address and boot-metadata service
      # rcctl stop tftpd
        # Stop unauthenticated boot-file service
      # rcctl stop httpd
        # Stop the response-file service
      # rcctl disable dhcpd tftpd httpd
        # Prevent the dedicated services from returning at boot
      

      If httpd or DHCP has another production role, remove only the provisioning listener, client records, and PF access, then validate and reload or restart the shared service.

      Use install.site(5) and reviewed, controlled site sets only for post-install customization. Keep secrets out of reusable site archives and make provisioning scripts safe to run more than once.

      Report a bug
      • Synopsis
      • Define the Provisioning Boundary
      • Obtain and Verify the Boot Files
      • Prepare TFTP
      • Publish the Response File through HTTP
      • Create a Host-Specific Response File
      • Configure the PXE Client Record
      • Restrict Provisioning Traffic with PF
      • Perform a Staged Installation
      • Validate and Retire Provisioning Access