📌 Overview

A Python tool, built against the FortiGate REST API, that audits a FortiGate's configuration for common issues and runs a structured troubleshooting sweep across multiple layers — interfaces, routing, VPN, system resources, policy/security, and local connectivity — rather than checking any one thing in isolation.

Repo: github.com/poyzerj/NetworkAutomation/fortigate_audit

🔧 Two Modes: Audit and Troubleshoot

The tool is split into two complementary pieces:

  • Audit mode — pulls interfaces, firewall policies, and VPN tunnel status from the FortiGate and runs a set of configuration checks against them (e.g., flagging administratively down interfaces, policies using an overly broad "ALL" service, VPN tunnels not in an "up" state)
  • Troubleshoot mode — a broader diagnostic sweep, layered by Physical/Interfaces, Routing, VPN, System/Resources, Policy/Security, Local Connectivity, and DNS, combining FortiGate-side API checks with local-machine diagnostics (ping, traceroute, DNS resolution) run from wherever the script executes

🧩 Design: Small, Composable Checks

Rather than one large monolithic audit function, each check is a small, standalone function that takes a shared context object and returns a structured result — a name, a layer, a pass/fail state, and a list of findings. New checks are added by writing the function and registering it in a list; nothing else in the tool needs to change. Remote checks (which need a live FortiGate connection) and local checks (which run entirely on the local machine) are kept in separate registries, so either set can be run independently — useful for isolating whether a problem is on the FortiGate side or the local network path.

🔍 Troubleshooting Sweep Detail

The troubleshoot sweep includes checks like:

  • Interface link status and error/drop counters (RX/TX errors, RX/TX drops), skipping interfaces that are intentionally administratively disabled
  • Routing table validation — confirming a default route actually exists
  • VPN tunnel Phase 1 (IKE SA) and Phase 2 (per-selector) status
  • CPU and memory utilization against configurable warning thresholds
  • Local connectivity — default gateway detection and ping, external reachability, DNS resolution — run independently of the FortiGate itself, to help distinguish a FortiGate-side problem from a local network issue

The CLI supports running the full sweep, a single named check in isolation (--check vpn), or listing all available checks — built with an eye toward a possible future interactive "diagnose this specific symptom" mode.

📈 Result

A reusable diagnostic tool that turns "go check the FortiGate" into a structured, repeatable sweep — useful both for a quick daily health check (audit mode) and for a deeper investigation when something's actually wrong (troubleshoot mode), without needing to remember which fifteen things to manually check every time.

📝 Notes / Lessons Learned

  • Separating "this data point is a genuine problem" from "this data point is informational" (via an info_only flag) and "the check itself failed to run" (via an error flag) makes the tool's output far more trustworthy than a simple pass/fail — a failed API call and a real configuration problem are very different things and shouldn't look the same in a report
  • Building small, composable checks around a shared context object made it trivial to add the hairpin-policy check later without touching anything else in the tool — a direct payoff of the initial design choice
  • Running local diagnostics (ping, traceroute, DNS) alongside FortiGate-side API checks helps separate "the firewall is misconfigured" from "the problem isn't the firewall at all" — a distinction that matters a lot when triaging a real issue under time pressure