Documentation Overview
Welcome to the Firewall-Mon documentation center. Firewall-Mon is a vendor-agnostic, high-performance firewall fleet monitoring system. It provides real-time SNMP status polling across eight vendor families, multi-protocol flow analytics (sFlow, NetFlow v5/v9, and IPFIX with denied-flow visibility), trap routing, and security-classified config drift logging in a unified dashboard — with role-based access control and optional two-factor authentication.
Product Posture
Unlike general Network Management Systems (NMS) which offer generic OID walks and massive configuration tables, Firewall-Mon is designed strictly firewall-first. It provides immediate, out-of-the-box visibility into CPU/ASIC chips, interface states, dynamic VPN tunnels (IPsec, SSL, dialup), High Availability (HA) cluster health, and environment sensors.
Key Project Roots
Firewall-Mon is a TechnicalLabs open-source project created by Xphox of Xphox Networks. It is released under the permissive MIT license and can be fully self-hosted within a single container in under 30 seconds.
Need Immediate Installation?
You can start the server locally using our single command line repository builder:
git clone https://github.com/xphox2/Firewall-Monitoring.git && cd Firewall-Monitoring && docker compose up -d
View Quick Start Steps →
Architecture Specification
Firewall-Mon operates as a cooperative process bundle sharing a single PostgreSQL 16 database. Devices are monitored either directly (polled over SNMP by the central server) or remotely (polled by local probe daemons relaying telemetry over outbound HTTPS).
Component Data Flow (Web-Native Flowchart)
The diagram below displays how the daemons, database layers, edge probes, and notification channels coordinate telemetry ingest.
firewall-collector → Relayed via HTTPS POST (idempotent batches) to fwmon-api.
Interactive Sequence Flow Player
Select a lifecycle flow tab below to view how requests, handshakes, and database updates interact sequentially.
X-Probe-Batch-ID header ensures that network retries are strictly idempotent.Database Concerns Layout
| Concern | Internal Package Path | Description |
|---|---|---|
| HTTP Handlers | internal/api/handlers/ |
Gin routes handling public statistics, probe relay uploads, and admin panel commands. |
| SNMP Engine | internal/snmp/ |
SNMPv2c/v3 client calls and vendor OID parsing profiles. |
| Database Migrations | internal/database/ |
PostgreSQL/SQLite DDL migrations and raw GORM connection hooks. |
| Alert Rules | internal/alerts/ |
Threshold matching policies and cooldown timers. |
| Config Parser | internal/configdiff/ |
Normalizes configuration files and classifies drift severity. |
Release Changelog
Tracking the development of the Firewall-Mon monitoring system core from the verified releases. Semantic versioning is strictly followed.
xphox/firewall-mon, xphox/firewall-collector), plus a Prometheus scrape pack and a prebuilt Grafana dashboard. Continuous engineering audits keep open findings at zero.
drops column to older flow_samples tables (Migration v10). This prevents the probe sync engine from re-queueing flow packets indefinitely due to missing column database constraints (SQLSTATE 42703).
ENCRYPTION_KEY can successfully decrypt credentials. Toggles health probes to 503 if unreadable.
SafeGo), containing crashes to the local process instead of aborting the server container.
FortiGate SNMP Setup Guide
Configure your FortiGate firewall to export metrics and relay SNMP Traps directly to the Firewall-Mon collector.
1. Enable SNMP
Via Web Console GUI
- Log in to the FortiGate dashboard interface.
- Navigate to System > SNMP.
- Toggle SNMP to Enabled.
- Add an SNMP Community (e.g. Version
v2c, namepublic).
Via CLI Command Line
config system snmp
set status enable
config community
edit 1
set name "public"
set status enable
next
end
end
2. Enable SNMP Trap Ingestion
To receive instant warnings during HA master failovers, VPN tunnel changes, and IPS alarms, route traps to port 162 on your Firewall-Mon host:
config system snmp
config trapd
edit 1
set ip <your-firewall-mon-server-ip>
set port 162
set status enable
next
end
end
Supported System Metrics (OID Details)
| OID Identifier | MIB Name | Description |
|---|---|---|
.1.3.6.1.4.1.12356.101.4.1.3 |
fgSysCpuUsage | CPU load percentage. |
.1.3.6.1.4.1.12356.101.4.1.4 |
fgSysMemUsage | RAM memory usage percentage. |
.1.3.6.1.4.1.12356.101.4.1.8 |
fgSysSesCount | Active concurrent firewall sessions count. |
.1.3.6.1.4.1.12356.101.13.1.1 |
fgHaMode | Active High Availability cluster operational mode. |
FortiGate sFlow Setup Guide
Configure sFlow v5 on your FortiGate firewall to export raw conversation-level packet telemetry to the Firewall-Mon flow analyzer on port 6343.
1. Configure the Global sFlow Collector
FortiOS sFlow parameters are configured globally via the CLI. Define the IP address of your Firewall-Mon server and set the sFlow collector port to 6343:
config system sflow
set collector-ip <your-firewall-mon-server-ip>
set collector-port 6343
end
2. Enable sFlow on Specific Interfaces
sFlow samples traffic packets on a per-interface basis. You must enable the sFlow sampler on any interface you wish to monitor (e.g. WAN or LAN ports):
config system interface
edit "port1"
set sflow-sampler enable
set sample-rate 512
set sample-direction both
next
end
Configuration Parameter Details
| Parameter | Recommended Value | Description |
|---|---|---|
sample-rate |
512 to 2048 |
The packets-to-samples ratio. For example, 512 means 1 out of every 512 packets is sampled. Widen for high-bandwidth links to reduce CPU load. |
sample-direction |
both |
Toggles traffic direction monitoring. Supports both, rx (inbound only), or tx (outbound only). |
3. Test sFlow Traffic Reception
Verify sFlow datagrams are successfully leaving your firewall and reaching the server host:
# Run on the Firewall-Mon server host to inspect incoming sFlow packets
sudo tcpdump -i any port 6343 -nn
FortiGate NetFlow Setup Guide
Configure NetFlow v9 on your FortiGate to export session-level flow records to the Firewall-Mon server or remote Firewall-Collector on port 2055. NetFlow complements sFlow: it carries complete, unsampled session accounting — every session with exact byte/packet counts and timing — that packet-sampled sFlow cannot provide. (Denied traffic is the exception: FortiOS reports it via syslog, not NetFlow — see section 3.)
1. Point NetFlow at the Collector
On FortiOS 7.0 / 7.2 the collector is configured with flat fields:
config system netflow
set collector-ip <your-collector-or-server-ip>
set collector-port 2055
set active-flow-timeout 60
set inactive-flow-timeout 15
end
On FortiOS 7.4 and later the flat fields were replaced by a collector table:
config system netflow
config collectors
edit 1
set ip <your-collector-or-server-ip>
set port 2055
next
end
set active-flow-timeout 60
set inactive-flow-timeout 15
end
The default timeouts are acceptable if your build rejects the two set lines; the values above keep long-lived sessions reporting on a predictable cadence.
2. Enable NetFlow on Specific Interfaces
Like sFlow, NetFlow export is enabled per interface. Enable it on every interface whose traffic you want analyzed — WAN at minimum:
config system interface
edit "port1"
set netflow-sampler both
next
end
both exports ingress and egress; rx / tx restrict direction.
3. Denied Traffic — Use Syslog, Not NetFlow
FortiOS does not export blocked sessions via NetFlow. Even with ses-denied-traffic enabled (which adds denied sessions to the session table and flags them netflow-origin), the exporter never emits records for them — verified live against FortiOS 7.4 with controlled denied traffic and collector-side sequence accounting. NetFlow firewall_event = denied records come from Cisco ASA NSEL and Palo Alto exporters only.
On FortiGate, denied-traffic visibility comes from syslog: forward-traffic logs with action="deny" carry the full tuple (source, destination, ports, protocol, policy, interfaces, source country), and Firewall-Mon ingests them natively. Make sure your deny policies log traffic, and enable implicit-deny logging:
# On each deny policy you want visibility into
config firewall policy
edit <policy-id>
set logtraffic all
next
end
# Log the implicit deny (policy 0)
config log setting
set fwpolicy-implicit-log enable
end
ses-denied-traffic (per-VDOM config system settings) remains a worthwhile CPU optimization under scan/flood conditions — repeated denied packets match an existing block session instead of re-evaluating the policy set — but it does not affect flow export.
4. Verify on the FortiGate
# Confirm the exporter configuration
get system netflow
# Watch export datagrams leave toward the collector
diagnose sniffer packet any 'udp and port 2055' 4 10
Flows should appear on the Firewall-Mon Flows page labeled NetFlow v9 within a few minutes of live traffic.
5. Running sFlow and NetFlow Together
If the device also exports sFlow, keep both enabled — the collector de-duplicates per device (default policy prefer-netflow) so byte totals are never double-counted, and the admin console flags devices seen exporting via more than one protocol. See the NetFlow / IPFIX Setup section for sampling overrides and template behavior.
NetFlow & IPFIX Setup Guide
In addition to sFlow, Firewall-Mon (and the remote Firewall-Collector) ingest NetFlow v5, NetFlow v9, and IPFIX. Exporters are auto-detected by the datagram version word, so a v9 exporter aimed at the IPFIX port still decodes correctly. Point your firewall's flow export at the server (or a collector) on these UDP ports (FortiGate operators: the FortiGate NetFlow Setup guide has the exact CLI):
# Default flow ingest ports
6343/udp # sFlow v5
2055/udp # NetFlow v5 / v9
4739/udp # IPFIX
1. Denied-Flow Visibility
NetFlow v9/IPFIX exporters can emit firewall events (IE 233). Cisco ASA NSEL and Palo Alto denial records are ingested as flows with firewall_event = denied — surfacing blocked traffic that never shows up in interface counters. Zero-byte denial and flow-create records are intentionally kept. FortiGate does not export denied sessions via NetFlow — its denied-traffic visibility comes through syslog (see the FortiGate NetFlow Setup guide, section 3).
2. Sampling & Templates
Sampled exporters (e.g. FortiGate sampled NetFlow) are pre-multiplied by the resolved sampling rate at ingest, so byte and packet counts reflect real volume. v9/IPFIX templates are cached (and persisted across restarts) per exporter, source ID, and template ID. For exporters that never advertise a sampler, set an explicit rate:
# On the collector: pin a sampling rate for an exporter that omits options data
PROBE_NETFLOW_SAMPLING_OVERRIDES=192.0.2.1=1000
3. Dual Export (sFlow + NetFlow)
If a device exports both sFlow and NetFlow, Firewall-Mon de-duplicates per device so bytes aren't double-counted (default policy prefer-netflow), and the admin console flags any device seen exporting via more than one protocol in the last hour.
4. Test Reception
# Inspect incoming NetFlow / IPFIX datagrams on the server host
sudo tcpdump -i any 'udp port 2055 or udp port 4739' -nn
Custom SNMP Vendor Setup
Firewall-Mon exposes a clean Go interface allowing developers to write and register custom SNMP profiles without modifying the main polling loops.
The VendorProfile Interface
To implement custom logic for a new firewall vendor, write a struct satisfying the `VendorProfile` interface located under `internal/snmp/vendor.go`:
type VendorProfile interface {
// ParseSystemStatus extracts CPU, Memory, Disk and Session counts
ParseSystemStatus(pdu map[string]interface{}) (models.SystemStatus, error)
// ParseInterfaces parses interface speed, status, and bandwidth metrics
ParseInterfaces(rows []map[string]interface{}) ([]models.InterfaceStatus, error)
// GetAllVPNTunnels extracts active IPsec and SSL VPN tunnel stats
GetAllVPNTunnels(rows []map[string]interface{}) ([]models.VPNStatus, error)
}
Registering the Profile
Add your profile mapping inside `internal/snmp/vendor.go` in the global `Profiles` map registration:
var Profiles = map[string]VendorProfile{
"fortigate": &FortiGateProfile{},
"paloalto": &PaloAltoProfile{},
"cisco_asa": &CiscoASAProfile{},
"sonicwall": &SonicWallProfile{},
"firewalla": &FirewallaProfile{},
"pfsense": &PfSenseProfile{},
"opnsense": &OPNsenseProfile{},
"generic": &GenericProfile{}, // standards-only MIB-II fallback
"custom": &CustomProfile{}, // Your profile here
}
Unknown or unmapped vendor strings fall back to the generic standards-only profile (MIB-II + HOST-RESOURCES), so any SNMP device reports interface, CPU, and memory metrics out of the box.