1. XML API L100

Hands-on tasks for this workshop will be performing XML API calls against a PAN-OS firewall, from your command-line environment, using the curl command. For each task, you can use the copy button to take the command into the clipboard, but ensure you replace any UPPERCASE_VARIABLES with your own values.

Assumptions: A host with curl installed, access to a PAN-OS next-generation firewall from your host.

Note:
  • Lookout for text in uppercase, such as YOUR_FIREWALL_IP, and replace the text with the relevant value for your environment.

  • Commands you could/should execute are denoted with $ at the start, and have copy buttons; other text boxes show expected outputs.

  • You may wish to have a text editor open on your machine, to amend copied commands before pasting them into the host’s CLI.

1.1. Store our firewall’s IP as a variable

First, to make our lives easier, we will assign the management IP address of the firewall to a variable, so we can easily refer to it in our API calls.

Today, in this environment, we will assign the API key value to a variable called host, to be used in future API calls. The export command stores the value of host in memory for the duration of the CLI session.

$ export host='YOUR_FIREWALL_IP'

1.2. Generate your API key

Before you can make any API calls, you need to generate an API key. Your API key will allow you to authenticate and authorise yourself for future API calls.

$ curl -ksd 'type=keygen&user=YOUR_ADMIN_USERNAME&password=YOUR_ADMIN_PASSWORD' https://$host/api -w "\n" | xmllint --format -
<response status = 'success'><result><key>LUFRPT16V1ZzaHNFYVJEdlZnb3Buc1dJRWtCVFFPYjFXTzI2N1phVzRsMg==</key></result></response>

In production environments, credentials should be stored, accessed and used securely, per the security policy and compliance requirements. Today, in this environment, we will assign the API key value to a variable to be used in future API calls. Take the characters between the key tags from the previous output as your API key, in the example above this is the characters from LUFRPT16... to ...Mg==

$ export key='YOUR_API_KEY'

For example:

$ export key='LUFRPT16V1ZzaHNFYVJEdlZnb3Buc1dJRWtCVFFPYjFXTzI2N1phVzRsMg=='

1.3. Make your first real API call

Your first API call will tell you if the firewall is in a ready and operational state. This operational command is useful to know if the firewall has been recently rebooted, or in the case of software firewalls like VM-Series or CN-Series, recently created. The answer should be yes, within the XML-formatted response.

$ curl -ksd "type=op&cmd=<show><chassis-ready></chassis-ready></show>&key=$key" https://$host/api -w "\n" | xmllint --format -
<?xml version="1.0"?>
<response status="success">
<result><![CDATA[yes
]]></result>
</response>

1.4. Get firewall system info

Next, retrieve information about the firewall system. This too is an operational command, as shown by type=op within the API call. The cmd= portion contains the operational command we want to execute.

$ curl -ksd "type=op&cmd=<show><system><info></info></system></show>&key=$key" https://$host/api -w "\n" | xmllint --format -

1.5. Show the routing table

Another useful operational command is to display the routing table.

$ curl -ksd "type=op&cmd=<show><routing><route></route></routing></show>&key=$key" https://$host/api -w "\n" | xmllint --format -

1.6. Show the rulebase configuration

Now we look at the firewall configuration. Notice the type of API call this time is type=config, and the action is get, which as expected tells the API we want to do a read operation on the configuration. The xpath is then used to navigate down through the XML configuration file structure to specifically find the rules within the security policy.

$ curl -ksd "type=config&action=get&xpath=/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules&key=$key" https://$host/api -w "\n" | xmllint --format -

1.7. Show the rulebase hit counts

We’ve seen the rulebase from the configuration, but if we wanted to programmatically retrieve the hit counts for each rule, that would be an operational command.

$ curl -ksd "type=op&cmd=<show><rule-hit-count><vsys><vsys-name><entry name='vsys1'><rule-base><entry name='security'><rules><all/></rules></entry></rule-base></entry></vsys-name></vsys></rule-hit-count></show>&key=$key" https://$host/api -w "\n"| xmllint --format -

1.8. Backup/export configuration

This is a common API call, given how many people have requirements to automate backing up configurations. This uses type=export to signify we are exporting something, and category=configuration describes the exact item we want to export.

$ curl -ksd "type=export&category=configuration&key=$key" https://$host/api -w "\n" | xmllint --format -

The command above sent the config file to the CLI terminal, we could instead save it to a file:

$ curl -ksd "type=export&category=configuration&key=$key" https://$host/api -w "\n" > exported_config.xml

1.9. User-ID

A frequent use case is to register user-to-IP mappings. The first task here, another operational command, shows the current user-to-IP mapping table, and should give an empty response.

$ curl -ksd "type=op&cmd=<show><user><ip-user-mapping><all/></ip-user-mapping></user></show>&key=$key" https://$host/api -w "\n" | xmllint --format -
<response status="success"><result></result></response>

The next API call registers a username to an IP address. This uses type=user-id. Note we pass in the username, the IP address they are currently using, and a timeout value (in seconds).

$ curl -ksd "type=user-id&cmd=<uid-message><version>2.0</version><type>update</type><payload><login><entry name=\"NewUser\" ip=\"10.50.100.9\" timeout=\"120\"/></login></payload></uid-message>&key=$key" https://$host/api -w "\n"

Replaying the API call to show the mapping table should now display the new user

$ curl -ksd "type=op&cmd=<show><user><ip-user-mapping><all/></ip-user-mapping></user></show>&key=$key" https://$host/api -w "\n" | xmllint --format -

1.10. Find An API Command - CLI Debug

One way to find an API call for specific operation is to observe or “debug” the CLI, which itself uses the XML API. Once debugging is enabled, an XML API call will be displayed when a CLI command is executed.

Using the example of our first API call in this workshop, the CLI command equivalent is “show chassis-ready”. When debugged, this gives the following output:

admin@firewall> debug cli on
admin@firewall> show chassis-ready
(container-tag: chassis-ready pop-tag:)
((eol-matched: . #t) (context-inserted-at-end-p: . #f))

<request cmd="op" cookie="5461146855105504" uid="1000"><operations><show><chassis-ready/></show></operations></request>

2021-11-05 12:56:57
<response status="success"><result><![CDATA[yes]]></result></response>

yes

Note the highlighted lines, first the command for turning on CLI debugging, then the execution the command of interest (show chassis-ready), then the observation of the XML API equivalent for the CLI command.

The XML required to make a call ourselves is between (but not including) the <operations></operations> tags. This gives us <show><chassis-ready/></show>, which becomes the cmd= portion of the final API command: https://$host/api/?type=op&cmd=<show><chassis-ready></chassis-ready></show>&key=$key

Connect to the firewall using SSH:

$ ssh YOUR_ADMIN_USERNAME@$host

Then choose one (or more) of the following operational commands, debug the CLI, then create and execute XML API command equivalents. You may wish to use two CLI windows, your original CLI for performing XML API commands, and a second CLI for SSH to the firewall.

  • show system masterkey-properties

  • show arp all

  • show interface management

  • clear user-cache all

1.11. Find An API Command - API Browser

Another way to find an API call for specific operation is to use the API browser, which can be found at https://firewall/api. Once logged in to the web GUI, browse to https://firewall/api and a listing of the types of available XML API request types is displayed. Hyperlinks can be used to browse through the XML API request types until the required request format is found.

Again using the example of our first API call in this workshop, show chassis-ready, click the Operational Commands link, then the show link, then the chassis-ready link. You will be shown the XML API format we observed in the CLI (<show><chassis-ready/></show>), as well as the XML API URL structure (/api/?type=op&cmd=<show><chassis-ready></chassis-ready></show>). Clicking the hyperlinked XML API URL performs the API command and displays a result.

Choose one (or more) of the following operational commands, find the command in the API browser, then create and execute XML API command equivalents:

  • show clock

  • show admins all

  • clear counter all

  • show system disk-space