Skip to main content
RunBook Academy

OPNsenseXXXIII · Logging and Remote LoggingLogging architecture

Logging architecture on OPNsense — where the logs come from and where they go

Foundation⏱ ~12 minsyslog-ngconfigctltailgrep

What you'll learn

  • Identify the components that produce logs on OPNsense
  • Trace a log message from producer to syslog-ng to disk to GUI
  • Recognise the default log locations and rotation behaviour
  • Locate the integration points where logs leave the firewall

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-18

Not yet marked complete on this device.

Logging on OPNsense looks simple from the GUI — there are Log Files menus, there are tabs, there is a search box. Underneath there are a dozen components producing messages, syslog-ng routing them by the program that emitted them, one plain-text file per application per day on disk, and integration points where messages leave the firewall for a remote destination. The operator who knows this architecture finds logs faster, configures remote forwarding correctly, and stops guessing about where a given message landed.

One directory per application, one file per day

OPNsense runs syslog-ng as its log daemon. Every local destination follows the same naming convention:

/var/log/<application>/<application>_YYYYMMDD.log

Alongside the daily files, each directory carries a latest.log symlink pointing at the newest one. These are ordinary text files with ordinary permissions — cat, tail -F, grep, awk, and less all work directly on them.

ComponentProgram name syslog-ng matchesLog directory
pf (packet filter)filterlog/var/log/filter/
Firewall subsystem messagesfirewall/var/log/firewall/
System (kernel, daemons, catch-all)everything unmatched at notice and above/var/log/system/
Authentication and auditaudit, plus the auth facility/var/log/audit/
Backend (configd, API)configd.py, api/var/log/configd/
Unbound (DNS resolver)unbound/var/log/resolver/
Dnsmasq (DNS/DHCP)dnsmasq/var/log/dnsmasq/
Kea (DHCP)kea-dhcp4, kea-dhcp6, kea-ctrl-agent, kea-dhcp-ddns/var/log/kea/
IPsec (strongSwan)charon/var/log/ipsec/
OpenVPNopenvpn/var/log/openvpn/
WireGuardwireguard, plus kernel messages naming a wg interface/var/log/wireguard/
Suricata (IDS/IPS)suricata/var/log/suricata/
Gateway monitoringdpinger/var/log/gateways/
Dynamic routingbgpd, ospfd, zebra, olsrd, routed/var/log/routing/
NTPntpd, ntp, ntpdate/var/log/ntpd/
Web GUI serverlighttpd/var/log/lighttpd/
Service watchdogmonit/var/log/monit/
Package managementpkg, pkg-static/var/log/pkg/
Captive portalcaptiveportal/var/log/portalauth/

Plugins add their own destinations the same way, so an installed plugin generally brings a new directory under /var/log/ rather than a new file in an existing one.

The syslog-ng pipeline

Everything on the box logs to the syslog socket. syslog-ng collects all of it into a single source and then splits it with filters. The filters key almost entirely on the program name of the sender, not on the syslog facility.

[ kernel, daemons, plugins, GUI ]
                 |
                 v
       syslog-ng  (source s_all)
                 |
   +-------------+---------------------------+
   |                                         |
   v                                         v
filter by program name                 remote destination(s)
   |                                    UDP / TCP / TLS
   v
/var/log/<app>/<app>_YYYYMMDD.log
   |
   v
GUI Log Files pages (via configd)

A local filter is one small definition per application. The filter for the firewall log is the whole of it:

filter f_local_filter {
    program("filterlog");
};

Anything at notice severity or above that no application filter claims falls through to /var/log/system/. That fall-through is why the system log is the right first stop when you do not know which component produced a message.

Rotation and retention

Rotation is not size-triggered by default and does not produce compressed generations. syslog-ng simply starts a new file when the date changes, and a housekeeping job trims the old ones. That job — configctl syslog archive, listed in the cron picker as “Rotate log files” — runs automatically every hour and does three things per log directory:

  1. If Maximum file size is set and the current file is over it, renames the file with a sequence suffix and restarts syslog-ng so a fresh file starts. Left empty, which is the default, this step never fires and the daily file grows without limit.
  2. Deletes the oldest files beyond Maximum preserved files.
  3. Repoints latest.log at the newest file.

Both settings live under System → Settings → Logging, on the “Local” tab. Maximum preserved files defaults to 31. Because the default is one file per day, that is roughly a month of history per application, held on disk, readable, and greppable.

Read-only / Safedaily files under the retention limit
$ ls /var/log/filter/; echo '---'; du -sh /var/log/filter /var/log/system /var/log/audit
filter_20260715.log  filter_20260726.log  filter_20260806.log
filter_20260716.log  filter_20260727.log  filter_20260807.log
filter_20260717.log  filter_20260728.log  filter_20260808.log
filter_20260718.log  filter_20260729.log  filter_20260809.log
filter_20260719.log  filter_20260730.log  filter_20260810.log
filter_20260720.log  filter_20260731.log  filter_20260811.log
filter_20260721.log  filter_20260801.log  filter_20260812.log
filter_20260722.log  filter_20260802.log  filter_20260813.log
filter_20260723.log  filter_20260803.log  filter_20260814.log
filter_20260724.log  filter_20260804.log  latest.log
filter_20260725.log  filter_20260805.log
---
612M    /var/log/filter
41M    /var/log/system
7.2M    /var/log/audit

Illustrative output

GUI exposure

The GUI does not keep a second copy of anything. Each Log Files page calls into configd, which reads the same files from /var/log/ and returns parsed records.

PageReads
Firewall → Log Files → Live View/var/log/filter/, parsed into named fields, with a live tail
Firewall → Log Files → Plain View/var/log/filter/, as raw lines
Firewall → Log Files → Overview/var/log/filter/, aggregated into counts
Firewall → Log Files → General/var/log/firewall/
System → Log Files → General/var/log/system/
System → Log Files → Backend/var/log/configd/
System → Log Files → Audit/var/log/audit/
System → Log Files → Web GUI/var/log/lighttpd/
System → Log Files → Bootthe boot log

Services with their own logs expose them on their own pages rather than under System — the IPsec log sits under VPN, the resolver log under Services, and so on.

Because the pages and the shell read the same files, the GUI is a genuine search tool over the whole retained window, not a live-only view. What it cannot show you is anything already deleted by the retention limit, which is a different constraint and a much more predictable one.

Read-only / Safethe same backend the GUI uses
$ configctl syslog status; echo '---'; configctl filter read log 1
Checking syslog-ng status. Running
---
[{"rulenr":"7","subrulenr":"","anchorname":"","rid":"02f4bab031b57d1e30553ce08e0ec131","interface":"igb0","reason":"match","action":"block","dir":"in","ipversion":"4","protoname":"tcp","src":"198.51.100.23","dst":"192.0.2.10","srcport":"40254","dstport":"3389","label":"Default deny / state violation rule","__timestamp__":"2026-08-14T16:25:31","__host__":"opnsense.example.com"}]

Illustrative output

Integration points

The points at which logs leave the firewall:

  1. Remote syslog forwarding — the primary one. System → Settings → Logging, “Remote” tab. UDP, TCP, or TLS over IPv4 or IPv6, with optional filters on application, severity, and facility. Forwarding runs in parallel with local storage; it does not replace it.

  2. The API — the same configd calls the GUI uses are reachable over the REST API, returning JSON. Useful for scripted collection and dashboards, not for bulk shipping.

  3. Plugin-specific outputs — some components write their own files outside the syslog-ng scheme and rotate them with newsyslog. Suricata’s EVE JSON at /var/log/suricata/eve.json is the one most estates ship directly to a SIEM; the Squid access log behaves similarly.

  4. The shell — direct read access over SSH. grep, awk, and tail -F over /var/log/<app>/ need no tooling beyond the base system.

What lives where

Quick reference:

NeedWhere to look
“Why is traffic being blocked?”/var/log/filter/, or Firewall → Log Files → Live View
“Did a rule change get applied?”/var/log/firewall/, /var/log/configd/
“Did the system reboot? Why?”/var/log/system/, and dmesg
“Who logged in? Failed logins?”/var/log/audit/
“Did the VPN tunnel come up?”/var/log/ipsec/, /var/log/openvpn/, /var/log/wireguard/
“What did a client resolve in DNS?”/var/log/resolver/ or /var/log/dnsmasq/
“Which client got which lease?”/var/log/kea/ or /var/log/dnsmasq/
“Is a gateway flapping?”/var/log/gateways/
“Did the IDS alert on this?”/var/log/suricata/, and /var/log/suricata/eve.json

Summary

  • OPNsense logs through syslog-ng into plain text, one directory per application, one file per day, plus a latest.log symlink.
  • Routing is by program name, not by syslog facility, and unclaimed messages fall through to /var/log/system/.
  • clog is the pfSense circular-log tool. It is not how OPNsense stores or reads logs.
  • Retention is Maximum preserved files under System → Settings → Logging, defaulting to 31 files, which is about a month. It bounds the file count, not the disk footprint.
  • The GUI, the API, and the shell all read the same files through configd.
  • Remote syslog forwarding is the integration point for centralised retention.

Knowledge check · 3 questions

  1. Q1. An operator is investigating why traffic is being blocked and wants the packet records pf wrote. Which path holds them?

  2. Q2. With default settings, OPNsense keeps roughly a month of firewall log history on disk, and the size of that history depends on how much traffic is logged.

  3. Q3. Which of the following are valid ways to get at OPNsense log data? Select all that apply.

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