OPNsense
Free · OSSFirewall
pfSense's faster-moving fork — same perimeter ground truth.
OPNsense homepage ↗pfSense's actively-maintained fork with a faster release cadence. Drop-in equivalent — same filterlog format, same rule semantics. Pick whichever your team prefers.
What it watches
- Firewall block/allow events (filterlog)
- Port-scan + sweep patterns at the edge
- VPN connection + authentication events
- Rule + config changes on the firewall
- Outbound connections to flagged destinations
MITRE ATT&CK coverage
Tactics this connector gives CyberCLI visibility into.
Every alert this connector surfaces
1 event type
Every matrix-covered event_type on the passthrough lane — pinned by the engine's coverage matrix.
The right column shows the operator-friendly phrase the dashboard renders. High-severity
AI-lane signals are summarized in What it watches above (Warden + Herald
handle those); the rest take the substrate's passthrough lane (no AI tokens burned).
| event_type | dashboard renders |
|---|---|
| firewall | Firewall activity on pfsense |
What it helps you catch
What you'd see in CyberCLI
illustrativeSame perimeter visibility as pfSense — a drop-in if your team runs OPNsense.
Routed to Warden (triage) → Knight (detection)
⛓ every step hash-chained · replayable
What CyberCLI reads from OPNsense
audit our mathpfSense's filterlog daemon emits one positional-CSV syslog line per packet that hits a logged pf rule — block or pass, no key=value. The 19 fields we read carry the invariant head (rule_id, pf_subrule, pf_anchor, pf_tracker, interface, pf_reason, action, direction, ip_version) and the IP-version-forked tail (proto, src_ip, dst_ip, src_port, dst_port, tcp_flags or icmp_type). Blocks land at rule_level 5; pass is kept for forensics but digest-suppressed. Enough to answer which rule fired on which interface, who tried to reach what, and over which L4.
Full field index · 19 fields ↓
.action.cybercli_class.cybercli_low_signal.cybercli_parse_status.cybercli_wire_format.direction.dst_ip.event_id.event_timestamp.interface.ip_version.pf_anchor.pf_reason.pf_subrule.pf_tracker.proto.rule_id.rule_level.src_ip MITRE techniques typically mapped
Trust Ladder ceiling · L0 → L4
- ·L0–L2: digest block events, notify Herald on rule-firing bursts and novel src_ip, summarize the per-interface block pattern for the case
- ·L3 (Knight verification): geo-IP + reputation lookup on src_ip, correlate the 4-tuple with concurrent Suricata/Zeek/UniFi flows, pivot pf_tracker across related packets — read-only
- ·L4 (Paladin containment, Pro+): src_ip block via pfsense.add_alias_entry into a pf table referenced by a deny rule — surface exists, every L4 firing requires operator sign-off
- ·L5+: rule/anchor edits, interface or NAT changes, pfBlockerNG list edits — perimeter policy stays operator-owned
- ·Any change touching the WAN gateway, VPN tunnels, or the management interface itself
Full ladder semantics · /trust →
Field count + sample event auto-derived from src/cybercli/connectors/opnsense/vector.vrl at build time. Numbers update the moment the engine's parser changes — no drift.
Close more of the kill chain
OPNsense covers 4 of 14 ATT&CK tactics. Pair it with these to widen coverage:
How to connect
- 1 Enable remote syslog on OPNsense (System → Settings → Logging / targets).
- 2 Point it at the CyberCLI syslog endpoint.
- 3 Run `cybercli onboard pfsense` — OPNsense reuses the pfSense pack (same filterlog format).
- 4 Confirm events in the dashboard's Connectors panel.
Download ISO from opnsense.org · install to bare-metal or VM
Real Onboarding Manual
v1.0 — 2026-06-18Within 30 seconds of toggling Remote Syslog on, you see pfSense filterlog lines arriving at the CyberCLI syslog substrate (port 514 UDP), parsed by the filterlog VRL into structured fields (src_ip, dst_ip, proto, action), and the first block/allow event appears in the dashboard under cybercli_connector=pfsense.
Pre-flight
- 1pfSense + CyberCLI host can route to each other on UDP 514
pfSense IS the firewall — so its own rules govern whether it can reach the CyberCLI host. By default a freshly-deployed pfSense has the LAN-to-LAN permit but no explicit rule for the syslog destination, which works only if both endpoints are on the same LAN interface. Cross-VLAN deployments need an explicit allow.
ping <cybercli-host-ip> # from pfSense's Diagnostics → Ping
- 2Vector substrate is up on the CyberCLI host
If `cybercli setup install-syslog` hasn't been run, port 514 isn't bound. pfSense's syslog client retries silently — you'd configure everything correctly but see zero events.
sudo ss -lnup | grep :514
Configure
- 1Onboard the connector in CyberCLI firstOn your CyberCLI host
The CyberCLI side primes the VRL pack + the source-IP guard before pfSense starts forwarding — otherwise the first packets get aborted at the guard stage before they can be parsed.
- command
-
cybercli setup add-syslog-source --connector pfsense --source-ip <pfsense-LAN-IP> - source-ip
-
The pfSense IP on the VLAN that reaches CyberCLIUsually the LAN-side IP, e.g. 192.168.1.1. If pfSense is on a different VLAN than CyberCLI, this is whichever IP pfSense uses as src when reaching the CyberCLI host.
Why thisSame lesson as UniFi — the source IP on pfSense's syslog packets is the outbound-interface IP, which may not be the management IP. The VRL guard aborts non-matching sources silently. Pass the egress IP, not the management URL host.
- 2Enable Remote Syslog in pfSensepfSense web UI → Status → System Logs → Settings (tab)
Scroll to the 'Remote Logging Options' section near the bottom. Enable remote logging + tick the categories you want forwarded — at minimum: Firewall Events (filterlog) is what we care about for v1.
- Send log messages to remote syslog server
-
checked - Source Address
-
Default (any)Leave default unless you have a specific outbound IP you want to pin. CyberCLI's source guard is single-IP per onboard, so pinning here is optional. - IP Protocol
-
IPv4Vector accepts both; pick whichever your CyberCLI host has reachable. - Remote log servers
-
<cybercli-host-ip>:514One server per line. Port 514 is default — Vector listens here. - Firewall events
-
checked (required)This is the keystone event class — filterlog blocks + allows. Without this, the pfSense connector is silent. - DHCP events
-
checked (optional)Useful for correlating client identity but noisy on busy networks. - VPN events
-
checked (recommended)OpenVPN/IPsec auth events surface here — high value.
- 3Save + applySame page · bottom · Save
Save commits the config. pfSense applies it immediately + restarts syslogd as part of the save — no separate reload needed. Watch the CyberCLI side with tcpdump to see the first packets arrive.
Verify
- 1
Confirm packets reach the substrate
sudo tcpdump -nni any 'src host <pfsense-LAN-IP> and udp dst port 514' -c 5
You should seeIP <pfsense-LAN-IP>.<src-port> > <cybercli-host>.514: ... length <varies>
If this failsIf 0 packets: either Remote Syslog isn't actually enabled (re-check the checkbox, hit Save), the source-IP on pfSense's outbound is different from what you typed (run tcpdump without the src filter and see what shows up), or an upstream firewall rule blocks UDP 514.
- 2
Confirm filterlog parses into structured events
sudo zcat /var/opt/cybercli/syslog/events/pfsense-<source-ip>/$(date +%Y-%m-%d).ndjson.gz | tail -1 | python3 -m json.tool
You should see"cybercli_connector": "pfsense", "cybercli_wire_format": "pfsense_filterlog", "action": "block"
If this failsIf packets arrive but events file is empty: VRL guard is aborting them. Source IP on the packet doesn't match the --source-ip you passed. Inspect with tcpdump -X and re-run `cybercli setup add-syslog-source --connector pfsense --source-ip <correct-ip> --force`.
Pitfalls (what bit us so it doesn't bite you)
▸ pfSense's source IP is the OUTBOUND interface IP, NOT the management IP
Same family as UDM-Pro 9.x. If pfSense is on its own VLAN and CyberCLI is on a different VLAN, pfSense uses the interface IP toward the CyberCLI host as src. Operators type the management IP into the source-IP guard, VRL aborts everything, events vanish.
Find the egress IP: from pfSense Diagnostics → Routes, find the route to your CyberCLI host's subnet. The 'Gateway' or interface IP for that route is the src that pfSense will use. Pass that to `--source-ip`. Or use multi-IP form: `--source-ip <mgmt>,<egress>`.
▸ Don't enable 'Everything' — it'll drown Warden
pfSense's Remote Logging Options has a tempting 'Everything' checkbox that ships every category. On a busy network this is thousands of events per second, most of which are DHCP renews + ARP chatter that consume Warden context with zero signal value.
Tick Firewall, VPN, and IPsec (if you use it) at minimum. Add DHCP only if you need client-identity correlation. Skip the rest unless you have a specific use case — you can always add more later.
▸ filterlog uses different field offsets for IPv4 vs IPv6 vs ICMP
pfSense's filterlog format has an offset asymmetry: position 8 is `src_ip` for IPv4 + TCP/UDP but `src_addr_v6` for IPv6 + TCP/UDP, and ICMP packs an additional sub-protocol code into positions 12-13 shifting everything after. The CyberCLI VRL pack handles all three forks transparently, but if you're inspecting raw events expecting a flat schema, you'll see different fields populated based on packet type.
Operationally: nothing to do, the pack handles it. If you're writing custom downstream queries that filter on src_ip: include both IPv4 + IPv6 address fields, or filter on the normalized `cybercli_src_ip` field that the VRL pack sets consistently regardless of protocol fork.
▸ OPNsense uses this same pack — pass --connector pfsense
OPNsense forked from pfSense + kept the filterlog format byte-for-byte identical. The CyberCLI pack handles both with one VRL. But the CLI does require `--connector pfsense` even when onboarding OPNsense — the alias is resolved before the conf.d render.
Just use `cybercli setup add-syslog-source --connector pfsense --source-ip <opnsense-ip>` and don't worry about it — the engine handles the alias internally. Memorize: pfsense pack covers both flavours at the wire.
▸ pfSense 2.6+ moved the syslog page — older guides will get you lost
In pfSense 2.5 + earlier the Remote Logging Options lived under Status → System Logs → Remote Logging (a dedicated tab). 2.6 reshuffled them into Status → System Logs → Settings as a section near the bottom of a longer page. Operators following older blog posts go looking for the missing tab.
On 2.6 and later: Status → System Logs → Settings (the existing first tab) → scroll DOWN past the General Logging Options to the Remote Logging Options section. Same fields, different page.
Troubleshoot
▸ Symptom: Remote Syslog enabled but tcpdump shows 0 packets
Cause: Either Save was clicked but syslogd didn't reload, the remote log server field has a typo, or pfSense's own firewall is blocking outbound UDP 514 (rare but possible if you've hardened the LAN_OUT rules).
Fix: Diagnostics → Command Prompt → `service syslogd restart` to force a reload. Verify the server field via 'Display Logs' page (it shows the active remote config). Check Firewall → Rules → LAN for any outbound deny.
▸ Symptom: Packets arrive but events file is empty
Cause: VRL source-IP guard aborting (mismatch between configured guard IP and packet src).
Fix: tcpdump with -X to see actual src IP. Re-run add-syslog-source with correct IP (or multi-IP comma list).
▸ Symptom: Events arrive but cef_parse_status=raw_passthrough
Cause: filterlog format detection failed — pfSense is emitting a non-standard log line, possibly because you enabled a category that isn't filterlog (e.g. raw DHCP server logs).
Fix: Disable the non-filterlog categories. Firewall events should always parse; if they don't, file a bug — the pack ships unit-tested against the current filterlog grammar.
FAQ
▸ Can CyberCLI push rule changes back to pfSense?
▸ What about Suricata events from pfSense's IDS package?
▸ Encrypted syslog (TLS) from pfSense?
Fully local. OPNsense ships logs to CyberCLI over your own network.