<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Opnsense on Backend Engineering Strategy Tools</title><link>https://backend-engineering-strategy-tools.github.io/site/tags/opnsense/</link><description>Recent content in Opnsense on Backend Engineering Strategy Tools</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 05 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://backend-engineering-strategy-tools.github.io/site/tags/opnsense/index.xml" rel="self" type="application/rss+xml"/><item><title>BIFROST — Raspberry Pi jump node</title><link>https://backend-engineering-strategy-tools.github.io/site/homelab/bifrost/</link><pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/homelab/bifrost/</guid><description>&lt;p&gt;The homelab needed a permanent always-on entry point — something low power, always reachable, a stable first hop. A first-gen Raspberry Pi in the rack fills that role. BIFROST.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="hardware"&gt;Hardware
&lt;/h2&gt;&lt;p&gt;Raspberry Pi 1 Model B running Raspbian, mounted in the rack with a &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/rack-3d-prints/" &gt;3D printed 1U mount&lt;/a&gt;. Draws under 2W at idle. Nothing runs on it except sshd.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-it-works"&gt;How it works
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;ssh -p 22222 user@bifrost.mjnet.info
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The chain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;bifrost.mjnet.info&lt;/code&gt; — Route53 CNAME pointing to &lt;code&gt;router.mjnet.info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;router.mjnet.info&lt;/code&gt; — HEIMDAL (SYS-009), kept current via DDNS&lt;/li&gt;
&lt;li&gt;OPNsense port forward: external TCP 22222 → Pi:22&lt;/li&gt;
&lt;li&gt;OPNsense DNS override: &lt;code&gt;bifrost.mjnet.info&lt;/code&gt; → Pi&amp;rsquo;s internal IP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The DNS override means the same hostname resolves to the internal IP when used inside the network — no split config needed in &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="opnsense-config"&gt;OPNsense config
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Port forward&lt;/strong&gt; (Firewall → NAT → Port Forward):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interface: WAN&lt;/li&gt;
&lt;li&gt;Protocol: TCP&lt;/li&gt;
&lt;li&gt;Destination port: 22222&lt;/li&gt;
&lt;li&gt;Redirect target: Pi internal IP, port 22&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;DNS override&lt;/strong&gt; (Services → Unbound DNS → Host Overrides):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host: &lt;code&gt;bifrost&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Domain: &lt;code&gt;mjnet.info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;IP: Pi internal IP&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="ssh-config"&gt;SSH config
&lt;/h2&gt;&lt;p&gt;Add to &lt;code&gt;~/.ssh/config&lt;/code&gt; on any client:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Host bifrost
 HostName bifrost.mjnet.info
 Port 22222
 User pi
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then &lt;code&gt;ssh bifrost&lt;/code&gt; from anywhere.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;If a more robust solution becomes necessary later (no open ports, survives CGNAT), the &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/bifrost-rpi-options/" &gt;options doc&lt;/a&gt; covers Tailscale, Cloudflare Tunnel, and WireGuard.&lt;/p&gt;</description></item><item><title>Dynamic DNS (DDNS)</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/ddns/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/ddns/</guid><description>&lt;p&gt;Most home internet connections have a dynamic IP — the ISP can reassign it at any time. Dynamic DNS (DDNS) keeps a DNS hostname pointed at whatever IP you currently have, by running a small client that detects changes and updates the DNS record automatically.&lt;/p&gt;
&lt;p&gt;Relevant when using &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/tunnels/" &gt;port forwarding or WireGuard&lt;/a&gt; to reach a private network from outside — you need a stable hostname to connect to.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-it-works"&gt;How it works
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;You register a hostname with a DDNS provider (e.g. &lt;code&gt;myhome.duckdns.org&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;An update client runs on your router or a machine on your network&lt;/li&gt;
&lt;li&gt;The client periodically checks your public IP (or watches for changes) and calls the provider&amp;rsquo;s API to update the DNS record&lt;/li&gt;
&lt;li&gt;DNS TTL is kept short (60–300s) so changes propagate quickly&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="providers"&gt;Providers
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Provider&lt;/th&gt;
 &lt;th&gt;Cost&lt;/th&gt;
 &lt;th&gt;Domain&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a class="link" href="https://www.duckdns.org" target="_blank" rel="noopener"
 &gt;DuckDNS&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;Free&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;*.duckdns.org&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Simple, no account required beyond OAuth login&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cloudflare&lt;/td&gt;
 &lt;td&gt;Free (if you own a domain)&lt;/td&gt;
 &lt;td&gt;Your own domain&lt;/td&gt;
 &lt;td&gt;Best option if you already use Cloudflare for DNS&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;No-IP&lt;/td&gt;
 &lt;td&gt;Free (limited)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;*.ddns.net&lt;/code&gt; etc.&lt;/td&gt;
 &lt;td&gt;Requires manual renewal every 30 days on free tier&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Dynu&lt;/td&gt;
 &lt;td&gt;Free&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;*.dynu.net&lt;/code&gt; etc.&lt;/td&gt;
 &lt;td&gt;More generous free tier than No-IP&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Afraid.org&lt;/td&gt;
 &lt;td&gt;Free&lt;/td&gt;
 &lt;td&gt;Shared subdomains&lt;/td&gt;
 &lt;td&gt;Long-running community service&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare&lt;/strong&gt; is the best option if you own a domain — you get a real subdomain (&lt;code&gt;home.yourdomain.com&lt;/code&gt;), the API is reliable, and the client support is universal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DuckDNS&lt;/strong&gt; is the easiest if you don&amp;rsquo;t own a domain — no configuration beyond a token.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="opnsense"&gt;OPNsense
&lt;/h2&gt;&lt;p&gt;OPNsense has a built-in DDNS client under &lt;strong&gt;Services → Dynamic DNS&lt;/strong&gt;. Supports Cloudflare, DuckDNS, No-IP, Route53, and others out of the box.&lt;/p&gt;
&lt;p&gt;Configuration for Cloudflare:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Service: &lt;code&gt;Cloudflare&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Hostname: &lt;code&gt;home&lt;/code&gt; (the subdomain to update)&lt;/li&gt;
&lt;li&gt;Domain: &lt;code&gt;yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Username: your Cloudflare account email&lt;/li&gt;
&lt;li&gt;Password: Cloudflare API token with &lt;code&gt;Zone:DNS:Edit&lt;/code&gt; permission for the domain&lt;/li&gt;
&lt;li&gt;Check IP: leave default (uses OPNsense&amp;rsquo;s WAN interface)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OPNsense updates the record whenever the WAN IP changes, detected via interface monitoring.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="linux-update-clients"&gt;Linux update clients
&lt;/h2&gt;&lt;p&gt;If the router doesn&amp;rsquo;t have a built-in client (or you want updates from a specific host):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ddclient&lt;/strong&gt; — the standard, supports most providers:&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apt install ddclient
&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;&lt;span style="color:#75715e"&gt;# /etc/ddclient.conf (Cloudflare example)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;protocol&lt;span style="color:#f92672"&gt;=&lt;/span&gt;cloudflare
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zone&lt;span style="color:#f92672"&gt;=&lt;/span&gt;yourdomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;login&lt;span style="color:#f92672"&gt;=&lt;/span&gt;your@email.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;password&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&amp;lt;api-token&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;home.yourdomain.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;inadyn&lt;/strong&gt; — lighter alternative, similar provider support:&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apt install inadyn
&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;&lt;span style="color:#75715e"&gt;# /etc/inadyn.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;provider cloudflare.com &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; your@email.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &amp;lt;api-token&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hostname &lt;span style="color:#f92672"&gt;=&lt;/span&gt; home.yourdomain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ttl &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxied &lt;span style="color:#f92672"&gt;=&lt;/span&gt; false
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="limitations"&gt;Limitations
&lt;/h2&gt;&lt;p&gt;DDNS does not help if your ISP uses CGNAT — if your router&amp;rsquo;s WAN IP is a private address (10.x, 100.64.x, 192.168.x), port forwarding and DDNS will not work. See &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/tunnels/" &gt;Tunnels&lt;/a&gt; for options that work without a public IP.&lt;/p&gt;
&lt;p&gt;DNS propagation delay means there&amp;rsquo;s a brief window after an IP change where connections will fail. Keep TTL at 60–300s to minimise this.&lt;/p&gt;</description></item><item><title>Firewall and router OS options</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/router-os/</link><pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/router-os/</guid><description>&lt;p&gt;Options for running a software-defined firewall or router, from homelab appliances to full routing OS deployments.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="the-main-split-appliance-vs-routing-os"&gt;The main split: appliance vs routing OS
&lt;/h2&gt;&lt;p&gt;Most options fall into one of two categories:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Firewall appliances&lt;/strong&gt; (OPNsense, pfSense, IPFire) — web UI-first, designed around the perimeter firewall use case. NAT, DHCP, DNS, VPN, IDS/IPS out of the box. Routing is possible but secondary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routing operating systems&lt;/strong&gt; (VyOS, MikroTik RouterOS, FRRouting) — CLI-first, designed around dynamic routing protocols (BGP, OSPF). Firewall rules exist but feel like an afterthought compared to the routing capabilities.&lt;/p&gt;
&lt;p&gt;For a homelab perimeter gateway: appliance. For BGP peering, complex routing topologies, or network-as-code: routing OS.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="opnsense"&gt;OPNsense
&lt;/h2&gt;&lt;p&gt;Open-source firewall and routing platform based on FreeBSD. Fork of pfSense, with a stronger emphasis on community ownership and more frequent security updates.&lt;/p&gt;
&lt;p&gt;Full gateway function: stateful firewall, NAT, DHCP, DNS (Unbound), TFTP/PXE, VPN (WireGuard, OpenVPN, IPsec), traffic shaping, IDS/IPS (Suricata), DDNS.&lt;/p&gt;
&lt;p&gt;BGP is available via the FRRouting plugin but is not a first-class feature — VyOS is better suited for BGP-heavy setups.&lt;/p&gt;
&lt;p&gt;→ &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/opnsense/" &gt;OPNsense reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: homelab perimeter gateway, home network, small office. The current actively-maintained community fork of the pfSense lineage.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="pfsense"&gt;pfSense
&lt;/h2&gt;&lt;p&gt;The original FreeBSD-based firewall appliance. Same underlying capabilities as OPNsense — they share a common ancestor (m0n0wall).&lt;/p&gt;
&lt;p&gt;Now owned by Netgate. The &lt;strong&gt;Community Edition (CE)&lt;/strong&gt; remains open source; &lt;strong&gt;pfSense Plus&lt;/strong&gt; is commercial and ships only on Netgate hardware or as a cloud image. Development focus has shifted toward Plus; CE updates have been slower.&lt;/p&gt;
&lt;p&gt;The practical difference between OPNsense and pfSense CE is increasingly small at the feature level. The main reasons to choose one over the other are familiarity, UI preference, and update cadence. OPNsense is the more actively developed option for community use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: environments where pfSense is already deployed, or where existing documentation/tooling targets it.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="vyos"&gt;VyOS
&lt;/h2&gt;&lt;p&gt;Open-source network OS built on Debian. Configured via a CLI with a commit/rollback model (similar to Juniper JunOS). Native BGP, OSPF, IS-IS via FRRouting.&lt;/p&gt;
&lt;p&gt;Configuration is declarative and version-controlled — the entire running config is a text file, which makes it automation-friendly (Ansible, Terraform).&lt;/p&gt;
&lt;p&gt;The rolling release is free; LTS releases require a subscription.&lt;/p&gt;
&lt;p&gt;→ &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/vyos/" &gt;VyOS reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: BGP peering, complex routing topologies, automation-driven network config, VM-based routing inside a cluster.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="mikrotik-routeros"&gt;MikroTik RouterOS
&lt;/h2&gt;&lt;p&gt;Commercial OS that runs on MikroTik hardware and as a VM (CHR — Cloud Hosted Router). Full routing OS with BGP, OSPF, MPLS, and a firewall. Configured via Winbox GUI, web UI, or CLI.&lt;/p&gt;
&lt;p&gt;Very capable at the price point. Hardware is inexpensive. The learning curve is steeper than OPNsense but shallower than VyOS for most tasks. Community is large and documentation is thorough.&lt;/p&gt;
&lt;p&gt;CHR (the VM version) is free for speeds up to 1Mbps; licensed tiers above that. On physical hardware, the license is included.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: cost-conscious deployments that need routing features, or environments already using MikroTik hardware.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="ipfire"&gt;IPFire
&lt;/h2&gt;&lt;p&gt;Linux-based firewall focused on simplicity and security hardening. Web UI, stateful firewall, IDS (Snort/Suricata), VPN (OpenVPN, WireGuard, IPsec), proxy.&lt;/p&gt;
&lt;p&gt;Less feature-rich than OPNsense but lighter and more opinionated. No BGP. Easier to get to a secure baseline quickly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: simple gateway where you want a small attack surface and don&amp;rsquo;t need advanced routing or a plugin ecosystem.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="untangle--arista-edge-threat-management"&gt;Untangle / Arista Edge Threat Management
&lt;/h2&gt;&lt;p&gt;Commercial product with a free tier (NG Firewall). Web UI, application-layer filtering, content inspection, threat management features. More enterprise-oriented than the others.&lt;/p&gt;
&lt;p&gt;Requires registration. The free tier is limited; the feature set that differentiates it from OPNsense is mostly in the commercial tiers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: environments that need application-layer filtering with a managed UI, or commercial support requirements.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="comparison"&gt;Comparison
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;OPNsense&lt;/th&gt;
 &lt;th&gt;pfSense CE&lt;/th&gt;
 &lt;th&gt;VyOS&lt;/th&gt;
 &lt;th&gt;MikroTik RouterOS&lt;/th&gt;
 &lt;th&gt;IPFire&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Base OS&lt;/td&gt;
 &lt;td&gt;FreeBSD&lt;/td&gt;
 &lt;td&gt;FreeBSD&lt;/td&gt;
 &lt;td&gt;Debian&lt;/td&gt;
 &lt;td&gt;Proprietary&lt;/td&gt;
 &lt;td&gt;Linux&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Primary interface&lt;/td&gt;
 &lt;td&gt;Web UI&lt;/td&gt;
 &lt;td&gt;Web UI&lt;/td&gt;
 &lt;td&gt;CLI&lt;/td&gt;
 &lt;td&gt;Winbox / CLI&lt;/td&gt;
 &lt;td&gt;Web UI&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;BGP / OSPF&lt;/td&gt;
 &lt;td&gt;Plugin (FRR)&lt;/td&gt;
 &lt;td&gt;Plugin (FRR)&lt;/td&gt;
 &lt;td&gt;Native (FRR)&lt;/td&gt;
 &lt;td&gt;Native&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;IDS/IPS&lt;/td&gt;
 &lt;td&gt;Suricata&lt;/td&gt;
 &lt;td&gt;Snort/Suricata&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;td&gt;No&lt;/td&gt;
 &lt;td&gt;Snort/Suricata&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;WireGuard&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes (Plus)&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DDNS&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Via script&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;td&gt;Yes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cost&lt;/td&gt;
 &lt;td&gt;Free&lt;/td&gt;
 &lt;td&gt;Free (CE)&lt;/td&gt;
 &lt;td&gt;Free (rolling)&lt;/td&gt;
 &lt;td&gt;Hardware license&lt;/td&gt;
 &lt;td&gt;Free&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Community&lt;/td&gt;
 &lt;td&gt;Active&lt;/td&gt;
 &lt;td&gt;Slowing (CE)&lt;/td&gt;
 &lt;td&gt;Active&lt;/td&gt;
 &lt;td&gt;Active&lt;/td&gt;
 &lt;td&gt;Active&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="further-reading"&gt;Further reading
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/opnsense/" &gt;OPNsense in the homelab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/vyos-bgp/" &gt;VyOS + BGP in the homelab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>OPNsense</title><link>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/opnsense/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/opnsense/</guid><description>&lt;p&gt;OPNsense is an open-source firewall and routing platform based on FreeBSD. It is a fork of pfSense, with a stronger emphasis on community ownership, a cleaner UI, and more frequent security updates. Both are descendants of m0n0wall.&lt;/p&gt;
&lt;p&gt;It covers the full gateway function: stateful firewall, NAT, DHCP, DNS, TFTP, VPN, traffic shaping, and IDS/IPS — all through a web UI or via the API.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="feature-overview"&gt;Feature overview
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Feature&lt;/th&gt;
 &lt;th&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Stateful firewall&lt;/td&gt;
 &lt;td&gt;Zone-based rules, aliases, scheduling&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;NAT&lt;/td&gt;
 &lt;td&gt;Outbound, inbound (port forwarding), 1:1&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DHCP&lt;/td&gt;
 &lt;td&gt;ISC DHCPv4 and Kea; supports network boot options&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DNS&lt;/td&gt;
 &lt;td&gt;Unbound resolver with DNSSEC; optional forwarding&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;TFTP&lt;/td&gt;
 &lt;td&gt;Simple server at &lt;code&gt;/usr/local/tftp&lt;/code&gt;; used for PXE boot&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;VPN&lt;/td&gt;
 &lt;td&gt;WireGuard, OpenVPN, IPsec&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;IDS/IPS&lt;/td&gt;
 &lt;td&gt;Suricata integration&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Traffic shaping&lt;/td&gt;
 &lt;td&gt;HFSC, PRIQ, CAKE&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;BGP / routing&lt;/td&gt;
 &lt;td&gt;FRRouting plugin available (not enabled by default)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="opnsense-vs-pfsense-vs-vyos"&gt;OPNsense vs pfSense vs VyOS
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;OPNsense&lt;/th&gt;
 &lt;th&gt;pfSense&lt;/th&gt;
 &lt;th&gt;VyOS&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Base&lt;/td&gt;
 &lt;td&gt;FreeBSD&lt;/td&gt;
 &lt;td&gt;FreeBSD&lt;/td&gt;
 &lt;td&gt;Debian Linux&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;License&lt;/td&gt;
 &lt;td&gt;BSD (true FOSS)&lt;/td&gt;
 &lt;td&gt;BSL (mixed)&lt;/td&gt;
 &lt;td&gt;GPL&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Model&lt;/td&gt;
 &lt;td&gt;Firewall appliance&lt;/td&gt;
 &lt;td&gt;Firewall appliance&lt;/td&gt;
 &lt;td&gt;Network OS&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Config interface&lt;/td&gt;
 &lt;td&gt;Web UI + API&lt;/td&gt;
 &lt;td&gt;Web UI&lt;/td&gt;
 &lt;td&gt;CLI (commit/rollback)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;BGP&lt;/td&gt;
 &lt;td&gt;Via FRRouting plugin&lt;/td&gt;
 &lt;td&gt;Via FRRouting plugin&lt;/td&gt;
 &lt;td&gt;Native (FRRouting built-in)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Typical use&lt;/td&gt;
 &lt;td&gt;Edge gateway, firewall&lt;/td&gt;
 &lt;td&gt;Edge gateway, firewall&lt;/td&gt;
 &lt;td&gt;Router, BGP peer, lab router VM&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OPNsense and pfSense are both appliance-style: you configure them through a UI and they manage all the underlying services for you. &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/vyos/" &gt;VyOS&lt;/a&gt; is a network OS in the Juniper/Cisco tradition — CLI-first, commit/rollback, intended for use as a router or BGP peer rather than a full gateway appliance.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="related"&gt;Related
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.opnsense.org/" target="_blank" rel="noopener"
 &gt;OPNsense documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/opnsense/plugins" target="_blank" rel="noopener"
 &gt;OPNsense plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/hardware/hardware-provisioning/ipxe-opnsense/" &gt;iPXE + OPNsense&lt;/a&gt; — PXE boot configuration via OPNsense DHCP and TFTP&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/opnsense/" &gt;OPNsense in the homelab&lt;/a&gt; — current setup and planned redo&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>OPNsense in the homelab</title><link>https://backend-engineering-strategy-tools.github.io/site/homelab/opnsense/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://backend-engineering-strategy-tools.github.io/site/homelab/opnsense/</guid><description>&lt;p&gt;&lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/public-notes/networking/opnsense/" &gt;OPNsense&lt;/a&gt; running on the Sun Fire X4150 — perimeter gateway for both the homelab and the home network.&lt;/p&gt;
&lt;p&gt;Current state: inherited setup, not clean, not properly documented. It works, but it was not built with intention. A redo is on the todo list.&lt;/p&gt;
&lt;p&gt;Dual role is intentional and will stay that way — OPNsense on the Sun Fire handles both the homelab and the house. One box, one gateway.&lt;/p&gt;
&lt;p&gt;The Sun Fire X4150 handles it without breaking a sweat. Old, but solid.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="todo-clean-reinstall"&gt;TODO: Clean reinstall
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Fresh OPNsense install on the Sun Fire&lt;/li&gt;
&lt;li&gt;Rename from &lt;code&gt;router.mjnet.info&lt;/code&gt; → &lt;code&gt;heimdal.mjnet.info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Document the full configuration: firewall rules, DHCP, DNS (Unbound), TFTP/PXE, BGP peering with VyOS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;On the hostname rename&lt;/strong&gt;: making the router&amp;rsquo;s hostname publicly resolvable is a mild information disclosure — it signals which host is the perimeter device. In practice the IP is what matters, and if it&amp;rsquo;s already reachable the name adds little. Still worth being deliberate about what resolves publicly.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="intended-role"&gt;Intended role
&lt;/h2&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;ISP/WAN → OPNsense (heimdal.mjnet.info) → LAN switch → rack
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Perimeter firewall and NAT gateway&lt;/li&gt;
&lt;li&gt;DHCP for the LAN&lt;/li&gt;
&lt;li&gt;DNS via Unbound&lt;/li&gt;
&lt;li&gt;TFTP/PXE for bare-metal provisioning&lt;/li&gt;
&lt;li&gt;eBGP peer upstream of VyOS (future — see &lt;a class="link" href="https://backend-engineering-strategy-tools.github.io/site/homelab/vyos-bgp/" &gt;VyOS + BGP&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;</description></item><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>