Synopsis #
Collect PF logs with pflogd(8) , export connection summaries with pflow(4) , query system counters with snmpd(8) , and forward logs with syslogd(8) . Use these records to diagnose failures, monitor capacity, and investigate security events.
Design Considerations #
- Clocks and identity. Accurate time is mandatory for correlation. Run ntpd(8) and ensure unique hostnames and stable IP sources for telemetry.
- Scope and privacy. Only log and export what you can store and protect. Avoid full packet payloads unless explicitly justified. Prefer sampled or flow-level telemetry for aggregate visibility.
- Separation of concerns. Collect data on the firewall or router. Use separate systems for heavy analysis, long-term storage, and dashboards.
- Network paths. Place collectors on dedicated management networks or via isolated VPNs. Protect UDP-based feeds (for example, NetFlow) from loss and spoofing.
- Version caveats. pflow(4) supports NetFlow v5 and IPFIX (version 10). Select the format accepted by the collector.
- Rotation and retention. Size
/varand set appropriate rotation in newsyslog.conf(5). Send logs to another system; do not rely only on local disks.
Configuration #
1) Packet filter logging (pflog) #
Enable targeted logging in pf.conf(5)
. The log keyword on a rule emits metadata to pflog0, which pflogd(8)
stores as a rotating pcap at /var/log/pflog.
## /etc/pf.conf — excerpt with rule logging
set skip on lo
wan = "em0"
lan = "em1"
lan_net = "10.10.10.0/24"
block all
# Log blocked unsolicited WAN traffic
block log on $wan
# Log SSH admin access attempts to the firewall
pass log on $wan proto tcp to ($wan) port 22 keep state
# Allow and log HTTPS from LAN to anywhere (for demo; tighten for production)
pass in log on $lan proto tcp from $lan_net to any port 443 keep state
pass out on $wan proto tcp from $lan_net to any port 443 keep state
Apply the policy and ensure pflogd is enabled:
doas pfctl -f /etc/pf.conf
# Atomic reload of PF rules
doas rcctl enable pflogd
# Start pflog capture on boot
doas rcctl start pflogd
# Launch now; writes /var/log/pflog
doas tcpdump -n -e -ttt -i pflog0
# Live view of PF log stream (Ctrl-C to stop)
Use
pfctl -vvsrto see which rules carrylogand to inspect per-rule counters.
2) Flow export with pflow(4) (NetFlow v5 and IPFIX) #
pflow(4)
exports summaries of PF state traffic to a remote collector over UDP. Configure a pflow0 interface with a stable source address, collector destination (IP:port), and protocol version.
Assumptions:
- Export source:
192.0.2.10(loopback or a management address) - Collector:
192.0.2.50:2055(NetFlow) - Protocol: IPFIX (10)
doas ifconfig pflow0 create
# Create the exporter interface
doas ifconfig pflow0 flowsrc 192.0.2.10 flowdst 192.0.2.50:2055 pflowproto 10
# Set source, destination, and NetFlow version
doas ifconfig pflow0 up
# Activate exporter
doas ifconfig pflow0
# Verify parameters
Only states created with keep state (pflow) are exported. Add this option to the pass rules for traffic to collect; existing states need to expire before the new option applies.
Permit the export path in PF (replace em0/addresses as needed):
## /etc/pf.conf — allow pflow export to collector
set skip on lo
wan = "em0"
pass out on $wan proto udp from 192.0.2.10 to 192.0.2.50 port 2055 keep state
Reload and confirm with a packet capture toward the collector:
doas pfctl -f /etc/pf.conf
doas tcpdump -ni em0 host 192.0.2.50 and udp port 2055
# Observe flow export packets; verify at the collector side as well
If your collector expects IPFIX, check pflow(4) on OpenBSD 8.0 for IPFIX support and template options, then switch
pflowprotoaccordingly.
3) System telemetry with snmpd(8) #
snmpd(8) exposes standard MIBs (interfaces, system, sensors). Bind it to a management interface and restrict access. The exact model (community vs. SNMPv3) depends on your security policy; SNMPv3 is recommended where supported by your tooling.
Minimal example: listen on LAN and allow read-only queries from 10.10.10.0/24.
## /etc/snmpd.conf — minimal read-only service
listen on 10.10.10.1 read snmpv2c
system contact "netops@example.com"
system location "DC1-R1"
read-only community "monitoring"
Restrict UDP 161 to the monitoring subnet in PF; the community directive has no source-prefix argument. The example uses SNMPv2c, whose community is transmitted without encryption.
doas rcctl enable snmpd
doas rcctl start snmpd
doas pkill -0 snmpd && echo "snmpd running"
# Basic liveness check
Consult snmpd.conf(5) for SNMPv3 user configuration and trap receivers. Ensure PF permits UDP 161 from your NMS and any trap egress (UDP 162).
4) Central log shipping with syslogd(8) #
Forward local logs to a remote collector using syslog.conf(5)
. UDP forwarding uses a single @ before the host.
## /etc/syslog.conf — forward everything to a collector and keep local files
*.* @192.0.2.60
# Keep existing local file rules below (trim to your needs)
auth.info /var/log/authlog
daemon.info /var/log/daemon
kern.info /var/log/kernlog
doas rcctl reload syslogd
# Re-read configuration; syslogd sends to 192.0.2.60:514/udp
logger -t test "syslog forwarding test $(date)"
# Send a test message; verify it arrives at the collector
Base syslogd also supports
@tcp://host:portand@tls://host:portdestinations; configure certificate trust and collector requirements as described in syslog.conf(5). Keep/etc/newsyslog.conftuned for local retention.
Verification #
- PF rule counters and logs with pfctl(8) and live pflog:
doas pfctl -vvsr | egrep 'log\b'
# Confirm which rules log and observe counters increasing
doas tcpdump -n -e -ttt -i pflog0
# Live packet logs for validation during tests
doas tcpdump -nr /var/log/pflog | head
# Inspect the rotated capture file
- pflow export on the wire:
doas tcpdump -ni em0 host 192.0.2.50 and udp port 2055
# Confirm NetFlow/flow export packets leaving the router
- SNMP reachability (from NMS or a test host):
snmp get -v 2c -c monitoring 10.10.10.1 sysUpTime.0
# Basic liveness; substitute v3 commands if applicable
- syslog forwarding path:
logger -t probe "forward-test $(date)"
# Emit a message and confirm it arrives at 192.0.2.60
tail -n 5 /var/log/messages
# Local copy remains available per syslog.conf
- Dashboards: use systat(1)
pfandifstatmodes during rollout to correlate queueing, rule hits, and interface rates with exported telemetry.
Troubleshooting #
- No pflog records. Ensure rules contain
log, PF is loaded, and pflogd(8) is running. Usetcpdump -i pflog0to bypass files and validate the stream. - Collector does not see pflow. Verify
flowsrc/flowdst/pflowprotoonpflow0, that PF permits UDP to the collector, and that intermediate ACLs allow it. Confirm time sync; some collectors drop excessively skewed timestamps. - High pflow loss. Flow export is best-effort over UDP. Dedicate a management path, or deploy a closer collector. Ensure CPU is not saturated during bursts.
- SNMP timeouts. Confirm
listen onaddress and PF source restriction match the NMS. Verify PF allows UDP 161 from the NMS and that community or v3 credentials are correct. - Syslog not forwarding. Check syntax in
/etc/syslog.conf, reloadsyslogd, and confirm reachability to the collector’s UDP 514. If the collector requires TCP/TLS, use its supported ingestion method. - Disk pressure in /var. Increase rotation frequency in newsyslog.conf(5) and export logs/flows off-box. Consider excluding noisy facilities or raising thresholds.
See Also #
- Networking
- OpenBGPD
- Related: QoS and Traffic Shaping
- Related: Network Services at Scale
- Related: Troubleshooting Playbooks