Oxidized for Fortinet FortiGate: Automated Config Backup with Git Versioning

Oxidized backup server collecting FortiGate firewall configurations over SSH and committing them to a Git repository

Firewall outages are rarely caused by hardware alone. More often, a well-intentioned change to a policy, an address object, or an SD-WAN rule goes live late on a Friday, nobody records exactly what was touched, and the engineer who remembers the original state has since moved on. In that moment, the quality of your FortiGate configuration backups decides whether recovery takes ten minutes or ten hours.

Oxidized, the open-source network configuration backup tool, addresses this problem directly. It logs in to each FortiGate over SSH on a schedule, collects the configuration, and commits every change to a Git repository. As a result, each modification becomes a commit with a timestamp, a diff, and a permanent history that outlives any individual administrator. This guide covers the complete implementation: preparing FortiOS, deploying Oxidized with Docker, tuning the FortiOS model for readable diffs, pushing to a remote repository, triggering backups from syslog, hardening the pipeline, and restoring a failed unit.

What Is Oxidized for FortiGate?

Oxidized for FortiGate is an automated backup workflow in which the Oxidized application connects to Fortinet FortiOS devices over SSH, runs the commands defined in its fortios model, stores the returned configuration text, and commits each changed version to a Git repository. It delivers scheduled backups, version history, diff views, and a REST API without requiring FortiManager or any commercial license.

Key Takeaways

  • Oxidized ships with a native fortios model, so no custom scripting is needed to back up FortiGate firewalls.
  • Git output turns every configuration change into an auditable commit, which supports change control, rollback planning, and compliance evidence.
  • A dedicated read-only administrator with trusted hosts keeps the backup account low-risk.
  • FortiOS configurations contain timestamps and encrypted secrets that create noisy diffs, so model variables deserve careful tuning.
  • Syslog-triggered backups capture changes within seconds instead of waiting for the next polling interval.
  • Backups are only valuable if you have rehearsed a restore, so test one before you need one.

Why FortiGate Configuration Backups Deserve Better Than Scheduled Exports

FortiGate administrators already have several ways to export a configuration. Nevertheless, most of those methods solve only part of the problem, and the gaps become obvious during an incident or an audit.

What Native FortiGate Backup Options Do Well

FortiOS provides a manual backup from the GUI, the execute backup config command family for TFTP, FTP, and SFTP targets, automatic revision backups on administrator logout, and centralized revision history through FortiManager. For a single firewall, these tools are perfectly adequate. In addition, FortiManager is excellent when you already manage policy packages centrally and license every device for it.

Where Native Options Fall Short

Problems appear at scale and in mixed environments. Manual exports depend on someone remembering to run them, scheduled scripts need maintenance, and local revision history on the device disappears along with the device itself. Furthermore, a FortiManager revision tells you that something changed, but it does not integrate naturally with the Git workflows, pull requests, and CI pipelines that many network teams now use.

ApproachStrengthsLimitations
Manual GUI exportSimple, no setupHuman-dependent, no history, no alerting
Scripted execute backup configScheduled, uses native commandsRequires TFTP or SFTP server, weak diffing, script upkeep
Revision backup on logoutAutomatic on the deviceStored locally, lost if the unit fails
FortiManager revisionsCentral history, policy packagesLicensing and architecture overhead, Fortinet-only
Oxidized with GitFree, versioned, multi-vendor, API-drivenRequires a server and operational ownership

In practice, many mature teams run both FortiManager and Oxidized. FortiManager handles provisioning, while Oxidized acts as an independent, vendor-neutral record that also covers switches, routers, and non-Fortinet firewalls.

How Oxidized Works with FortiOS

Before building anything, it helps to understand what each moving part does. Oxidized is a Ruby application built around four pluggable concepts: sources, inputs, models, and outputs.

Architecture Components

LayerComponentFunction in a FortiGate Deployment
SourceCSV, SQL, HTTP, or NetBoxSupplies the list of firewalls, IP addresses, and credentials
InputSSHOpens the CLI session to FortiOS
ModelfortiosDefines which commands run and how output is cleaned
OutputGit or gitcryptStores each changed configuration as a commit
Hooksgithubrepo, exec, slackdiffReacts to events such as a stored change
InterfaceREST API and Oxidized WebExposes node status, diffs, and manual triggers

The Backup Lifecycle

Each polling cycle follows the same sequence, which makes troubleshooting far more predictable once you recognize it.

  1. Oxidized reads the node list from the configured source.
  2. A worker thread opens an SSH session to the FortiGate using the credentials supplied for that node.
  3. The fortios model sends its commands and collects the output.
  4. Model rules strip volatile lines and, optionally, secrets.
  5. Oxidized compares the cleaned result with the last stored version.
  6. If the content differs, the output driver writes a new Git commit.
  7. Any hook bound to the post-store event fires, for example a push to a remote repository.
  8. The node is rescheduled for the next interval.

The FortiOS Model Explained

The fortios model gathers the system status, the hardware inventory, and the configuration itself, then removes elements that change on every run. Moreover, it recognizes the FortiOS prompt, which is where many custom setups fail. Because the model is community-maintained, new FortiOS releases occasionally require a model update, so keep the Oxidized image current rather than pinning it for years.

Prerequisites and Planning

A short planning session prevents most deployment problems. The table below summarizes what you need before touching the firewall.

RequirementRecommendationWhy It Matters
Backup serverLinux VM with 2 vCPU and 2 GB RAM for small estatesOxidized is light, but Git history grows steadily
Container runtimeDocker Engine with ComposeSimplifies upgrades and rollback
FortiOS accessSSH enabled on a management interfaceOxidized uses the CLI, not the REST API of the firewall
Service accountDedicated read-only administratorLimits blast radius if credentials leak
Network pathTCP 22 from backup server to each FortiGateOften blocked by local-in policies
Time syncNTP on server and firewallsCommit timestamps and syslog correlation depend on it
Remote GitPrivate repository on GitLab, GitHub, or GiteaProtects history if the backup server is lost

Network and Firewall Considerations

FortiGate protects its own management plane with local-in policies and per-interface allowed access settings. Consequently, a backup that works from your laptop may fail from the Oxidized server simply because the server sits in a different subnet. Confirm that SSH is permitted on the interface Oxidized will reach, and that no local-in policy or trusted host entry drops the session.

Sizing for Larger Estates

Oxidized scales comfortably into the thousands of devices when you raise the thread count and tune timeouts, yet the real constraint is usually the firewalls themselves. A busy FortiGate may take several seconds to render a large configuration, so avoid setting a thread count that launches hundreds of simultaneous sessions against one site over a slow WAN link.

Preparing the FortiGate for Oxidized

The goal is a service account that can read the configuration and nothing else. Doing this properly takes about five minutes per firewall, and it is the single most valuable security decision in the project.

Create a Least-Privilege Admin Profile

Start by defining an access profile with read permissions. FortiOS also ships with a built-in read-only super administrator profile on recent versions, which is convenient for multi-VDOM units. However, a custom profile makes the intent explicit and survives upgrades without surprises.

config system accprofile edit "oxidized-ro" set secfabgrp read set ftviewgrp read set authgrp read set sysgrp read set netgrp read set loggrp read set fwgrp read set vpngrp read set utmgrp read set wanoptgrp read set wifi read next end

The profile above grants read access across the major permission groups. Note that available groups differ between FortiOS releases, so run set ? inside the edit context and adjust to match your version.

Create the Service Account with Trusted Hosts

Next, create the administrator and bind it to the Oxidized server address. The trusted host setting means that even a stolen password is useless from any other network location.

config system admin edit "oxidized" set accprofile "oxidized-ro" set vdom "root" set trusthost1 10.10.50.25 255.255.255.255 set password ChangeThisLongRandomPassword next end

After saving, verify the account by opening an SSH session from the Oxidized server and running show full-configuration. If the output is truncated or secrets appear unexpectedly masked, revisit the profile permissions before proceeding.

Use SSH Key Authentication Where Possible

Passwords work, but keys are better. A dedicated key pair removes the password from your Oxidized configuration file and makes rotation straightforward. FortiOS accepts a public key on the administrator object.

config system admin edit "oxidized" set ssh-public-key1 "ssh-rsa AAAAB3NzaC1yc2E... oxidized@backup01" next end

On the Oxidized side, the key path is supplied through the ssh_keys variable, which you will see in the configuration section. Because key type support varies between FortiOS versions, test RSA first if an ed25519 key is rejected.

Multi-VDOM Considerations

When virtual domains are enabled, the global configuration and each VDOM configuration are separate scopes. To capture everything in a single file, the backup account needs sufficient privileges at the global level. In contrast, a VDOM-scoped administrator only sees its own VDOM, which is useful for MSP tenants but insufficient for a full device backup. Test your chosen profile in a lab unit, because the model’s behavior with multi-VDOM units can differ across Oxidized releases.

FortiGate High Availability Clusters

In an active-passive cluster, configuration synchronizes from the primary to the secondary, so backing up the cluster address normally captures the full configuration. Even so, node-specific values such as hostnames and reserved management interface addresses can differ. For that reason, many teams register each member’s dedicated management address as a separate Oxidized node, which also confirms that both units remain reachable.

Installing Oxidized with Docker

Docker is the most maintainable way to run Oxidized because upgrading means pulling a new image rather than wrestling with Ruby gems and native libraries such as libssh and libgit2.

Directory Layout

Create a persistent directory on the host. This single directory will hold the configuration file, the inventory, and the Git repository, so it is the one location you must back up.

sudo mkdir -p /srv/oxidized sudo chown -R 30000:30000 /srv/oxidized

The official image runs as an unprivileged user, and ownership mismatches are a leading cause of the container exiting immediately. Check the image documentation for the UID used by your version.

The Core Configuration File

Save the following as /srv/oxidized/config. It defines polling behavior, SSH input, Git output, a CSV source, and the REST interface bound to localhost.

username: oxidized password: ChangeThisLongRandomPassword model: fortios interval: 3600 use_syslog: false debug: false threads: 20 timeout: 30 retries: 3 rest: 127.0.0.1:8888 vars: remove_secret: false ssh_keys: /home/oxidized/.config/oxidized/ssh/id_rsa input: default: ssh ssh: secure: false output: default: git git: user: Oxidized email: oxidized@example.com repo: /home/oxidized/.config/oxidized/fortigate.git source: default: csv csv: file: /home/oxidized/.config/oxidized/router.db delimiter: !ruby/regexp /:/ map: name: 0 ip: 1 model: 2 group: 3

Several choices here deserve explanation. The interval of 3600 seconds polls hourly, which balances freshness against load. Setting secure: false skips SSH host key verification, which is convenient in a lab, though production deployments should enable it and pre-populate the known hosts file to prevent man-in-the-middle exposure. Finally, binding the REST interface to localhost keeps an unauthenticated API off the network until you place a reverse proxy in front of it.

The Device Inventory

The CSV source reads one firewall per line using the colon delimiter and the field map above.

fw-hq-01:10.10.1.1:fortios:edge fw-branch-02:10.20.1.1:fortios:branch fw-dc-03:10.30.1.1:fortios:datacenter

The node name should match the hostname configured on the FortiGate, because that alignment becomes essential when you add syslog triggers later. For larger estates, replace the CSV file with a NetBox or HTTP source so that the inventory is generated rather than hand-edited.

Starting the Container

docker run -d --name oxidized \ --restart unless-stopped \ -p 127.0.0.1:8888:8888 \ -v /srv/oxidized:/home/oxidized/.config/oxidized \ oxidized/oxidized:latest oxidized

Watch the first run with docker logs -f oxidized. A healthy start shows each node being queued and, after a short delay, a message indicating that the configuration was stored.

Verifying the First Backup

Once the logs look clean, confirm through the API and the repository.

curl -s http://127.0.0.1:8888/nodes.json git -C /srv/oxidized/fortigate.git log --oneline

The first command lists every node with its last status, while the second shows the commit history. If a node reports a failure, jump ahead to the troubleshooting section, where the common causes are tabulated.

Git Versioning for FortiGate Configurations

Git is what elevates Oxidized from a backup utility to a change-tracking system. Each time a configuration differs from the last stored copy, Oxidized writes a commit, which gives you a precise record of what changed and when.

Why Git Suits Firewall Configurations

FortiOS configurations are structured, line-oriented text, which is the ideal input for diff algorithms. Consequently, a one-line change to a firewall policy produces a one-line diff, and a change in the middle of a six-thousand-line file remains easy to spot. Additionally, Git provides cryptographic integrity of history, cheap storage through delta compression, and a universal toolset that auditors and engineers already understand.

Git Output Options

OutputUse CaseConsideration
gitStandard versioned backupsRepository stored in plain text on the server
gitcryptEncrypted repositoriesRequires git-crypt setup and key management
fileSimple flat filesNo history, so unsuitable for change tracking
httpForwarding to another systemNeeds a receiving service you maintain

For firewall configurations, choose git at minimum, and consider gitcrypt if the repository will be mirrored to a shared platform.

Reading the History

Because Oxidized writes ordinary Git commits, standard commands work. The repository is bare by convention, so use the -C flag or clone it.

# Clone for convenient browsing git clone /srv/oxidized/fortigate.git ~/fortigate-configs cd ~/fortigate-configs # Show the last five changes to one firewall git log -5 --stat -- fw-hq-01 # Show exactly what changed in the most recent commit git show HEAD -- fw-hq-01 # Compare two points in time git diff HEAD~10 HEAD -- fw-hq-01

In a repository organized by group, files appear under their group directory, so adjust paths to match. Importantly, commit messages record the node and group names, which makes git log --grep a quick way to find every change to a specific firewall.

Pushing to a Remote Repository

A backup that lives only on the backup server is not really a backup. Therefore, add a hook that pushes each stored change to a private remote.

hooks: push_to_remote: type: githubrepo events: [post_store] remote_repo: git@git.example.com:netops/fortigate-configs.git publickey: /home/oxidized/.config/oxidized/ssh/deploy.pub privatekey: /home/oxidized/.config/oxidized/ssh/deploy

Despite the hook’s name, it pushes to any Git server that accepts SSH, including GitLab and Gitea. Use a deploy key restricted to this single repository with write access, and protect the main branch so that nobody rewrites history.

Taming Noisy Diffs in FortiOS Backups

The most common complaint about FortiGate versioning is noise. If every poll produces a commit, the history becomes useless. Fortunately, the causes are well understood.

Noise SourceWhat HappensRemedy
Config header timestampHeader line changes on each exportEnable the model’s timestamp removal variable if your version provides it
Encrypted secretsSome ENC values are re-salted between exportsUse remove_secret, accepting that restores then need secrets re-entered
Uptime or counters in status outputVolatile values change constantlyRely on the model’s built-in filtering and update Oxidized
Full versus partial configDefaults inflate the file and shift with upgradesChoose the export style your team prefers and keep it consistent

The trade-off around secrets is worth pausing on. Removing secrets produces tidy diffs and a repository that is safer to share, but a backup stripped of pre-shared keys and local passwords cannot fully restore a firewall unaided. Conversely, keeping secrets yields a complete backup that must be protected like a credential vault. Most teams keep secrets on the backup server, encrypt the repository, and never mirror it to a public platform.

Because model variable names evolve, check the fortios model documentation for your installed version before relying on any specific option. Then, after changing a variable, trigger a manual run and confirm that a second consecutive backup produces no new commit. That simple test proves your noise suppression works.

Real-Time Backups with Syslog Triggers

Hourly polling is a sensible baseline, yet it leaves a window in which a change exists on the firewall but not in Git. If that window matters to your change process, you can close it by letting the FortiGate announce its own configuration changes.

How the Trigger Works

FortiOS writes an event log entry whenever an administrator edits an object or attribute. When those events are forwarded to a syslog receiver, a small script can extract the device name and call the Oxidized REST endpoint that moves that node to the front of the queue. Consequently, the backup runs seconds after the change rather than at the next interval.

  1. An administrator saves a change on the FortiGate.
  2. FortiOS generates a configuration event and sends it to the syslog server.
  3. rsyslog passes each matching line to a trigger script.
  4. The script extracts the device name from the log line.
  5. The script calls the Oxidized API to schedule that node immediately.
  6. Oxidized fetches the configuration and commits the diff to Git.

Configure FortiOS to Send Syslog

config log syslogd setting set status enable set server "10.10.50.25" set port 514 set facility local7 end

This forwards logs to the Oxidized host. Make sure the log filter includes event logs, and that the system event subtype for configuration changes is enabled in your logging settings.

Configure rsyslog and the Trigger Script

On the backup server, enable a UDP listener and hand each message to a program.

module(load="imudp") input(type="imudp" port="514" ruleset="fgt") ruleset(name="fgt") { action(type="omprog" binary="/usr/local/bin/oxidized-trigger.sh") }

The script below looks for the configuration-change log identifiers that FortiOS commonly uses for attribute and object edits. Verify the identifiers against the log reference for your FortiOS release, since they can vary.

#!/bin/bash pattern='devname="([^"]+)"' while read -r line; do case "$line" in *'logid="0100044546"'*|*'logid="0100044547"'*) if [[ $line =~ $pattern ]]; then curl -s "http://127.0.0.1:8888/node/next/${BASH_REMATCH[1]}" > /dev/null fi ;; esac done

Because the script uses the devname field, the node name in your Oxidized inventory must match the FortiGate hostname exactly. Moreover, a single administrative session can generate dozens of log lines, so you may prefer to add a short debounce, for example by writing the device name to a temporary file and processing it once every thirty seconds. Finally, restrict UDP 514 to your firewall addresses, because an open syslog listener can be abused to trigger needless backups.

Using the Oxidized REST API and Web Interface

Oxidized exposes a lightweight HTTP interface that is useful for dashboards, scripts, and manual operations. The same service provides a web view of nodes, versions, and diffs.

EndpointPurpose
/nodesLists all nodes with status and last run time
/nodes.jsonSame data in JSON for automation
/node/fetch/NAMEReturns the latest stored configuration
/node/next/NAMEQueues an immediate backup for that node
/node/version?node_full=GROUP/NAMELists stored versions of a node
/reloadReloads the inventory from the source

For example, to force a fresh backup of one firewall and then read it back, run:

curl -s http://127.0.0.1:8888/node/next/fw-hq-01 curl -s http://127.0.0.1:8888/node/fetch/fw-hq-01 | head -40

In practice, the JSON node list is a convenient data source for monitoring. A Prometheus exporter or a simple script can raise an alert when any node reports a status other than success for more than two intervals, which catches silent failures such as an expired password or a changed trusted host.

Securing the Backup Pipeline

A repository of firewall configurations is a high-value target. It reveals your network topology, address objects, VPN peers, and, depending on your settings, secrets. Treat the Oxidized server accordingly.

ControlRecommendation
Service accountRead-only profile, single trusted host, unique strong credential or key
TransportSSH only, with host key verification enabled in production
Secrets in GitEncrypt with gitcrypt or strip with remove_secret, depending on restore needs
API exposureBind to localhost and publish through a reverse proxy with authentication and TLS
Server hardeningPatch regularly, limit SSH access, enable disk encryption
Remote repositoryPrivate, deploy key per repository, protected main branch, MFA for human users
Credential storageKeep passwords out of version control, prefer SSH keys and environment secrets
MonitoringAlert on failed nodes and on unexpected commits

These measures align with widely used frameworks. For instance, NIST SP 800-53 addresses configuration baselines and change control, while the CIS Controls call for secure configuration of network devices. For a deeper, tool-specific checklist, the dedicated security guide for Oxidized covers hardening in more detail.

Restoring a FortiGate from an Oxidized Backup

A backup earns its value during recovery, so rehearse this procedure in a lab before an emergency forces you to improvise.

Restore Workflow

  1. Identify the correct commit using git log and confirm it with git diff against the current state.
  2. Retrieve the file with git show COMMIT:PATH and save it as a text file.
  3. Remove any leading comment lines that Oxidized added from command output, so the file begins at the FortiOS configuration header.
  4. Confirm that the firmware version on the target matches the version recorded in the header.
  5. Make the file available on a TFTP, FTP, or SFTP server, or upload it through the GUI restore option.
  6. Run the restore, accept the reboot, and verify connectivity and policy behavior afterward.
git show 3f9a2c1:fw-hq-01 > fw-hq-01.conf

From the FortiGate CLI, a restore from a file server looks like this, with the exact protocol options depending on your firmware:

execute restore config sftp fw-hq-01.conf 10.10.50.25 backupuser

Restore Pitfalls to Know About

Several issues catch teams out. First, FortiOS validates the configuration header, so removing the timestamp line for cleaner diffs can interfere with a restore unless you re-add a valid header. Second, if you stripped secrets, local administrator passwords and pre-shared keys must be re-entered. Third, restoring a configuration from a different firmware generation can fail or silently drop unsupported settings. Therefore, keep a note of the FortiOS version alongside each backup, which the model’s status output usually captures.

For partial rollbacks, a safer technique is to copy only the affected CLI blocks, such as a single config firewall policy section, and paste them into a console session during a maintenance window.

Change Auditing and Compliance Evidence

Because every commit records what changed and when, Git history doubles as audit evidence. Pairing it with FortiGate event logs, which record who made the change, produces a complete trail.

FrameworkRelevant AreaHow Oxidized Helps
NIST SP 800-53CM-2, CM-3, CM-6Baseline configurations, change tracking, configuration settings
CIS ControlsSecure configuration of network devicesVersioned, reviewable configurations with drift visibility
ISO 27001:2022Configuration managementDocumented, retrievable configuration history
PCI DSS 4.0Network security control configuration reviewsDiffs that simplify periodic configuration review
SOC 2Change management criteriaTimestamped records of production changes

To operationalize this, schedule a weekly job that emails the diff summary of all firewall changes to the security team, and require that every commit correlate with an approved change ticket. As a result, unauthorized or emergency changes become visible within hours rather than at the next audit.

Scaling Oxidized Across Many FortiGates

As the estate grows, three techniques keep the deployment manageable.

Use Groups for Different Credentials and Sites

Groups allow separate credentials or variables per environment, which suits datacenters, branches, and customer tenants.

groups: datacenter: username: oxidized-dc password: AnotherLongRandomPassword branch: username: oxidized-br password: YetAnotherLongRandomPassword

Each node picks up its group from the inventory field mapped earlier, and Git stores its file under the group directory. For MSPs, this separation also prevents one customer’s credentials from being used against another’s firewall.

Generate the Inventory from a Source of Truth

Maintaining a CSV by hand works for twenty firewalls but becomes error-prone at two hundred. Switching the source to NetBox or an HTTP endpoint means that adding a device to your documentation automatically adds it to the backup rotation. Likewise, decommissioning a device removes it, which keeps stale failures out of your dashboard.

Tune Threads, Timeouts, and Intervals

Start with 20 threads, a 30-second timeout, and a one-hour interval. Then watch the node list. If many nodes time out on slow links, raise the timeout before raising retries. Conversely, if the server is idle and the queue is long, increase threads gradually while observing CPU usage on both the server and the busiest firewalls.

Troubleshooting FortiGate Backups in Oxidized

Most failures fall into a handful of categories. Start by reading the container log, then reproduce the connection manually from the same host using SSH.

SymptomLikely CauseFix
Node shows no_connectionTrusted host, local-in policy, or routing blocks SSHTest with ssh from the Oxidized host and adjust access settings
Authentication failedWrong credential, locked account, or expired passwordVerify the login manually and review admin lockout settings
Timeout during fetchSlow link or very large configurationRaise the timeout and reduce concurrent threads
Output truncatedPaging prompt or incomplete permissionsCheck the console output setting and the access profile
Key exchange or cipher errorOld SSH library versus modern FortiOS ciphersUpdate the Oxidized image and check allowed algorithms
Commit on every runVolatile lines in outputTune model variables and update Oxidized
Container exits at startFile ownership or YAML syntax errorFix permissions and validate the YAML
Missing group directoryGroup field not mappedCorrect the source map indexes

Debugging a Single Node

When one firewall misbehaves, isolate it. Temporarily enable debug in the configuration, restart, and watch the SSH session. Alternatively, test the same login with a plain SSH client using the identical account. If the manual login works but Oxidized fails, the cause is usually a prompt mismatch, which happens when a customized login banner or an unusual hostname character confuses the prompt matching.

When FortiOS Upgrades Break Backups

Occasionally, a major FortiOS release changes banner text, prompt behavior, or cipher support. Consequently, backups may begin failing after an upgrade even though nothing changed on the Oxidized side. Pull the latest image, retry, and if the problem persists, open an issue in the Oxidized project with the FortiOS version and a sanitized debug log. Because the model is community-maintained, such reports are usually resolved quickly.

Common Mistakes to Avoid

  • Using a full administrator account for backups, which turns a convenience into a liability.
  • Skipping trusted hosts, so the credential works from anywhere.
  • Leaving the REST API listening on all interfaces without authentication.
  • Storing the only copy of the repository on the backup server.
  • Ignoring failed nodes until the day a restore is needed.
  • Mismatched node names and firewall hostnames, which break syslog-triggered runs.
  • Never testing a restore, then discovering that the stored file needs editing.
  • Disabling host key verification permanently after a lab trial.
  • Running with the latest tag unattended, then losing a working version after a surprise update.

Oxidized Compared with Other FortiGate Backup Options

ToolCostVersion ControlMulti-VendorBest Fit
OxidizedFreeNative GitYesTeams that want Git workflows and API access
FortiManagerLicensedRevision historyFortinet onlyCentral policy management and provisioning
RANCIDFreeCVS or Subversion styleYesLegacy environments already using it
Netmiko or Nornir scriptsFreeYou build itYesTeams needing custom logic and writing code
Commercial NCM suitesLicensedYesYesOrganizations wanting vendor support and reporting

When the decision is between Oxidized and RANCID, the usual deciding factors are Git support, an active community, and a maintained REST API, all of which favor Oxidized. Scripts built with Netmiko or Nornir offer more flexibility, but they also require you to own scheduling, error handling, and diffing.

Real-World Scenarios

Scenario One: Recovering from a Bad Policy Push

A branch firewall loses connectivity after a late change to an SD-WAN rule. Without history, the team would compare against memory. With Oxidized, an engineer runs git log for the node, spots the commit from twenty minutes earlier, reads the diff, and reverts the single block. Total recovery time is a few minutes, and the incident review has an exact record.

Scenario Two: Replacing a Failed Unit

A datacenter FortiGate suffers a hardware fault. The replacement is staged on the bench, upgraded to the recorded firmware version, and restored from the latest Oxidized commit after the leading comment lines are removed. Secrets were retained in the encrypted repository, so VPN tunnels return without manual re-keying.

Scenario Three: Passing an Audit

During a PCI DSS assessment, the assessor requests evidence of review of firewall configurations. The team exports the Git log for the previous quarter, matches commits to approved change tickets, and highlights the single emergency change that was retroactively documented. The conversation shifts from skepticism to confirmation.

Optimization Recommendations

AreaRecommendationBenefit
Image managementPin a tested version tag and upgrade deliberatelyPredictable behavior
PollingHourly interval plus syslog triggersFresh data with low load
RepositoryPeriodic garbage collection and off-site mirrorSmaller storage, resilience
AlertingNotify on failed nodes and on commits to critical firewallsFaster response
DocumentationStore a README in the repository describing restore stepsFaster recovery under pressure
AccessRotate keys and credentials on a scheduleReduced exposure

Frequently Asked Questions

Does Oxidized support FortiGate firewalls?

Yes. Oxidized includes a fortios model that supports FortiGate devices running FortiOS, connecting over SSH and storing the configuration in your chosen output, typically Git.

Do I need FortiManager to use Oxidized?

No. Oxidized connects directly to each FortiGate and works independently of FortiManager, although the two can coexist.

What permissions does the Oxidized account need on FortiOS?

The account needs read access sufficient to display the full configuration. A dedicated read-only administrator profile with a trusted host restriction is the recommended approach.

How often should I back up FortiGate configurations?

An hourly poll suits most environments. For tighter control, combine polling with syslog-triggered backups so that changes are captured within seconds.

Does Oxidized back up FortiGate VDOM configurations?

It can, provided the account has global access on a multi-VDOM unit. Test against a lab device, because behavior can vary between Oxidized and FortiOS versions.

Are secrets stored in the Oxidized backup?

By default, encrypted secrets remain in the stored configuration. You can strip them with the remove_secret option, but a backup without secrets cannot fully restore a firewall.

Can Oxidized restore a configuration to a FortiGate?

Oxidized only backs up and versions configurations. Restoration is performed with FortiOS tools such as the GUI restore function or the execute restore config command.

How do I push FortiGate backups to GitHub or GitLab?

Use the githubrepo hook with a deploy key and a private remote repository, bound to the post_store event so that each change is pushed automatically.

Why does Oxidized create a commit every run?

Volatile lines such as timestamps usually cause this. Update Oxidized, enable the relevant model variables, and confirm that two consecutive runs produce no commit.

Is Oxidized suitable for production firewalls?

Yes, provided you use a least-privilege account, protect the repository, monitor failures, and rehearse restores. Many organizations rely on it daily.

Conclusion

Automating FortiGate backups with Oxidized and Git replaces guesswork with evidence. A read-only service account keeps risk low, the fortios model removes most of the manual effort, and Git supplies the history that change management, audits, and incident response all depend on. Furthermore, syslog triggers and the REST API turn a simple scheduled job into a responsive part of your operational toolkit.

The practical next step is modest: build the service account on one firewall, run the container, and confirm that two consecutive backups produce a single commit. From there, add the remote push, enable syslog triggers, and rehearse a restore. Once 

Picture of Martin Kelly
Martin Kelly

We hired CWNx to revamp our company website and run a few ad campaigns. The new design is sleek and professional, and the campaigns brought in a noticeable uptick in qualified leads. Communication was smooth throughout the project. I'm docking one star only because the initial timeline slipped by a few days, but the final output was absolutely worth the wait.

Leave a Reply

Your email address will not be published. Required fields are marked *

Our Blogs

Related Blogs & News

Stay ahead of the curve with expert insights on cybersecurity, network engineering, web development, and the latest in digital technology — all curated by the Creative Web Nexus team.