Posted on

Installing OPNsense on the Rock Pi 4B+ (FreeBSD aarch64 + opnsense-bootstrap)

Running OPNsense on a Rock Pi 4B+ turns a $90 single-board computer into a respectable home/small-office firewall — gigabit routing, WireGuard, Suricata IDS, the lot — while drawing under 5 W idle. The catch: OPNsense has no official ARM64 build. The path that actually works is FreeBSD 14 aarch64 + the opnsense-bootstrap script. Here is the complete walkthrough we use in the shop.

What You Need

  • A Rock Pi 4B / 4B+ (we use the 4B+ with 4 GB RAM and onboard eMMC)
  • A 64 GB microSD card (for the initial FreeBSD install — final OS lives on eMMC)
  • A USB 3.0 gigabit Ethernet adapter with a FreeBSD-supported chipset (we use the ASIX AX88179 — driver name axge). The onboard NIC becomes your LAN; the USB NIC becomes your WAN.
  • A 3A USB-C power supply — under-powered supplies are the #1 cause of mid-boot kernel panics on this board
  • A USB-to-serial UART adapter (3.3 V) — strongly recommended; HDMI console is unreliable on FreeBSD/aarch64 with the Rockchip framebuffer

Honesty up front: there is no Deciso-signed OPNsense image for ARM. What we are doing is installing FreeBSD aarch64 first, then running the community opnsense-bootstrap.sh on top. It works, it is stable, and it gets security updates — but you are responsible for keeping FreeBSD itself patched.

Step 1 — Flash FreeBSD 14 aarch64 to microSD

Grab the FreeBSD 14.x RPI aarch64 image — the Raspberry Pi image works on the Rock Pi 4 with one device-tree swap. From download.freebsd.org/snapshots/arm64/aarch64/ISO-IMAGES/ pull the latest:

wget https://download.freebsd.org/snapshots/arm64/aarch64/ISO-IMAGES/14.2/FreeBSD-14.2-STABLE-arm64-aarch64-RPI.img.xz
xz -d FreeBSD-14.2-STABLE-arm64-aarch64-RPI.img.xz
sudo dd if=FreeBSD-14.2-STABLE-arm64-aarch64-RPI.img of=/dev/sdX bs=4M status=progress conv=fsync

Step 2 — Swap in the Rock Pi 4 Device Tree

The RPI image boots a Raspberry Pi DTB by default. The Rock Pi 4 has its own DTB shipped inside the FreeBSD image — we just need to point U-Boot at it.

Mount the FAT partition of the SD card (the first one) on your PC and edit boot/loader.conf:

fdt_overlays=""
fdt_file="rockchip/rk3399-rock-pi-4b.dtb"

Then drop a U-Boot built for the Rock Pi 4 into the same partition. The pre-built u-boot-rock-pi-4.bin from the FreeBSD ports tree (sysutils/u-boot-rockpi4) is what you want — flash it to the SPI offset:

sudo dd if=u-boot-rock-pi-4-rockchip.bin of=/dev/sdX seek=64 conv=notrunc

Step 3 — First Boot and Network Up

Connect the UART (TX/RX/GND on pins 8/10/6 of the Rock Pi GPIO header, 1.5M baud), insert the SD, power on. You should see U-Boot, then the FreeBSD loader, then a login prompt. Default creds are root / no password.

Bring up the onboard NIC (dwc0) as a temporary management interface:

ifconfig dwc0 up
dhclient dwc0

Confirm internet, then set the FreeBSD release to the version OPNsense expects (currently 14.2):

freebsd-update fetch install
pkg update
pkg install -y curl ca_root_nss

Step 4 — Run opnsense-bootstrap

This is the magic. The OPNsense team maintains a script that converts a clean FreeBSD install into a working OPNsense system — it swaps the pkg repo, installs the OPNsense base, MVC framework, web GUI, and config layer, and reboots into a functional firewall.

fetch https://raw.githubusercontent.com/opnsense/update/master/src/bootstrap/opnsense-bootstrap.sh.in
mv opnsense-bootstrap.sh.in opnsense-bootstrap.sh
sh ./opnsense-bootstrap.sh -r 25.7

Replace 25.7 with the current OPNsense release tag (check github.com/opnsense/core/releases). The script takes 10–20 minutes — most of that is downloading the OPNsense package set.

When it finishes it asks for a reboot. reboot and the board comes back as OPNsense:

*** OPNsense.localdomain: OPNsense 25.7 ***

 LAN (lan)      -> dwc0     -> v4: 192.168.1.1/24
 WAN (wan)      -> axge0    -> v4/DHCP

 0) Logout                              7) Ping host
 1) Assign interfaces                   8) Shell
 ...

Step 5 — Move the Install From microSD to eMMC

SD cards die. Once OPNsense is up and you have confirmed it routes traffic, copy the running system to the eMMC. From the OPNsense console pick option 8 (Shell):

# Identify devices: SD is usually mmcsd0, eMMC is mmcsd1
gpart show

# Stop services, snapshot the FS, dd it over (10–15 min)
service nginx stop
dd if=/dev/mmcsd0 of=/dev/mmcsd1 bs=4M status=progress

# Update fstab + bootloader to point at eMMC, then reboot
sed -i '' 's/mmcsd0/mmcsd1/g' /mnt/etc/fstab
reboot

Power off, remove the SD card, power on — boots from eMMC. We have a separate walkthrough on flashing the Rock Pi 4B+ eMMC if you would rather flash the image directly with rkdeveloptool and skip the dd step.

Configuring the Firewall

Default LAN is 192.168.1.1/24 with DHCP serving .100–.245. Plug a laptop into the onboard Ethernet, hit https://192.168.1.1, log in with root / opnsense, and run through the setup wizard. Things we always change:

  • Interfaces → Assignments — confirm axge0 is WAN and dwc0 is LAN (not the other way around — it is easy to flip them).
  • System → Settings → Cron — schedule configd | configctl system update weekly.
  • Services → Unbound DNS — enable DNSSEC, point upstreams at 1.1.1.1 / 9.9.9.9.
  • VPN → WireGuard — for road-warrior access. The Rock Pi 4 handles ~400 Mbit/s of WireGuard, which is more than most home WAN uplinks.
  • Services → Intrusion Detection — enable Suricata on WAN, ET Open ruleset. Stay in IDS (alert-only) mode until you have tuned it for a week.

Performance, Realistically

On a Rock Pi 4B+ (RK3399, 4× A53 + 2× A72, 4 GB DDR4):

  • NAT throughput: ~940 Mbit/s line-rate (limited by the onboard gigabit NIC)
  • WireGuard: 380–420 Mbit/s with AES-NI off (no AES-NI on aarch64)
  • OpenVPN: 90–110 Mbit/s — software crypto is the bottleneck
  • Suricata at 200 Mbit/s WAN: single-CPU pegged at 60–70%; fine for 200/200 fibre, marginal for 500/500
  • Idle power: 3.8 W; full-load NAT ~6.5 W

For a 1 Gbit/s+ symmetric WAN with deep packet inspection, look at an x86 box. For the typical 100–500 Mbit/s home or branch-office WAN, the Rock Pi is comfortable.

Common Gotchas

“The USB NIC is detected but won’t pass traffic.”

The axge driver needs if_axge_load="YES" in /boot/loader.conf. Without it the device shows up but stays at link-down. Realtek RTL8153 adapters (ure driver) have the same trap — load if_ure_load="YES".

“Boot stops at the rainbow square.”

Rainbow square = HDMI firmware loaded, kernel did not start. 19 times out of 20 this is the power supply. Use a known-good 3A USB-C PSU, not a phone charger.

“opnsense-bootstrap fails on package install.”

The script pins to a FreeBSD release. If you ran freebsd-update to a version newer than what the OPNsense tag was built against, pkg refuses the repo. Roll back with freebsd-update -r 14.2-RELEASE upgrade or pick a more recent -r tag for the bootstrap script.

“eMMC boots U-Boot but not OPNsense.”

U-Boot is looking for the kernel on the first FAT partition. If your dd from microSD didn’t include the GPT, redo capturing the full disk including the partition table.

Why a Rock Pi 4 and Not a Pi 4?

You can do most of this on a Raspberry Pi 4 too, but the Rock Pi 4 wins on three things that matter for a firewall:

  • Onboard eMMC — no SD card to corrupt under sustained syslog writes
  • True PCIe x4 — if you outgrow USB Ethernet, drop in a PCIe NIC via the M.2 slot
  • Faster A72 cores — material difference for Suricata and WireGuard throughput

If you want the comparison in detail, see Rock Pi 4B+ vs Raspberry Pi 4 — when to pick which. For an always-on firewall the Rock Pi wins on every axis except community size.

Total bill of materials: Rock Pi 4B+, microSD for staging, a $12 USB gigabit adapter, a 3A PSU. Under $130 all-in for a firewall that will outlive most consumer routers and run patched software for years.