<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hardware Provisioning: PXE Booting and Tooling on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/hardware/hardware-provisioning/</link><description>Recent content in Hardware Provisioning: PXE Booting and Tooling on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/public-notes/hardware/hardware-provisioning/index.xml" rel="self" type="application/rss+xml"/><item><title>PXE Booting with OPNSense + iPXE</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/hardware/hardware-provisioning/ipxe-opnsense/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/hardware/hardware-provisioning/ipxe-opnsense/</guid><description>&lt;p&gt;How to configure OPNSense as a PXE boot server using its built-in DHCP and TFTP services, and how to write an iPXE boot menu that can chainload Talos Linux (or anything else).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="opnsense-dhcp--network-boot-fields"&gt;OPNSense DHCP — Network Boot Fields
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Services → ISC DHCPv4 → [LAN] → Network Booting&lt;/code&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Field&lt;/th&gt;
 &lt;th&gt;Value&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Enable network booting&lt;/td&gt;
 &lt;td&gt;✓&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Next-server IP&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;192.168.1.1&lt;/code&gt; (OPNSense LAN address)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Default BIOS filename&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;undionly.kpxe&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;x86 UEFI (32-bit) filename&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ipxe.efi&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;x64 UEFI/EBC (64-bit) filename&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ipxe.efi&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;iPXE boot filename&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;default.ipxe&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The DHCP server serves the correct boot file based on client architecture. BIOS clients get &lt;code&gt;undionly.kpxe&lt;/code&gt;; UEFI clients get &lt;code&gt;ipxe.efi&lt;/code&gt;. Both then chainload &lt;code&gt;default.ipxe&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tftp--downloading-the-boot-files"&gt;TFTP — Downloading the Boot Files
&lt;/h2&gt;&lt;p&gt;OPNSense runs a TFTP server rooted at &lt;code&gt;/usr/local/tftp&lt;/code&gt;. SSH in and fetch the iPXE binaries:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fetch -o /usr/local/tftp/undionly.kpxe https://boot.ipxe.org/undionly.kpxe
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fetch -o /usr/local/tftp/ipxe.efi https://boot.ipxe.org/ipxe.efi
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="ipxe-boot-script"&gt;iPXE Boot Script
&lt;/h2&gt;&lt;p&gt;Save as &lt;code&gt;/usr/local/tftp/default.ipxe&lt;/code&gt;. This example has a boot menu with options for netboot.xyz, a Talos Omni boot, and a debug shell.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-ipxe" data-lang="ipxe"&gt;#!ipxe

dhcp
set menu-timeout 5000

:start
menu PXE Boot Menu
item --gap -- ----------------------------
item netboot Boot netboot.xyz
item talos Boot Talos (Omni)
item shell iPXE Shell
item --gap -- ----------------------------
choose target &amp;amp;&amp;amp; goto ${target}

:netboot
chain http://boot.netboot.xyz || goto failed
goto start

:talos
echo Booting Talos via Omni...

set api https://&amp;lt;your-omni-instance&amp;gt;.omni.siderolabs.io
set token &amp;lt;join-token&amp;gt;
set event [&amp;lt;siderolink-ipv6&amp;gt;]:8090
set log tcp://[&amp;lt;siderolink-ipv6&amp;gt;]:8092

kernel tftp://${next-server}/talos/vmlinuz-omni \
 ima_template=ima-ng \
 ima_appraise=fix \
 ima_hash=sha512 \
 selinux=1 \
 consoleblank=0 \
 nvme_core.io_timeout=4294967295 \
 initrd=initramfs.xz \
 init_on_alloc=1 \
 slab_nomerge \
 pti=on \
 console=tty0 \
 console=ttyS0 \
 printk.devkmsg=on \
 talos.platform=metal \
 siderolink.api=${api}?jointoken=${token} \
 talos.events.sink=${event} \
 talos.logging.kernel=${log}

initrd tftp://${next-server}/talos/initramfs-omni.xz
boot || goto failed

:shell
shell

:failed
echo Boot failed, press Enter to continue...
read fake
goto start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt;, &lt;code&gt;event&lt;/code&gt;, and &lt;code&gt;log&lt;/code&gt; values come from the Omni console when you generate a join link.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="talos-kernel-and-initramfs--image-factory"&gt;Talos Kernel and Initramfs — Image Factory
&lt;/h2&gt;&lt;p&gt;The standard Talos release binaries do not include firmware for all hardware. Since Talos 1.6, several older NIC drivers (including Broadcom BNX2 / BCM5709) were removed from the mainline image and made available as extensions via the image factory.&lt;/p&gt;
&lt;p&gt;Generate a custom image at &lt;a class="link" href="https://factory.talos.dev" target="_blank" rel="noopener"
 &gt;factory.talos.dev&lt;/a&gt; with the extensions you need (e.g. &lt;code&gt;siderolabs/bnx2&lt;/code&gt;), then download the PXE artifacts:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /usr/local/tftp/talos
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fetch -o /usr/local/tftp/talos/vmlinuz-omni &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://pxe.factory.talos.dev/image/&amp;lt;IMAGE_ID&amp;gt;/v1.10.1/kernel-amd64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fetch -o /usr/local/tftp/talos/initramfs-omni.xz &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://pxe.factory.talos.dev/image/&amp;lt;IMAGE_ID&amp;gt;/v1.10.1/initramfs-amd64.xz&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Replace &lt;code&gt;&amp;lt;IMAGE_ID&amp;gt;&lt;/code&gt; with the schematic ID from the image factory, and adjust the version tag as needed.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="gotchas"&gt;Gotchas
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;UEFI boot and NIC memory limits&lt;/strong&gt; — &lt;code&gt;ipxe.efi&lt;/code&gt; can be too large to fit in the NIC&amp;rsquo;s PXE memory buffer on some older hardware. If the UEFI chain fails silently, switch to BIOS/legacy mode and use &lt;code&gt;undionly.kpxe&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DHCP options 66/67 conflict&lt;/strong&gt; — If you have previously set DHCP options 66 (next-server) and 67 (boot file) as raw additional options, remove them. OPNSense&amp;rsquo;s built-in network boot fields handle this; having both causes conflicts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BIOS boot order after first boot&lt;/strong&gt; — Talos writes its own bootloader on first boot. If the BIOS is set to PXE as the primary device, the machine will fall back to the PXE menu on every subsequent reboot. Set disk as the primary boot device once the cluster is up.&lt;/p&gt;</description></item></channel></rss>