📌 Overview

A Python automation script that bootstraps a FortiGate from its factory-default (or current) state over SSH — setting the admin password, configuring WAN and LAN interfaces, enabling the LAN DHCP server, and optionally provisioning a REST API admin account and token.

Repo: github.com/poyzerj/NetworkAutomation/fortigate_bootstrap

🔧 What It Does

  1. Checks reachability, then SSHes in as admin with a blank password, handling the forced password-change prompt
  2. If the LAN interface is bundled into a hardware switch, breaks it out into an independent interface first
  3. Pushes WAN configuration (static IP, gateway, DNS)
  4. Pushes LAN configuration (static IP, DHCP server) — last, since this is the point where the session is expected to drop
  5. Optionally reconnects at the new LAN address to create a REST API admin account and print a one-time token

🖥️ Two Templates: Hardware vs. Virtual

The script ships with two config templates, since FortiGate's interface behavior differs meaningfully between platforms:

  • Physical FortiGate template — desktop models with a built-in LAN switch bundle their physical LAN ports into a single virtual-switch interface, which has to be explicitly broken out before it can take its own static IP
  • EVE-NG / virtual lab template — virtual FortiGate images expose port1/port2 as independent interfaces from the start, so no switch breakout step is needed

⚠️ Designed Around an Expected Session Drop

One of the trickier design problems here: the script reconfigures the LAN interface's IP address while connected to the FortiGate through that same interface. That means the SSH session dropping partway through a run isn't a bug — it's expected behavior, and the script logs it as such rather than treating it as a failure. If a REST API account is requested, the script reconnects at the new LAN address afterward, which doubles as confirmation that the LAN reconfiguration actually took effect.

🔒 Credential & Token Handling

The admin password lives only in the gitignored config file. If a REST API account is created, the generated token is printed once to the console and deliberately never written to the log file, since a long-lived API token in a log would be a real credential exposure risk.

📈 Result

A repeatable way to take a FortiGate from factory defaults (or any known starting state) to a working WAN/LAN configuration with DHCP running, in a single scripted run — with the interface-breakout logic adapting to whether the target is physical hardware or a virtual lab image.

📝 Notes / Lessons Learned

  • Virtual-switch behavior on FortiGate hardware varies noticeably across models and firmware — the breakout logic is documented as a best-effort default, with an explicit note to verify show system virtual-switch output against the config before running on unfamiliar hardware
  • A script that reconfigures its own connection path needs to treat the resulting disconnect as an expected state, not an error — logging it correctly instead of surfacing a false failure was a deliberate design choice
  • Sequencing matters: pushing WAN config first (which doesn't touch the active session) before LAN config (which does) minimizes the risk window and keeps the drop predictable and expected, rather than happening at a random point mid-run