
Every few months, someone on a networking forum asks the same question: “Can I install OPNsense directly on Ubuntu?” The honest answer is no — not in the way most people imagine. OPNsense is a FreeBSD-based operating system in its own right, not a package you apt install on top of an existing Linux distribution. What you can do, and what most production environments actually do, is run OPNsense as a fully virtualized appliance on an Ubuntu 26.04 LTS host using KVM and libvirt.
That distinction matters more than it sounds. A lot of guides floating around the internet conflate “installing on Ubuntu” with “installing alongside Ubuntu,” and the confusion leads to wasted hours and broken network configurations. Having spent over a decade wrangling production firewalls, hypervisors, and everything in between, this article walks through the correct, battle-tested method: deploying OPNsense as a KVM virtual machine on a fresh Ubuntu 26.04 LTS server, complete with bridged networking, hardware passthrough considerations, and the kind of post-install hardening that actually holds up under real traffic.
Why go this route instead of bare metal? Flexibility, mostly. Running OPNsense inside KVM on Ubuntu means the host can double as a hypervisor for other workloads, snapshots become trivial for rollback, and you’re not burning an entire physical box on a firewall that might only need two vCPUs and 4GB of RAM for a small office. It’s also how a surprising number of homelab-to-production migrations happen — someone builds it in a VM to test, then never bothers moving it to dedicated hardware because performance is fine.
This guide assumes you’re comfortable with basic Linux administration and have physical or remote console access to the Ubuntu host, since network interface changes mid-session can lock you out if you’re not careful.
Prerequisites Before You Start
Before touching a single command, confirm the hardware and software baseline. Skipping this step is the number one cause of failed installs and mysteriously sluggish firewall performance later.
- CPU with virtualization extensions (Intel VT-x or AMD-V) enabled in BIOS/UEFI, non-negotiable for KVM
- Ubuntu 26.04 LTS Server installed as the host, with at least 2 physical or logical network interfaces
- Minimum 4GB RAM allocated to the host beyond what you plan to give the VM (8GB+ total recommended)
- At least 20GB of free disk space for the OPNsense virtual disk
- Root or sudo access on the Ubuntu host
- A downloaded OPNsense DVD ISO image (amd64) from the official OPNsense download page
Check virtualization support with a quick command before going further:
egrep -c '(vmx|svm)' /proc/cpuinfo
Anything above zero confirms the CPU supports hardware virtualization. If it returns 0, stop here — you’ll need to enable it in firmware settings or you’re working with unsupported hardware.
Step 1: Prepare Ubuntu 26.04 LTS as the Hypervisor Host
Update the system first. This isn’t optional housekeeping — outdated kernel modules have caused more than a few KVM networking headaches over the years.
sudo apt update && sudo apt full-upgrade -y
sudo reboot
Once the system is back up, install the virtualization stack:
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager
Add your user to the relevant groups so you’re not stuck running everything as root for every VM operation:
sudo usermod -aG libvirt,kvm $USER
newgrp libvirt
Verify libvirt is actually running:
sudo systemctl status libvirtd
sudo systemctl enable --now libvirtd
If libvirtd fails to start, check journalctl -u libvirtd -xe immediately — a common culprit is a conflicting AppArmor profile on freshly upgraded systems, and it’s easier to fix at this stage than after the VM exists.
Step 2: Configure Bridged Networking on the Host
This is where a lot of installs go sideways. OPNsense needs at least two distinct network interfaces — one for WAN, one for LAN — and for the VM to actually see real traffic, those interfaces need to be bridged rather than NATed through the default libvirt virtual network.
Identify your physical interfaces:
ip link show
Suppose you have enp1s0 (WAN-facing, plugged into your modem/ISP router) and enp2s0 (LAN-facing, plugged into your internal switch). Using Netplan, which Ubuntu 26.04 LTS uses by default, create bridges for each:
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
dhcp4: no
enp2s0:
dhcp4: no
bridges:
br-wan:
interfaces: [enp1s0]
dhcp4: no
br-lan:
interfaces: [enp2s0]
dhcp4: no
Save this to /etc/netplan/01-opnsense-bridges.yaml and apply it:
sudo netplan apply
A practical note here: if you’re doing this over SSH, apply netplan changes with extreme caution. Bridging a physical interface that carries your SSH session will drop your connection the instant the bridge comes up. Console access or a scheduled rollback (netplan try) saves you from a very frustrating drive to the data center.
Step 3: Create the OPNsense Virtual Machine
With bridges in place, spin up the VM using virt-install. This example allocates 2 vCPUs, 4GB RAM, and a 20GB virtual disk — reasonable for small-to-medium traffic, though anything pushing gigabit-plus WAN throughput or heavy IDS/IPS inspection should get more.
sudo virt-install \
--name opnsense-fw \
--ram 4096 \
--vcpus 2 \
--cpu host-passthrough \
--disk path=/var/lib/libvirt/images/opnsense.qcow2,size=20,format=qcow2 \
--cdrom /root/OPNsense-26.1-dvd-amd64.iso \
--network bridge=br-wan,model=virtio \
--network bridge=br-lan,model=virtio \
--os-variant freebsd13.2 \
--graphics vnc,listen=0.0.0.0 \
--boot cdrom,hd
The --cpu host-passthrough flag matters more than people realize — it exposes the host’s actual CPU features to the guest, which noticeably improves packet processing performance inside OPNsense compared to the default emulated CPU model.
Connect to the VM console via virt-manager or virsh console opnsense-fw (though the graphical console is easier for the initial installer since it’s a full TUI). Boot from the ISO and you’ll land in the familiar OPNsense installer environment.
Step 4: Run the OPNsense Installer
Log in to the live environment with username installer and password opnsense. From here, the process mirrors bare-metal installation almost exactly, which is one of the nice things about running it virtualized — the underlying FreeBSD installer doesn’t care whether it’s on real silicon or QEMU’s virtual hardware.
- Select your keyboard layout, or accept the US default if unsure.
- Choose Quick/Easy Install for standard setups; pick Custom Installation only if you need specific partition layouts or ZFS pool tuning.
- Confirm ZFS or UFS as the filesystem. ZFS is now the recommended default and handles snapshot-based rollbacks elegantly, though UFS remains lighter on resource-constrained VMs.
- Select the target virtual disk (it’ll show as the 20GB
qcow2volume created earlier). - Confirm the destructive install warning — this wipes the virtual disk, not anything on the host.
- Set the root password when prompted. Do not skip this or leave it as default; this single field is the difference between a secured appliance and an open invitation.
- Complete the install and reboot when prompted, detaching the ISO from the VM’s boot order afterward so it doesn’t loop back into the installer.
Once rebooted, OPNsense assigns interfaces automatically based on what it detects — typically vtnet0 and vtnet1 given the virtio network model specified during VM creation.
Step 5: Initial Network and WAN/LAN Configuration
At the console menu, assign interfaces if they weren’t auto-detected correctly. Option 1 in the console menu handles this — map vtnet0 to WAN and vtnet1 to LAN, matching the bridge order used in virt-install.
Set a static LAN IP through the console (option 2) so you can reach the web GUI:
LAN IP address: 192.168.10.1
Subnet mask: 24
From a machine on the LAN-side bridge, open a browser to https://192.168.10.1 and accept the self-signed certificate warning — this is expected on first boot and gets replaced later if you configure a proper certificate. Log in with root and the password set during installation.
The setup wizard walks through general settings, NTP configuration, WAN interface (DHCP or static, depending on your ISP), and LAN interface confirmation. Pay attention to the RFC1918 checkbox on the WAN step — if your WAN address happens to be a private range (common behind double-NAT setups or ISP CGNAT), disable that block filter or you’ll silently drop legitimate traffic.
Post-Installation Hardening
A freshly installed firewall is not a secured firewall. It’s a target with a nice interface. Treat the following as mandatory, not optional:
- Change the default HTTPS port away from 443 if the WAN-facing management interface is ever exposed, and disable WAN GUI access entirely unless absolutely required
- Create a dedicated admin user with limited privileges instead of relying solely on root for day-to-day management
- Enable two-factor authentication (TOTP) on the root and admin accounts under System > Access > Users
- Apply firmware updates immediately after initial setup via System > Firmware > Updates — the base install ISO is often several point releases behind
- Configure the firewall’s own logging to a remote syslog target so log data survives even if the appliance itself is compromised or corrupted
Security researchers and OPNsense’s own hardening documentation consistently flag default credential reuse and exposed management interfaces as the two most common real-world compromise vectors.
Performance Tuning for Production Workloads
Running OPNsense virtualized doesn’t mean accepting mediocre throughput. A few adjustments make a measurable difference, especially under sustained traffic or IDS/IPS inspection load.
CPU Allocation
Pin vCPUs to physical cores using virsh vcpupin rather than leaving scheduling entirely to the hypervisor. This reduces jitter, which matters a lot for VoIP or latency-sensitive traffic passing through.
Network Driver Selection
Stick with virtio network interfaces rather than emulated e1000 or rtl8139 models — the throughput difference is not subtle, often 3-5x under load.
Disk I/O
Use qcow2 with the virtio-scsi controller and enable cache=none with io=native for the disk configuration. This avoids double-caching between host and guest, which otherwise wastes RAM and adds latency.
Tunables Inside OPNsense
Under System > Settings > Tunables, adjusting kern.ipc.nmbclusters and increasing the firewall state table size (net.inet.ip.fw.dyn_max) helps on busy networks with many concurrent connections — a home lab rarely needs this, but a small business with 50+ devices and heavy NAT translation will notice the difference.
Suricata/IDS Overhead
If running Suricata or Zenarmor for deep packet inspection, budget significantly more CPU — inspection is CPU-bound, and undersized VMs choke badly the moment inline IPS mode is enabled rather than passive detection.
Troubleshooting Common Issues
VM won’t boot from the ISO: Double-check the boot order in virt-install or virt-manager settings — a common mistake is leaving hd before cdrom in the boot sequence, causing the VM to boot into an empty disk indefinitely.
No network connectivity after bridging: Run bridge link show and ip a to confirm the physical interface joined the bridge correctly. A frequent gotcha is leaving dhcp4: yes on the physical interface itself instead of the bridge in Netplan, which causes IP conflicts.
Web GUI unreachable after install: Confirm interface assignment matches expectations at the console — vtnet0/vtnet1 ordering isn’t always intuitive, and it’s easy to have LAN and WAN swapped, which locks you out of the GUI from your management network.
Sluggish throughput despite adequate specs: Almost always traced back to emulated NIC drivers or missing host-passthrough CPU mode. Verify with virsh dumpxml opnsense-fw | grep model that virtio is actually in use.
Self-signed certificate warnings persist: Expected behavior unless a proper certificate (Let’s Encrypt via ACME plugin, for instance) is configured under System > Trust > Certificates.
High CPU usage on the host from the OPNsense VM: Check for accidental promiscuous mode on bridges combined with heavy broadcast traffic — a misconfigured bridge sometimes forwards traffic it shouldn’t, spiking both host and guest CPU unnecessarily.
Best Practices for Long-Term Stability
Backup the configuration immediately after initial setup, and again after any significant rule changes, via System > Configuration > Backups. Store these off-box — a firewall backup sitting only on the firewall itself defeats the purpose during a disaster recovery scenario.
Schedule firmware updates during low-traffic windows, never during business hours on a production gateway. Snapshot the VM at the hypervisor level (virsh snapshot-create-as) before major firmware upgrades, giving an instant rollback path if an update misbehaves.
Monitor resource usage from the host side using virt-top or integrate with existing monitoring stacks like Zabbix or Prometheus node exporters, rather than relying solely on OPNsense’s internal dashboard widgets for capacity planning.