Backing Up Cisco ASA and Firepower with Oxidized: Enable Mode, Contexts, and Pitfalls

Oxidized backup server capturing Cisco ASA security contexts and Firepower device configurations over SSH into a Git repository

Cisco firewalls look simple from the outside. You SSH in, type show running-config, and read the output. Anyone who has automated that process across a real estate knows how quickly the simplicity evaporates. The login lands in user EXEC mode, so you need enable privileges before the configuration is visible. A multiple-context ASA hides most of its configuration behind context switches. Secrets are masked in the default output. The running configuration can differ from the startup configuration. And on the Firepower side, the device you are logged into often is not the system that holds the policy at all.

Oxidized can handle all of this, but only if you design the backup around how these platforms actually behave. This guide walks through the full picture: how enable mode works with Oxidized, how to back up every security context on a multi-context ASA, what to do about Firepower Threat Defense and the Firepower Management Center, how to avoid the pitfalls that silently produce incomplete backups, and how to restore when something breaks. Along the way, it covers Docker deployment, Git versioning, syslog-triggered captures, hardening, and troubleshooting.

What Is Oxidized for Cisco ASA and Firepower?

Oxidized for Cisco ASA and Firepower is an automated backup workflow in which the Oxidized application connects to Cisco firewalls over SSH, enters privileged mode, runs configuration display commands defined in a model, and commits each changed result to a Git repository. For ASA appliances it captures the running configuration directly, while for Firepower Threat Defense it captures the device-level configuration and complements, rather than replaces, backups from the Firepower Management Center.

Key Takeaways

  • Oxidized needs privileged EXEC access on an ASA, which you can provide through an enable password or, more cleanly, through automatic privilege assignment for the backup user.
  • On a multi-context ASA, the system context and every user context are separate configurations, so each one needs its own capture.
  • The default show running-config output masks pre-shared keys and similar secrets, so a backup built from it is not a complete restore source.
  • Firepower Threat Defense policy lives in the Firepower Management Center or Firepower Device Manager, which means device CLI backups alone are insufficient.
  • Timestamps and uptime lines create noisy diffs unless the model strips them.
  • A syslog hook on configuration command messages captures changes within seconds.
  • Every restore path needs rehearsal, because ASA, FTD, and FMC each restore differently.

Why Cisco Firewall Backups Are Trickier Than They Look

The phrase Cisco firewall covers several quite different products. Choosing the right backup method starts with knowing which one you actually run.

The Platform Landscape

PlatformWhere the Configuration LivesWhat Oxidized Can Capture
ASA, single contextOn the applianceFull running configuration over SSH
ASA, multiple contextSystem context plus one config per user contextEach context, with context switching
ASA with FirePOWER moduleASA on the appliance, module policy in FMC or ASDMASA configuration only
FTD managed by FMCPolicy in FMC, deployed to the deviceDevice-level running configuration, not the policy source
FTD managed by FDMPolicy in the on-box managerLimited CLI view, backup through the manager
Firepower chassis running FXOSChassis and logical device settingsChassis configuration through the FXOS CLI

In short, Oxidized is an excellent fit for ASA software and a useful partial tool for Firepower. For the Firepower family, treat it as one layer in a larger backup strategy.

Running Configuration Versus Startup Configuration

An ASA keeps its active configuration in memory and saves it to flash only when an administrator writes memory. Consequently, the running configuration can include changes that have never been saved, and a reload would discard them. Conversely, the startup configuration can be older than what the firewall currently enforces.

CharacteristicRunning ConfigurationStartup Configuration
LocationMemoryFlash
Reflects enforced behaviorYesOnly after a reload
Survives a rebootOnly if savedYes
Best backup sourceAuditing what is enforcedVerifying what will survive a reload

Because enforcement matters most, Oxidized captures the running configuration. Even so, a periodic comparison against the startup configuration is a worthwhile hygiene check, and a later section describes it.

What the Default Output Hides

By default, show running-config masks several sensitive values. Pre-shared keys in tunnel groups, SNMP community strings, and similar items appear as asterisks. In contrast, the more system:running-config command displays more of those values, and with password encryption enabled on newer releases, they appear in encrypted form rather than as plain text. Therefore, a backup assembled from the default command cannot restore VPN tunnels on its own, and an engineer must re-enter those secrets afterward.

How Oxidized Works with Cisco ASA

Oxidized organizes its work around sources, inputs, models, and outputs.

Architecture Components

LayerComponentFunction in a Cisco Firewall Deployment
SourceCSV, SQL, HTTP, or NetBoxLists firewalls, addresses, models, and groups
InputSSHOpens the CLI session
Modelasa, a Firepower model, or a custom modelHandles enable, paging, commands, and cleanup
OutputGit or gitcryptStores each changed configuration as a commit
Hooksgithubrepo, exec, slackdiffReacts to stored changes
InterfaceREST API and Oxidized WebShows node status and allows manual triggers

The Backup Lifecycle

  1. Oxidized loads the node list from the source.
  2. A worker opens an SSH session to the firewall.
  3. The model logs in and escalates to privileged mode.
  4. The model disables the pager so long output is not interrupted.
  5. The model runs its display commands and collects the output.
  6. Volatile lines are stripped, and secrets are optionally removed.
  7. Oxidized compares the result to the last stored version.
  8. A changed result becomes a Git commit, and any hook fires.

The ASA Model

Oxidized ships with an asa model that handles enable mode, pager settings, and the display of the configuration and basic inventory. Model coverage and options evolve between releases, so confirm the variables supported by your installed version. Likewise, check which Firepower-related models your version provides, since naming and scope have changed over time.

Prerequisites and Planning

RequirementRecommendationWhy It Matters
Backup serverLinux VM with 2 vCPU and 2 GB RAMLight workload, Git grows steadily
Container runtimeDocker Engine with ComposeSimple upgrades and rollbacks
SSH accessEnabled on a reachable interfaceOxidized uses SSH only
Service accountDedicated local or AAA userLimits blast radius
Source restrictionSSH allowed only from the Oxidized serverMakes stolen credentials less useful
Time syncNTP on all devicesReliable logs and commit times
Remote GitPrivate repository on GitLab, GitHub, or GiteaProtects history if the server fails
Platform inventoryWhich ASA, FTD, FMC, and FXOS devices existDetermines the backup method per device

Management Reachability

SSH to an ASA is permitted only from addresses and interfaces you explicitly allow. If the Oxidized server sits behind a VPN or on a remote segment, the management-access feature may be needed so that the firewall accepts SSH on an interface other than the one the traffic arrives on. Decide this before building the account, since it is the most common reason a first test fails.

Preparing the ASA for Oxidized

The goal is a user that can log in over SSH from one address, reach privileged mode, and read the configuration.

Enable SSH on the ASA

If SSH is not yet configured, generate keys and allow the Oxidized server.

crypto key generate rsa modulus 2048 ssh version 2 ssh 10.10.50.25 255.255.255.255 inside ssh timeout 30 aaa authentication ssh console LOCAL

These commands generate host keys, restrict SSH to version 2, permit the Oxidized server on the inside interface, extend the idle timeout so long configurations do not drop the session, and authenticate against the local user database. Cipher and key exchange options differ by release, so confirm available choices with ssh ? on your software version.

Create the Service Account

username oxidized password ChangeThisLongRandomPassword privilege 15

A privilege 15 user is the simplest approach, but it is also the most powerful, which is exactly what a read-only backup account should not be. The next section explains how enable mode works and how to narrow the account.

Enable Mode in Depth

An SSH session to an ASA begins in user EXEC mode, where the prompt ends with a greater-than sign. The configuration is visible only in privileged EXEC mode, where the prompt ends with a pound sign. Oxidized therefore needs a reliable way to cross that boundary.

Three Approaches Compared

ApproachHow It WorksStrengthsLimitations
Enable passwordOxidized sends enable and then the enable passwordSimple, widely supportedStores a second secret, high privilege
Automatic enable on loginAAA places the user directly in privileged modeNo enable secret in OxidizedUser keeps full privilege 15
Command authorization with a limited levelUser stays at a lower level with only chosen commands allowedTrue least privilegeMore complex, easy to misconfigure

Approach One: The Enable Password

This is the default pattern. Define the enable secret on the ASA, then give Oxidized the same value through its variables.

vars: enable: ChangeThisEnablePassword

The model sends the enable command, answers the password prompt, and continues. As a result, it works with nearly every ASA version. Nevertheless, the enable password is a shared secret that grants far more than reading, so protect the Oxidized configuration file accordingly.

Approach Two: Automatic Enable

An authorization setting can place the SSH user directly into privileged mode, which removes the need to store an enable password in Oxidized.

aaa authorization exec LOCAL auto-enable

With this in place and the user at privilege 15, the session arrives at the pound-sign prompt immediately. When using this method, remove the enable variable from the Oxidized configuration, or confirm that the model tolerates a session that is already privileged.

Approach Three: Command Authorization for Least Privilege

For strict environments, local command authorization lets a lower-privilege user run only specific commands. The idea is to assign the user a custom level and raise just the needed show commands to that level.

username oxidized password ChangeThisLongRandomPassword privilege 5 aaa authorization command LOCAL privilege show level 5 mode exec command running-config privilege show level 5 mode exec command version privilege show level 5 mode exec command context

This approach is powerful and fragile at the same time. The exact set of commands the model runs, including pager and context-switching commands, must all be permitted, and a missing one produces confusing authorization failures. Consequently, test it against the exact model you use, capture every command from a successful manual run, and only then roll it out. If your organization uses TACACS+ or RADIUS, the same idea is usually implemented with a command set on the AAA server, which is easier to maintain.

Failover Pairs

In an active-standby pair, the configuration is synchronized from the active unit. Backing up the shared management address captures the active unit. In addition, many teams register each unit’s management address separately, which confirms that both remain reachable and that the standby is in sync.

Installing Oxidized with Docker

Directory Layout

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

The Core Configuration File

Save this as /srv/oxidized/config.

username: oxidized password: ChangeThisLongRandomPassword model: asa interval: 3600 use_syslog: false debug: false threads: 10 timeout: 45 retries: 3 rest: 127.0.0.1:8888 vars: enable: ChangeThisEnablePassword input: default: ssh ssh: secure: false output: default: git git: user: Oxidized email: oxidized@example.com repo: /home/oxidized/.config/oxidized/cisco-firewalls.git source: default: csv csv: file: /home/oxidized/.config/oxidized/router.db delimiter: !ruby/regexp /:/ map: name: 0 ip: 1 model: 2 group: 3

A 45-second timeout leaves room for large configurations, while ten threads keeps the load on firewall control planes modest. In production, switch secure to true after populating known hosts.

The Device Inventory

fw-asa-hq-01:10.10.1.2:asa:asa-single fw-asa-dc-02:10.30.1.2:asa:asa-single

Start 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

Follow the first run with docker logs -f oxidized, then confirm with curl -s http://127.0.0.1:8888/nodes.json and git -C /srv/oxidized/cisco-firewalls.git log --oneline. If a node fails, jump to the troubleshooting section.

Handling Multiple Security Contexts

A multiple-context ASA behaves like several virtual firewalls on one chassis. Each context has its own configuration, interfaces, and policies. The system context controls resource allocation and context definitions, while the admin context provides management access. A backup that captures only the context you happened to log into is a partial backup, and partial backups are the most dangerous kind because they look complete.

What Each Context Contains

ContextContentsWhy It Needs Its Own Backup
SystemContext definitions, interface allocation, failover, resource classesControls how every other context exists
AdminManagement access, plus its own policiesOften the login target for SSH
User contextsInterfaces, access lists, NAT, VPN, and policy per tenantHold the actual security policy

Approaches to Backing Up Contexts

ApproachHow It WorksBest Fit
One node per context with its own management addressEach context has an SSH-reachable interface, and Oxidized logs into it directlyContexts with dedicated management IPs
Login to admin context and switchThe model runs a context switch command before displaying the configurationContexts without separate management access
Combined captureSeparate nodes for the system context and every user context, all through custom modelsFull coverage with clear history per context

In practice, the second and third approaches are the most common, because few designs give every context its own management address.

Custom Models for System and Context Captures

The context-switch commands are the key. In the system context, the command changeto system moves the session there. For a user context, changeto context NAME does the same. Because the prompt changes to include the context name, the prompt pattern must allow slashes. Save the following as /srv/oxidized/model/asasystem.rb.

class ASASystem < Oxidized::Model comment '! ' prompt %r{^\r?[\w.@/()-]+[#>]\s?$} cmd :all do |cfg| cfg.each_line.to_a[1..-2].join end cmd 'show version' do |cfg| cfg.gsub!(/^\S+ up .*\n/, '') comment cfg end cmd 'show running-config' do |cfg| cfg.gsub!(/^: Written by .*\n/, '') cfg end cfg :ssh do post_login do if vars(:enable) cmd 'enable', /^[pP]assword:/ cmd vars(:enable) end end post_login 'terminal pager 0' post_login 'changeto system' pre_logout 'exit' end end

A user-context model is almost identical, except that it reads the context name from a variable and switches to it. Save this as /srv/oxidized/model/asacontext.rb, changing only the class name and the switch step.

class ASAContext < Oxidized::Model comment '! ' prompt %r{^\r?[\w.@/()-]+[#>]\s?$} cmd :all do |cfg| cfg.each_line.to_a[1..-2].join end cmd 'show running-config' do |cfg| cfg.gsub!(/^: Written by .*\n/, '') cfg end cfg :ssh do post_login do if vars(:enable) cmd 'enable', /^[pP]assword:/ cmd vars(:enable) end end post_login 'terminal pager 0' post_login do cmd "changeto context #{vars(:asa_context)}" end pre_logout 'exit' end end

These models are sketches built on the standard Oxidized model syntax, so test them on a lab ASA and adjust them to your software version. Models are plain Ruby, which means they belong in version control and deserve the same review as any other code.

Wiring Contexts into the Inventory

Assign each context to a group, and set the context name as a variable on that group.

groups: ctx-dmz: vars: asa_context: dmz ctx-partner: vars: asa_context: partner

Then list one node per context, all pointing at the same management address.

fw-asa-mc-01-system:10.10.1.3:asasystem:system fw-asa-mc-01-dmz:10.10.1.3:asacontext:ctx-dmz fw-asa-mc-01-partner:10.10.1.3:asacontext:ctx-partner

Because each node writes to its own file, Git history for the DMZ context is separate from the partner context. Importantly, when a new context is created on the ASA, nothing in Oxidized changes automatically, so the system-context history is your signal that a new node needs adding. Reviewing context definitions in the system backup each week prevents silent gaps.

Firepower: What Oxidized Covers and What It Does Not

Firepower Threat Defense combines the ASA data plane, known as LINA, with the Snort inspection engine, and a management plane that differs by deployment. This is where teams most often assume a backup exists and discover otherwise.

Where Firepower Configuration Actually Lives

Management ModelAuthoritative SourceRecommended Backup
FTD managed by FMCFirepower Management CenterFMC backup, plus Oxidized for device-level configuration
FTD managed by FDMThe on-box Firepower Device ManagerManager backup, plus exported configuration
ASA with FirePOWER moduleFMC or ASDM for module policyASA configuration through Oxidized, module policy through its manager
FXOS chassisChassis manager and FXOS CLIChassis export, plus Oxidized for CLI configuration where supported

What the Device CLI Shows

On an FTD managed by FMC, the device CLI can display parts of the running configuration, and an administrator can reach the underlying ASA-style prompt through the diagnostic CLI. That output reflects what FMC deployed, so it is useful as an independent record of the deployed state. However, it is not a source from which you can rebuild access control, intrusion, or SSL policy, because those policies are defined and stored in FMC.

Backing Up the Firepower Management Center

FMC provides its own backup and restore function, including scheduled backups to remote storage. For a production deployment, this is the primary protection for policy. In addition, FMC includes an import and export function for selected policies, and a REST API that can retrieve policy objects. Pairing scheduled FMC backups with Oxidized captures of each FTD device gives you two independent layers: the policy source, and the deployed result.

A Practical Firepower Backup Strategy

  1. Schedule FMC backups to a remote target and verify that the files are restorable on a lab FMC.
  2. Capture each FTD device’s running configuration with Oxidized to record what was actually deployed.
  3. Store FMC deployment history and audit logs in your log platform.
  4. For FDM-managed devices, schedule exports through the manager and archive them alongside Oxidized history.
  5. For FXOS chassis, export the chassis configuration after every significant change.

Because model names and support for Firepower platforms change between Oxidized releases, check the model list for your installed version, and test against a lab device before trusting the results. Where support is incomplete, a custom model following the patterns shown above is usually a small amount of work.

Git Versioning for Firewall Configurations

Why Git Fits

ASA configurations are line-oriented text where one added access list entry is one added line. Consequently, Git diffs show precisely what changed, and a one-line change inside a twelve-thousand-line configuration remains easy to find. Git also provides integrity, compact storage, and a toolset that auditors recognize.

Reading the History

git clone /srv/oxidized/cisco-firewalls.git ~/cisco-configs cd ~/cisco-configs # Last five changes to one firewall git log -5 --stat -- asa-single/fw-asa-hq-01 # What changed in the latest commit git show HEAD -- asa-single/fw-asa-hq-01 # Compare two points in time git diff HEAD~10 HEAD -- asa-single/fw-asa-hq-01

Because nodes are stored under their group directory, adjust the paths to match. Commit messages record the node, so git log --grep finds every change to a firewall quickly.

Push to a Remote Repository

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

The hook works with any SSH-reachable Git server. Use a deploy key limited to this repository and protect the main branch so history cannot be rewritten.

Taming Noise in Cisco Firewall Backups

A useful Git history contains commits that mean something. When every hourly run creates a commit, reviewers stop paying attention, and the one meaningful change gets lost. Fortunately, ASA noise comes from a short and predictable list.

Noise SourceWhat HappensRemedy
Written-by headerThe comment line recording who saved the configuration and when changes with every writeStrip it in the model, as the custom models above do
Uptime in version outputUptime increases constantlyRemove the uptime line from the captured version text
Timestamps in certificates and keysGenerated values shift after renewalsAccept as legitimate changes
Masked secretsAsterisks appear identically, but a changed secret is invisibleDecide on a secrets policy, covered below
Failover stateActive and standby units show different transient linesKeep each unit as its own node
Context churnNew contexts appear in the system configurationTreat as a signal to add a node

After changing any model, run two consecutive backups of a quiet lab firewall. If the second run produces a commit, noise remains. Repeat until two consecutive runs produce identical files, and only then deploy the model broadly.

The Secrets Decision

Because the default output masks keys, a quiet danger follows. If someone changes a tunnel group pre-shared key, the masked line looks identical before and after, and Git records no change. Consequently, your history is accurate about structure and silent about secrets.

PolicyWhat You GainWhat You Risk
Default output with masked secretsSafer repository, clean diffsCannot restore VPN keys, cannot detect key changes
More complete output with encrypted secretsBetter restore fidelityRepository must be protected like a credential store
Default output plus a separate encrypted ASA backupClean diffs and full-fidelity recoveryTwo artifacts to manage

For most teams, the third policy is the best balance. Oxidized stores the readable, masked history for review, while a scheduled ASA backup, which includes certificates, keys, and related files, goes to encrypted storage.

The ASA Backup Command

Recent ASA software includes a backup command that bundles the configuration and related files into an archive. Its options let you protect the archive with a passphrase and choose a destination.

backup location tftp://10.10.50.25/asa-backups/fw-asa-hq-01.tar.gz passphrase ChangeThisBackupPassphrase

Syntax and supported destinations differ between releases, so check backup ? on your version. In addition, restrict the destination server tightly and encrypt the passphrase’s storage, because an archive plus its passphrase is a complete copy of the firewall’s identity.

Checking Running Against Startup

Because an ASA can run with unsaved changes, a periodic comparison between running and startup is a valuable hygiene check. A difference means that a reload would roll back someone’s work.

  1. Retrieve the startup configuration with the same service account.
  2. Remove comment and header lines that legitimately differ.
  3. Compare the result against the latest Oxidized version.
  4. Investigate any remaining differences and decide whether to save or revert.
ssh oxidized@10.10.1.2 "show startup-config" | grep -v '^[:!]' > /tmp/startup.cfg grep -v '^[:!]' ~/cisco-configs/asa-single/fw-asa-hq-01 | diff - /tmp/startup.cfg | head -40

This example assumes the account lands in privileged mode automatically. If you use an enable password, add the enable step to the session. Any differences it prints are either saved-but-unreloaded changes or running changes that nobody saved, and both deserve a conversation.

Real-Time Backups with Syslog Triggers

Hourly polling leaves a gap between a change and its capture. ASA can announce configuration commands through syslog, which closes the gap.

How It Works

  1. An administrator executes a configuration command on the firewall.
  2. The ASA generates a command-execution message in the 1110xx range.
  3. The message is forwarded to the Oxidized server over syslog.
  4. rsyslog hands the sender address and message to a script.
  5. The script recognizes a configuration command and calls the Oxidized API.
  6. Oxidized fetches the running configuration and commits the diff.

Configure Logging on the ASA

logging enable logging timestamp logging trap notifications logging host inside 10.10.50.25 udp/514

These commands turn on logging, include timestamps, send messages at the notifications level and above, and forward them to the Oxidized host. Command-execution messages are generated at the notifications level, which is why that severity matters. If your ASA reaches the server through a different interface, change the interface name accordingly.

Configure rsyslog and the Script

template(name="ipmsg" type="string" string="%fromhost-ip% %msg%\n") module(load="imudp") input(type="imudp" port="514" ruleset="asa") ruleset(name="asa") { action(type="omprog" binary="/usr/local/bin/oxidized-trigger.sh" template="ipmsg") }
#!/bin/bash while read -r ip msg; do case "$msg" in *"User 'oxidized'"*) ;; *"%ASA-5-111008"*|*"%ASA-5-111010"*|*"%FTD-5-111008"*) curl -s "http://127.0.0.1:8888/node/next/${ip}" > /dev/null ;; esac done

Notice the first pattern. Oxidized’s own session runs commands on the firewall, and without an exclusion for the backup account those commands could trigger another backup, which would trigger another, and so on. Excluding the service account breaks that loop. Message wording varies slightly across releases, so capture samples from your own firewalls and adjust. Furthermore, a short debounce, such as processing each address at most once every thirty seconds, keeps busy change windows from flooding the queue.

Using the Oxidized REST API and Web Interface

EndpointPurpose
/nodesLists 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
/node/version?node_full=GROUP/NAMELists stored versions
/reloadReloads the inventory

The JSON node list is a convenient monitoring source. Alert on any node that remains in a failed state for more than two intervals, since that catches expired credentials, changed SSH access lists, and context nodes that no longer exist.

Securing the Backup Pipeline

Firewall configurations disclose address plans, NAT, VPN peers, and policy logic, so the repository deserves the same care as a credential store.

ControlRecommendation
Service accountDedicated user, SSH only from the Oxidized server, long random password or key
PrivilegePrefer automatic enable or command authorization over a shared enable password
SSH settingsVersion 2 only, strong ciphers where supported, current Oxidized image
Host key checkingEnable in Oxidized after populating known hosts
API exposureBind to localhost, publish only through an authenticated TLS proxy
RepositoryPrivate remote, deploy key, protected main branch
Encryption at restUse gitcrypt or disk encryption on the backup server
Archive passphrasesStore in a secrets manager, separate from the archives
MonitoringAlert on failed nodes and unexpected commits

These measures follow the same principles as CIS Controls for network device configuration and the configuration management controls in NIST SP 800-53. Moreover, an AAA server such as TACACS+ gives you per-command accounting for the service account, which makes misuse visible.

Restoring Cisco Firewalls from Backups

Restoration differs sharply across the platforms, and the most common error is assuming that loading a file replaces the configuration.

Restoring an ASA

Copying a configuration file to the running configuration merges it into whatever is already there. It does not replace it. Therefore, a clean restore either wipes the configuration first or loads the file as the startup configuration followed by a reload.

  1. Retrieve the target version from Git and confirm it with git diff against the current state.
  2. Review the file for masked secrets, which load literally as asterisks if you paste them back.
  3. Place the file on a TFTP, SCP, or flash location the ASA can reach.
  4. For a clean rebuild, copy the file to the startup configuration and reload.
  5. For a targeted rollback, paste only the affected sections into configuration mode.
  6. Save with write memory, then verify traffic, VPNs, NAT, and failover state.
copy tftp://10.10.50.25/fw-asa-hq-01.cfg startup-config reload

After the reload, re-enter any secrets that the masked output could not preserve, and restore certificates and keys from the encrypted ASA backup. Importantly, rehearse this procedure on a spare unit, because the first restore attempt always reveals something that the runbook missed.

Restoring a Multi-Context ASA

Restore the system context first, since it defines the contexts and their configuration locations. Then restore each user context from its own history. The system configuration references a configuration URL for each context, so copying the context file to that location and reloading the context is one route, while pasting the content into the context after switching to it is another. Consult your software version’s documentation for the exact reload mechanism, and test it in a lab before relying on it.

Restoring Firepower Threat Defense

For an FTD managed by FMC, the device is largely disposable and the policy source is not. A failed device is typically re-imaged, registered to the FMC again, and then receives its policies through a deployment. Consequently, your most important restore asset is a verified FMC backup, not the device CLI output. FMC restores generally require a matching software version, so record versions alongside every backup.

PlatformPrimary Restore PathOxidized Output Role
ASA, single contextStartup configuration load and reloadPrimary source
ASA, multiple contextsSystem first, then each contextPrimary source per context
FTD with FMCRe-register, then deploy from FMCIndependent record of deployed state
FTD with FDMRestore from the manager backupLimited reference
FXOS chassisImport chassis configurationReference where captured

Change Auditing and Compliance Evidence

Because every commit records what changed and when, Git history combined with firewall command logs forms a complete audit trail.

FrameworkRelevant AreaHow the Workflow Helps
NIST SP 800-53CM-2, CM-3, CM-6Baselines, tracked changes, documented settings
CIS ControlsSecure configuration of network devicesVersioned, reviewable firewall policy
ISO 27001:2022Configuration managementRetrievable configuration history
PCI DSS 4.0Network security control reviews and approved changesDiffs that simplify periodic review
SOC 2Change management criteriaTimestamped records of production changes

To put this to work, send a daily digest of commits to the network and security teams, and require that each commit correlate with an approved change ticket. As a result, undocumented changes surface within a day instead of at the next audit.

Scaling Across Many Firewalls

Groups for Roles and Credentials

Use groups to separate datacenter, branch, and customer firewalls, and to carry different credentials and variables. Git places each group in its own directory, which keeps large repositories navigable.

A Source of Truth for the Inventory

A CSV file is sufficient for a pilot, though it drifts from reality over time. Switching to NetBox or an HTTP source means the inventory follows your documentation, and retired firewalls leave the rotation automatically.

Timing and Load

Firewall control planes are modest, so keep thread counts conservative and timeouts generous. Meanwhile, stagger polling across groups if hundreds of devices share a management network, and rely on syslog triggers for timely capture instead of shortening the interval.

Troubleshooting Cisco Firewall Backups in Oxidized

SymptomLikely CauseFix
Node shows no_connectionSSH access list or interface blocks the serverVerify the ssh statement and management-access, then test manually
Authentication failedWrong password, user not in the local database, or AAA mismatchTest the same login manually and review the aaa authentication ssh console setting
Enable password rejectedWrong secret or auto-enable already appliedMatch the method to the configuration and remove an unnecessary enable variable
Command authorization failedA command the model runs is not permitted for the userCapture the command list from a manual run and authorize each one
Output interrupted by more promptsPager not disabledConfirm the pager command runs before the configuration display
Hang or timeout after context switchPrompt pattern misses the context promptAllow slashes and context names in the prompt pattern
Only one context appears in GitModel captured only the login contextAdd system and per-context nodes as described
Key exchange or cipher errorStrict ASA SSH settings versus an outdated libraryUpdate the Oxidized image and review cipher settings
Commit on every runWritten-by line or uptime changingStrip volatile lines and verify two matching runs
Backup loop after syslog triggerOxidized’s own commands trigger messagesExclude the service account in the trigger script

Debugging a Single Node

Isolate the failing node, enable debug temporarily, and restart the container. Then run the same commands manually over SSH with the same account and compare the transcripts. If the manual session works and Oxidized does not, the culprit is nearly always the prompt pattern, the enable handshake, or a command that the account is not authorized to run.

After an ASA or FTD Upgrade

Major upgrades can alter banners, SSH algorithms, or command output. When backups begin failing afterward, update the Oxidized image, retest custom models, and compare a manual session with the model’s expectations. If the bundled model is at fault, report it to the project with the software version and a sanitized debug log.

Pitfalls Checklist

These are the mistakes that most often turn a working-looking backup into a hollow one.

  • Capturing only the login context on a multi-context ASA and assuming it is the whole configuration.
  • Trusting masked output as a complete restore source, then loading asterisks as real secrets.
  • Pasting a full configuration into the running configuration and expecting it to replace rather than merge.
  • Storing a shared enable password in Oxidized when automatic enable would avoid it.
  • Granting privilege 15 to a backup account without source restrictions.
  • Treating a device CLI capture of FTD as a substitute for FMC backups.
  • Forgetting the standby unit, then discovering its configuration diverged.
  • Allowing the backup account’s own commands to trigger syslog-driven backups in a loop.
  • Letting the written-by header or uptime create a commit every hour.
  • Never rehearsing a restore on a spare unit.

Oxidized Compared with Other Cisco Firewall Backup Options

MethodCostVersion ControlMulti-VendorBest Fit
OxidizedFreeNative GitYesReadable history and API across vendors
ASDM backupIncludedFile-basedNoOccasional manual backups
ASA backup command with schedulingIncludedFile-basedNoFull-fidelity archives with keys and certificates
FMC scheduled backupIncludedBackup setsNoFirepower policy protection
Cisco Defense OrchestratorLicensedChange logCisco focusedCloud-delivered policy management
Ansible with Cisco collectionsFreeYou build itYesTeams invested in Ansible
Commercial NCM suitesLicensedYesYesVendor support and reporting

In practice, these options layer rather than compete. Native backups provide full-fidelity recovery, FMC protects Firepower policy, and Oxidized provides the readable, multi-vendor history that sits next to your routers, switches, and other firewalls.

Real-World Scenarios

Scenario One: Tracing a Broken Partner VPN

A partner tunnel fails on Monday morning. The engineer opens the Git history for the partner context and finds a Friday commit that changed a crypto map entry and an access list. The diff shows the exact lines, the command log names the administrator, and the fix is a two-line revert instead of a day of packet captures.

Scenario Two: Discovering a Missing Context

During a quarterly review, the system context history shows a new context created three weeks earlier that was never added to Oxidized. Because the system backup recorded the definition, the team adds the node, captures its first backup, and closes a gap that had silently existed since the context was built.

Scenario Three: Replacing a Failed ASA

An ASA in a regional office fails. The replacement is staged with the same software version, loaded with the latest configuration as startup configuration, and reloaded. The engineer re-enters the VPN pre-shared keys from the secrets manager and restores certificates from the encrypted ASA backup. The office returns to service the same day, using a procedure the team had rehearsed.

Optimization Recommendations

AreaRecommendationBenefit
Enable handlingAutomatic enable or command authorizationNo shared enable secret in Oxidized
ContextsSeparate nodes for the system and every user contextComplete, separable history
SecretsMasked history in Git plus encrypted native backupsClean diffs and full-fidelity recovery
FirepowerFMC scheduled backups plus device capturesPolicy source protected and deployed state recorded
PollingHourly interval plus syslog triggersFresh data, low load
ModelsKeep custom models in version controlReviewable, reproducible behavior
RepositoryOff-site mirror and periodic garbage collectionResilience and smaller storage
DocumentationREADME with restore steps and version notesFaster recovery under pressure

Frequently Asked Questions

Does Oxidized support Cisco ASA?

Yes. Oxidized includes an asa model that connects over SSH, handles enable mode, disables the pager, and stores the configuration in Git or another output.

How does Oxidized handle enable mode on an ASA?

The model sends the enable command and answers the password prompt using the enable variable. Alternatively, configure automatic enable on login so no enable secret is needed.

Can Oxidized back up every context on a multi-context ASA?

Yes, with separate nodes. Capture the system context and each user context by switching contexts in a model, or by logging in to a context’s own management address.

Does Oxidized back up Firepower Threat Defense?

It can capture device-level configuration, but FTD policy lives in the Firepower Management Center or Firepower Device Manager. Use FMC backups as the primary protection.

Why are pre-shared keys missing from my ASA backup?

The default show running-config output masks them. Use a separate encrypted ASA backup for full-fidelity recovery, or consider more complete output with strict repository protection.

Is the running configuration enough to restore an ASA?

It restores most structure, but masked secrets, certificates, and keys need separate recovery. Keep an encrypted native backup alongside Oxidized history.

Does copying a file to running-config replace the configuration?

No. It merges the file into the existing running configuration. For a clean restore, load the file as the startup configuration and reload.

What permissions does the Oxidized account need on an ASA?

Access to privileged mode and permission to run show commands, pager settings, and any context-switch commands the model uses. Restrict SSH to the Oxidized server’s address.

How do I trigger a backup after each ASA change?

Forward command-execution syslog messages to a receiver, and run a script that calls the Oxidized next-node endpoint, excluding the backup account to avoid loops.

Why does Oxidized commit every time it runs?

A volatile line, usually the written-by header or uptime, changes between runs. Strip those lines in the model and confirm that two consecutive runs match.

Conclusion

Backing up Cisco firewalls with Oxidized is straightforward once you respect how the platforms behave. Enable mode needs a deliberate, least-privilege answer. A multi-context ASA needs one capture per context, including the system context. Masked secrets need a complementary native backup. And Firepower needs its management center protected on its own terms, with Oxidized recording what was actually deployed. Furthermore, syslog triggers and a startup-versus-running check turn the repository from a periodic snapshot into a living, trustworthy record.

The practical next step is small. Pick one lab ASA, confirm that enable handling works, capture two consecutive backups with no noise, and rehearse one restore. After that, extend the pattern to contexts, add the encrypted native backups, and fold FMC backups into the same operational rhythm. Together, these pieces replace hope with evidence.

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.