Skip to content

Runbook 02 — OPNsense install + base config

Goal: install latest stable OPNsense on the VM from runbook 01, get GUI access on the MGMT-bound management IP, and apply base system settings + hardening + the virtio tunings. No zone VLANs yet (that's runbook 03).

Prereqs: runbook 01 validated (VM boots the installer; vtnet0=LAN trunk, vtnet1=WAN).


1. Install

At the installer login prompt, log in as installer / opnsense (or root / opnsense on older images) to launch the guided installer.

  • Keymap: default.
  • Install (UFS) — the Proxmox host datastore is ZFS, so guest ZFS would be ZFS-on-ZFS: double ARC (wasted RAM on a small firewall) + write amplification, and on a single guest disk ZFS only detects corruption, can't repair it — your host pool already detects and repairs the zvol. Use UFS (SU+J) and let the host provide integrity/compression/snapshots.
  • Rollback (the reason ZFS boot environments are nice) is covered host-side: qm snapshot 9140 pre-update before a firmware update, plus the config-XML backup (§7). (If you specifically want in-guest boot environments and have RAM to spare, ZFS is fine — but cap the guest ARC via vfs.zfs.arc_max.)
  • Set the root password (use a strong one; store in your password manager).
  • Complete, remove the ISO, reboot:
    # on the Proxmox node, detach the installer media so it boots from disk
    qm set <vmid> --ide2 none
    

2. Assign interfaces + management IP (console)

At the OPNsense console menu:

  1. Option 1 — Assign interfaces.
  2. VLANs now? no (we do VLANs in the GUI, runbook 03).
  3. WAN = vtnet1
  4. LAN = vtnet0
  5. (no optional interfaces yet) → confirm.
  6. Option 2 — Set interface IP address → LAN:
  7. IPv4 via DHCP? no
  8. IPv4 address: 10.20.10.1, subnet 24 — this is the MGMT zone gateway. The untagged LAN carries this address only until the MGMT VLAN (tag 10) is created in runbook 03; you then move the address onto the tagged MGMT interface and the untagged LAN is removed.
  9. upstream gateway: none (blank)
  10. IPv6: none
  11. Enable DHCP server on LAN? no (DHCP is per-VLAN via Kea, runbook 04)
  12. Revert to HTTP for the web GUI? no (keep HTTPS)
  13. WAN — DHCP transit + the one WG-admin public IP: the ISP router stays inline and routes your static public block to OPNsense (it does not NAT those). So:
  14. Leave WAN IPv4 = DHCP — it takes a private transit lease (e.g. 10.1.10.x); the gateway is auto-named WAN_DHCP (10.1.10.1). Use that name wherever the runbooks say WAN_GW. Set a static DHCP reservation on the router so this WAN IP never changes.
  15. Add only .69 as an IP Alias Virtual IP on WAN (Interfaces → Virtual IPs → + → mode IP Alias, interface WAN). This is the WG admin endpoint address (runbook 07) — the single inbound exception on the Comcast link. Hold .65–.68 in reserve (unassigned) for future use.
  16. IPv6: None (IPv4-only — see §6 "Turn off IPv6").

Home serves no public services. Under the edge/origin design (CLAUDE.md; runbook 17) the public-facing layer lives on remote VPS edges and reaches home over outbound-dialed WireGuard tunnels — which need no WAN VIP or port-forward (home initiates them). The only inbound on the Comcast link is the WG admin dial-in on .69:51820. So there are no service IP-Aliases here, no 80/443/53/22 forwards — just the one .69 VIP. (.65–.68 stay reserved in case a future need genuinely requires another inbound address.)


3. First GUI login

From a client on the MGMT segment (or a host temporarily attached to the LAN bridge), browse to https://10.20.10.1 (accept the self-signed cert). Log in as root. Skip/complete the setup wizard quickly — we set everything explicitly below.

In the wizard's LAN step, leave "Enable DHCP server" UNCHECKED and keep the LAN IP 10.20.10.1. Per-VLAN DHCP (Kea) comes in runbook 04; the untagged LAN never runs DHCP.


4. System settings

System → Settings → General - Hostname: fw01 (or keep opnsense) · Domain: ${domain} - Time zone: America/Chicago - DNS servers: 9.9.9.9, 1.1.1.1 (each once — no duplicates) · leave "use gateway" = none for now (revisit in runbook 05 so DNS follows policy). - Uncheck "Allow DNS server list to be overridden by DHCP/PPP on WAN" (we control DNS via Unbound). - Prefer IPv4 over IPv6: on — IPv4-only build; this makes the firewall itself prefer v4 (the GUI counterpart of the fleet's gai.conf).

System → Settings → Administration - Web GUI: keep HTTPS; port 443 (clean default). Optionally regenerate a self-signed cert now; a proper cert comes with ACME in runbook 09. - SSH (hardening) — row labels on this page: Secure Shell Server / Root Login / Authentication Method: - Enable Secure Shell: on - Permit root user login: OFF - Permit password login: OFF (key-only) - Listen Interfaces: leave default for now; we scope SSH to MGMT in runbook 06. - (There is no "Login Group" field on this page in 26.1 — SSH access is governed by the user's group/privileges + login shell, set on the user below.) - Before you lock yourself out: create an admin user with an SSH key first — System → Access → Users → Add — group membership admins, paste your key into "Authorized Keys". For key SSH login the user also needs a Login shell set (e.g. /bin/sh); a shell isn't needed for GUI-only. Test key login, then the password/root toggles above are safe.

System → Settings → Cron — defaults fine. NTP is under Services → Network Time (not System → Settings) — the NTP pool is already set by default.


5. Plugins + firmware

System → Firmware → StatusCheck for updates → update to the latest stable, reboot if prompted.

System → Firmware → Plugins — install (if a plugin isn't listed, click the "Click to view the community plugins." link first to reveal community plugins): - os-qemu-guest-agent (pairs with --agent enabled=1 from runbook 01) - os-acme-client (optional — only for the firewall's own GUI cert via DNS-01; the origin Caddy does its own ACME internally, runbook 09)

Note: no os-haproxy plugin — the reverse proxy is the internal origin Caddy (runbook 09), which handles its own Let's Encrypt certs (DNS-01). The firewall port-forwards nothing for it: public traffic reaches the origin Caddy over the edge WireGuard tunnels (runbook 17), not WAN.

After install, Services → Qemu Guest Agent → enable/start (or it auto-starts). Confirm on Proxmox: qm agent <vmid> ping returns nothing/success and the GUI shows the guest IP.


6. Virtio tunings (required for stable virtio under KVM/Proxmox)

Interfaces → Settings: - Disable hardware checksum offload: ON (exact labels use "offload", not "offloading") - Disable hardware TCP segmentation offload: ON - Disable hardware large receive offload: ON - VLAN Hardware Filtering: it's a dropdown — select "Disable VLAN Hardware Filtering" (safe for virtio) - Turn off IPv6: CHECKED — IPv4-only build (26.1 label; help text: "If checked, IPv6 interface configuration will be ignored and all forwarding traffic will be blocked. Use with care."). This single box is the master IPv6 off-switch — it overrides per-interface IPv6 settings and blocks all IPv6 forwarding, so the per-interface "IPv6 = None" (runbook 03) becomes moot/tidy. Don't run RA/DHCPv6.

Save → reboot to apply cleanly.


7. Back up the clean base

System → Configuration → Backups → Download. Keep this "base" config as a known-good restore point. (Do not commit it to this git repo — it will start accumulating secrets.)


Validation

  • [ ] GUI reachable at https://10.20.10.1; root + new admin (key) both work.
  • [ ] Permit root login and password login are off for SSH; key login as user works.
  • [ ] Firmware on latest stable; the plugins installed; guest-agent answers qm agent <vmid> ping.
  • [ ] Interfaces → Settings shows the 3 "Disable hardware … offload" options checked.
  • [ ] LAN = 10.20.10.1/24, no DHCP on LAN; WAN has its transit lease + gateway up; you can ping 9.9.9.9 from Interfaces → Diagnostics → Ping.

Then → runbook 03 (interfaces + VLANs).