Editing Palo Configs by Scripts: pan-os-php

There are recurring cases where tasks cannot be edited quickly and easily using the classic Palo Alto Networks GUI or Panorama. For example, editing multiple policies at once, such as during a zone migration. Or checking which policies haven’t log forwarding enabled, hence enabling it directly. Or finding unused objects, including deleting them.

For these situations (and many more!), there’s a tool with a wealth of predefined scripts: pan-os-php. This first blog post covers installation and some initial use cases.

Installation

pan-os-php is based on Docker and is maintained by Sven Waschkut. (Note that it was formerly under the hood of Palo Alto Networks itself, but is not updated anymore there.)

If you are using Windows, you can use the Windows Subsystem for Linux (WSL) as the easiest way to get it working:

Mac users can use Colima.

For the Docker part, you can follow the official documentation, which is:

Adding the current user to the Docker group to be able to start Docker without root privileges: (logout required after the following command to get it working)

By the way: It seems that Docker does not offer IPv6 support by default. What a shame! Come on, it’s 2025! Some help is here.

The installation of pan-os-php is simple: (Use the same command to update it later on.)

To start pan-os-php, always use the following command:

Basic Steps

Being in the Docker instance, everything starts with “pan-os-php” again. Press Tab two times to get some inline information. Quite useful helping keywords are: listfilters, listactions, and help, which work almost everywhere.

A very basic command uses the following three options:

  • in=filename.xml
  • type=<various-types-see-examples-below-or-inline-help>
  • out=filename-out.xml <- if not used, the default output is /dev/null ;)

1) Getting the Configuration

You can either manually download an XML file from a Palo/Panorama and place it into your working directory (which is automatically listed as the “/share” folder), or you can download it via the API from the device itself. This requires the type=upload:

Here’s a sample run:

 

After that, you can use this local XML rather than the API for every step you’re doing.

2) Do Something

Now you can work with this freshly downloaded XML file in various ways. Please have a look at the “First Use Cases” below.

A few basic keywords, though:

  • location=vysyX <- Select the vsys for a firewall (default: vsys1) or the device group for a Panorama (default: shared).
  • template=any <- Select the template if you’re within Panorama.

As a best practice, you should always do a first run with only the filter criteria (in order to see which objects will be touched), followed by a second run with the actual requested action.

3) Get the Changes

I personally prefer to extract “set” commands that I can use on the CLI on a Palo/Panorama rather than uploading a complete XML to the device itself. Fortunately, this can be done in the following way, which compares the input and output XMLs and displays appropriate “set” commands:

pan-os-php type=diff file1=pa-test1.xml file2=pa-test1-out.xml outputformatset

Alternatively, you can omit step 3 by specifying the following “outputformatset” directly within the “Do Something” part, which is: outputformatset=textfile.txt.

First Use Cases

Finding (and deleting) unused objects

For sure, everyone has unused objects such as addresses, groups, services, etc. Use pan-os-php in the following way to get rid of those objects. Hint: Yes, pan-os-php works recursively with this cool object filter: “is.unused.recursive”.

First run, just to get some information on which objects are unused, looking at the “address” and “service” objects here:

Second run to delete those objects. Note that you need the “out=” parameter for this while the 1st out is the 2nd in:

Finally, generating the “set” commands:

Now I can use those commands within the CLI to get rid of those unused objects. Just for reference, here are a few commands out of my test run:

Activating log and log forwarding on all policies

If you really want to be sure that you’re logging every policy hit, just do this. First run: on which policies is either the “log at session end” not set, or no log forwarding profile specified:

Second run, enabling “log at session end” on all of those policies and setting the log forwarding to the profile called “default”. Multiple actions in the same run can be done by separating them with a slash. This time, I’m using the appendix “outputformatset=textfile.txt” to get the required commands directly rather than setting the “out=…” parameter:

Here are a few of such commands, just for reference again. Note that only the required commands are listed by pan-os-php, that is: rules that had either the logging enabled or the log forwarding set already will only get the other required command (last two lines):

Migrating a zone to another

A slightly more complex scenario: In case you are migrating some networks from one zone to another, you want to add a second src|dst zone to all rules that currently have another zone as their src|dst.

In this example, I’m using pan-os-php with a panorama.xml file, hence specifying a location. The zone “S2S-VPN” shall get a sibling of “Transfer”. I’m doing the “from” in the first run, and the “to” in a second, while extracting the set commands from a diff between the original input and the 2nd output:

Yet another example. Replacing (rather than adding) one zone to another, in this case: “WAN” becomes “Transfer”, both for “from” and “to”. No filter needed, since only policies are involved where the current WAN zone is present. Both actions at one. One-liner:

Outlook

Please use the “listfilters” and “listactions” helpers to get ideas about what you can do with pan-os-php, or to find out which parameters the individual sections require.

Some more advanced use cases are:

  • rule analyses concerning best practices (formerly Iron Skillet)
  • firewall migration from 3rd party devices, e.g. Sophos (formerly Expedition)
  • correction of misconfigured objects

Some of those will be covered in upcoming blog posts. Stay tuned.

Photo by Mohamed Munawwar Luthfee on Unsplash.

Leave a Reply

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