Skip to main content
RunBook Academy

OPNsenseIV · OPNsense ArchitectureOPNsense architecture

FreeBSD as the base — services, rc.d, and what the operator notices

Foundation⏱ ~14 minservicesysrcsysctlpkg

What you'll learn

  • Identify what OPNsense inherits from FreeBSD and what it adds on top
  • Read the FreeBSD rc.d service framework as it appears on an OPNsense system
  • Explain the kernel-level differences from Linux that an operator encounters
  • List the FreeBSD diagnostic commands the operator will use most often

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

OPNsense is a FreeBSD system with a PHP web front-end, a curated package set, and a generated PF ruleset on top. There is no hidden layer between the operator and the FreeBSD base — when the operator opens a shell on an OPNsense appliance, the commands are FreeBSD commands and the behaviour is FreeBSD behaviour. Operators with a Linux-only background find this disorienting for the first day; operators with a FreeBSD background find it liberating.

This lesson covers what OPNsense inherits from FreeBSD (almost everything), how FreeBSD services actually start (rc.d and the booting process), and the differences from Linux that the operator notices in daily work.

What OPNsense is, structurally

A running OPNsense appliance has four layers, each with a clear responsibility:

  1. HardenedBSD 14.x kernel and base system. The kernel boots, detects hardware, mounts filesystems, brings up interfaces, and provides the socket stack, the routing table, PF, and the network drivers.
  2. FreeBSD userland. The standard FreeBSD utilities — ifconfig, netstat, route, pfctl, sockstat, pkg, sysctl, vmstat, dmesg, tcpdump, ngctl — all present, all behaving as they do on FreeBSD.
  3. OPNsense core. A collection of PHP scripts that read the config XML and translate it into FreeBSD-native configuration (PF ruleset, rc.conf parameters, Unbound config, ISC DHCP config, IPsec strongSwan config, CARP VIPs). The PHP code lives under /usr/local/sbin/ and the web framework is /usr/local/opnsense/.
  4. OPNsense plugins. Optional packages (WireGuard, IPsec, Suricata, FRR, OpenVPN) that follow the same pattern: PHP code in /usr/local/opnsense/, config in the same XML, generated service config under /var/.../.

The operator’s shell access is at layer 1–2; the web GUI and API are at layer 3. The boundary between them is the config XML — every GUI change becomes an XML edit, every XML edit (through the supported path) is applied by the PHP layer and propagated to FreeBSD services.

Read-only / Safe/usr/local/opnsense/
$ ls /usr/local/opnsense/
COPYING.md
README.md
Scripts
Service
UPLOAD.htm
Versions
bin
conf
contrib
mvc
service
services
src

Illustrative output

The FreeBSD booting model and rc.d

FreeBSD does not use systemd. It uses the older rc.d framework, which is a collection of shell scripts under /etc/rc.d/ and /usr/local/etc/rc.d/. Each script declares its dependencies (require, provide, before, after), what it provides (REQUIRES, PROVIDES), and how to start, stop, reload, and status-check its service.

The boot sequence reads /etc/rc.conf for variables that control which services are enabled (nginx_enable="YES", sshd_enable="YES", and so on), then walks the dependency graph from the enabled services and starts each one in order.

OPNsense manages rc.conf for the operator. The PHP scripts write the right variables when a service is enabled in the GUI, and the operator sees the result at the shell:

Read-only / Safeservice nginx status
$ service nginx status
nginx is running as pid 1138.
nginx: ready (no errors)

Illustrative output

rc.d, sysrc, and the boot-time variables

rc.conf is the file that controls which services start at boot. The variables follow a strict convention: <service>_enable="YES" or "NO". The sysrc command is the safe way to edit rc.conf from the shell — it parses the file, preserves comments, and either replaces an existing variable or appends a new one.

Read-only / Safesysrc -n
$ sysrc -n nginx_enable
YES

Illustrative output

The dependency graph that rc.d walks at boot matters for production. The boot order on a typical OPNsense box is:

kernel → zfs/ufs → mountcrit → var → dev → fsclean →
   → network → routing → pfsync → pf → opnsense-bootstrap →
      → syslog-ng → unbound → nginx → ...

If pf fails to start (bad ruleset, missing table file), the boot process continues past pf and OPNsense’s services come up without firewalling — the appliance is up but not protected. Always check service pf status after any reboot or any ruleset edit. The lesson on lockout prevention covers this in the context of remote management.

The FreeBSD vs Linux differences the operator notices

A list of differences that show up in operational work. None of these are better or worse than Linux; they are what the operator encounters.

ConceptFreeBSDLinux
Service frameworkrc.d shell scriptssystemd units
Default firewallPF (also ipfw, npf)nftables (or legacy iptables)
Network configifconfig, route (newer commands alongside)iproute2 (ip, ss, tc)
Package managerpkg (binary)apt, dnf, pacman (distribution-specific)
FilesystemUFS or ZFS (OPNsense uses ZFS)ext4, xfs, btrfs (distribution-specific)
Process infops, top, procstatps, top, /proc/<pid>/...
Memory infovmstat, sysctl hw.physmem, systat -vmfree, /proc/meminfo
Socket infosockstat, netstatss, netstat
Kernel moduleskldstat, kldload, /boot/loader.conflsmod, modprobe, /etc/modules-load.d/
Live patchinglimitedlivepatch (depending on distro)
Container modeljailscgroups/namespaces

The diagnostic toolkit the operator uses

A short list of FreeBSD commands that appear repeatedly in production. The course uses each of these elsewhere; the lesson records what each one is for.

CommandPurpose
pfctl -s statePF state table (active flows)
pfctl -s rulesPF ruleset loaded into the kernel
pfctl -s tablesPF tables (alias contents)
pfctl -s AnchorsPF anchors (loaded sub-rulesets)
netstat -rnRouting table (FIB)
netstat -anListening sockets
sockstat -cActive connections per process
ifconfig <iface>Interface status, addresses, counters
sysctl net.inet.ip.forwardingIP forwarding toggle
sysctl -a | grep net.inetAll network tunables
vmstat 1Memory, CPU, paging every second
systat -vmstat 1FreeBSD’s classic top-like view
dmesgKernel ring buffer (last boot)
procstat -v <pid>Process memory map and open files
service <name> statusService state
tail -F /var/log/system/latest.logFollow the system log
tcpdump -ni <iface>Packet capture
pkg infoList installed packages
pkg audit -FList known vulnerabilities in installed packages

The operator does not need to memorise the entire list. The course brings each command up when it is the right diagnostic tool for the problem at hand.

Summary

  • OPNsense is FreeBSD (HardenedBSD) + PHP framework + plugins. The operator’s shell is a FreeBSD shell.
  • FreeBSD uses rc.d, not systemd. Services are started by shell scripts that declare dependencies. rc.conf controls what is enabled.
  • The OPNsense bootstrap step runs late in the boot and is the step that applies the GUI config to FreeBSD services. If the web GUI does not come up, check opnsense-bootstrap in the system log.
  • The FreeBSD vs Linux differences that matter operationally are: service framework, default firewall, network config toolset, package manager, filesystem, and process/socket inspection commands.
  • The diagnostic toolkit is the FreeBSD toolkit. The course brings each command up in context.

Knowledge check · 3 questions

  1. Q1. You need to enable an OPNsense-supported daemon and have full shell access. What is the supported way to enable it so the change survives a reboot and a future GUI apply?

  2. Q2. OPNsense uses systemd as its service framework, like most modern Linux distributions.

  3. Q3. Which of the following statements correctly describe FreeBSD vs Linux differences that an OPNsense operator encounters daily? Select all that apply.

Passing score: 75%. Answers are checked in this browser.