Palo Alto Automated Scheduled Configuration Backup
I'm writing this in February 2025, and as far as I know, Palo Alto firewalls (not Panorama) don’t have a built-in mechanism for automatic configuration backups. Panorama, on the other hand, supports scheduled backups and allows you to send them to various locations like an SCP or FTP server. I’m not sure why this feature isn’t available on standalone firewalls, but in any case, let’s look at how you can use the API to periodically fetch the configuration from the Palo Alto firewall.
As always, if you find this post helpful, press the ‘clap’ button. It means a lot to me and helps me know you enjoy this type of content.
Overview
The Palo Alto KB article explains how to use the XML API with cURL to fetch the configuration and then use a cron job to run it periodically. This method works, but I want to make some tweaks to ensure we have a proper backup in place.
For this example, I’ll use a Python script and create a dedicated admin user with very limited permissions for backing up the configuration. We’ll then set up a cron job to take the backup every day at 1 AM.
Creating an Admin User and API Key
As I mentioned, I want to create a separate admin user with very limited permissions. We’re only going to grant access to the XML API's 'export' permission. This means that even if someone tries to log in to the GUI with this user, they won’t have access to anything or any of the tabs.
As usual, navigate to Device > Admin Roles and create a role with only the 'Export' permission under the XML API. De-select everything else.
Next, create a new admin user and assign this role to the user. This is all that’s needed to back up the configuration using the XML API.
Next, we need to generate or obtain the API key for this user account. The easiest way to do this is by running the following cURL command. Replace the Firewall IP, username and password with your own.
curl -k -X GET 'https:YOUR_FIREWALL_IP/api/?type=keygen&user=xml_api_backup&password=SECRET_PWD'
In the response, copy the API key and keep it somewhere safe. Keep in mind that if you change the password in the future, you’ll need to regenerate the key.
Config Backup with CURL
Let's start by following the instructions from the Palo Alto KB article and using a cURL command. The command may look something like this.
curl -kG "https://FIREWALL_IP/api/?type=export&category=configuration&key=YOUR_KEY" > running-config-curl.xml
This pulls the configuration and saves it in the current working directory. While this works, I noticed that the XML file isn’t formatted correctly. However, I was still able to load the config back into the firewall, and it was accepted.
I didn’t want to spend time tweaking cURL to fix this, so I decided to use Python instead. If you prefer cURL, feel free to use it.
Config Backup with Python
Here's a Python script to fetch the firewall configuration using the XML API and save it in a properly formatted XML file. I'm creating the Python file called main.py
in a directory called palo_configs
. You also need to create a directory called backups
to save the backup files.
Before running the script, you need to set the API_KEY
as an environment variable.
export API_KEY="YOUR_KEY_HERE"
import requests
import xml.dom.minidom
from datetime import datetime
import os
requests.packages.urllib3.disable_warnings()
current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M")
filename = f'firewall_config_{current_datetime}.xml'
api_key = os.getenv("API_KEY")
url = f"https://FIREWALL_IP/api/?type=export&category=configuration"
headers = {'X-PAN-KEY': api_key}
r = requests.get(url, verify=False, headers=headers)
dom = xml.dom.minidom.parseString(r.text)
formatted_xml = dom.toprettyxml(indent=" ", newl="\n", encoding="utf-8")
with open(f"/home/suresh/palo_configs/backups/{filename}", 'wb') as f:
f.write(formatted_xml)
When you run the script, it saves the backup file in the backups directory with the date and time appended to the filename. Make sure the directory exists before running the script, or the script will fail to save the file.
The response from the firewall is in XML format, and the following lines take care of formatting the XML.
dom = xml.dom.minidom.parseString(r.text)
formatted_xml = dom.toprettyxml(indent=" ", newl="\n", encoding="utf-8")
xml.dom.minidom.parseString(r.text)
- Parses the raw XML response from the firewall.dom.toprettyxml(indent=" ", newl="\n", encoding="utf-8")
- Converts the parsed XML into a nicely formatted version with proper indentation and line breaks.
This ensures the config file looks similar to how it would appear if you manually exported it from the firewall GUI.
Cron Job for Periodic Backups
So far, we’ve been running the script manually, but we can automate it using a cron job to run at 1 AM every day. To make this work, here are the files we need to have.
- backups - Directory where the backup files are stored.
- main.py - The Python script that fetches and saves the firewall configuration.
- key.env - A file that stores the API key. Make sure this file is not accessible to unauthorized users.
- backup_script.sh - A simple Bash script to run the Python script with the API key loaded.
├── backups
│ ├── firewall_config_2025-02-26_12-35.xml
│ └── firewall_config_2025-02-26_12-40.xml
├── backup_script.sh
├── key.env
└── main.py
1 directory, 5 files
API Key Storage (key.env
)
Instead of hardcoding the API key, we store it in key.env file. Please ensure this file is not world-readable to prevent unauthorized access. Add the following to the key.env
file and modify the permission.
export API_KEY="YOUR_KEY_HERE"
chmod 600 /home/suresh/palo_configs/key.env
Bash Script (backup_script.sh
)
This script loads the API key from key.env and runs the Python script. Make sure this script has permission to execute.
#!/usr/bin/bash
source /home/suresh/palo_configs/key.env
/usr/bin/python3 /home/suresh/palo_configs/main.py
chmod +x backup_script.sh
Adding the Cron Job
To schedule the backup at 1 AM daily, edit the crontab file and add the following line at the bottom.
crontab -e
0 1 * * * /home/suresh/palo_configs/backup_script.sh
This tells cron to execute backup_script.sh
at 1 AM every day. After saving the crontab file, verify it’s added by running the following command. This ensures the backup runs automatically without manual intervention.
crontab -l
If the cron job isn’t working as expected, you can log its output to a file to help with troubleshooting. Modify the cron job to redirect both standard output and errors to a log file. Set the timer to */5 * * * *
if you want to run the script every five minutes during the troubleshooting rather than waiting for a whole day.
*/5 * * * * /home/suresh/palo_configs/backup_script.sh >> /home/suresh/palo_configs/backup.log 2>&1
Closing Up
I hope you find this post useful, and if you have any better ideas, please let me know in the comments.