CyberCLI
← All connectors

OPNsense

Free · OSS

Firewall

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.

TA0001 · Initial Access TA0008 · Lateral Movement TA0010 · Exfiltration TA0011 · Command & Control
See the full coverage matrix →

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

Same perimeter visibility as pfSense — a drop-in if your team runs OPNsense.
Catches the scan-then-connect pattern of an attacker mapping your perimeter.
Flags an unauthorized firewall-rule change after an admin account is popped.

What you'd see in CyberCLI

illustrative
CYCON 3 high OPNsense

Same 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 math
Fields normalized
19
parsed from the source event
Event categories
with on-disk fixtures
Trust Ladder
L0 → L4
AI authorization range

pfSense'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

AI can authorize
  • ·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
Requires human approval
  • ·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. 1 Enable remote syslog on OPNsense (System → Settings → Logging / targets).
  2. 2 Point it at the CyberCLI syslog endpoint.
  3. 3 Run `cybercli onboard pfsense` — OPNsense reuses the pfSense pack (same filterlog format).
  4. 4 Confirm events in the dashboard's Connectors panel.
Install / activate
Download ISO from opnsense.org · install to bare-metal or VM

Real Onboarding Manual

v1.0 — 2026-06-18
Tested with
pfSense CE 2.7.xpfSense Plus 23.05+OPNsense 23.7+ (uses the same filterlog format → reuses this pack)
What good looks like

Within 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

  1. 1
    pfSense + 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
  2. 2
    Vector 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

  1. 1
    Onboard the connector in CyberCLI first
    On 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 CyberCLI
    Usually 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 this

    Same 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.

  2. 2
    Enable Remote Syslog in pfSense
    pfSense 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
    IPv4
    Vector accepts both; pick whichever your CyberCLI host has reachable.
    Remote log servers
    <cybercli-host-ip>:514
    One 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.
  3. 3
    Save + apply
    Same 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. 1

    Confirm packets reach the substrate

    sudo tcpdump -nni any 'src host <pfsense-LAN-IP> and udp dst port 514' -c 5
    You should see
    IP <pfsense-LAN-IP>.<src-port> > <cybercli-host>.514: ... length <varies>
    If this fails

    If 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. 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 fails

    If 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
Why it happens

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.

How to fix it

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
Why it happens

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.

How to fix it

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
Why it happens

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.

How to fix it

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
Why it happens

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.

How to fix it

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
Why it happens

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.

How to fix it

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?
Not in v1. The syslog pack is read-only by design. v1.x will add a Paladin-driven executor lane that uses pfSense's XML-RPC API to suspend a noisy rule or block an IP, gated behind the Trust Ladder.
What about Suricata events from pfSense's IDS package?
If you run Suricata inside pfSense, its alerts come through filterlog as normal firewall events — the pfsense pack captures them. For deeper Suricata-specific fields (signature ID, severity), onboard suricata separately with `cybercli onboard suricata` pointed at the same IP.
Encrypted syslog (TLS) from pfSense?
pfSense supports TLS syslog forwarding as of 2.7. Vector listens on TCP 6514 with TLS. You can switch the Remote log servers entry to tls://<cybercli>:6514 — but verify the cert chain CyberCLI uses matches what pfSense will trust. Most operators leave it plain UDP on internal VLANs.
Guild roles it feeds
  • Warden (triage)
  • Knight (detection)
The Guild →
Sovereignty

Fully local. OPNsense ships logs to CyberCLI over your own network.

Go deeper