/go-panos

Go package to interact with Palo Alto devices.

Primary LanguageGoMIT LicenseMIT

go-panos

GoDoc Travis-CI Go Report Card

A Go package that interacts with Palo Alto devices using their XML API. For official and detailed package documentation, please visit the Godoc page.


This API allows you to do the following:

  • List objects on devices: address, service, custom-url-category, device-groups (Panorama), policies, tags, templates, log forwarding profiles, security profile groups, managed devices (Panorama), etc..
  • Retrieve information about all applications (predefined) or a single one.
  • Create, rename, and delete objects.
  • Create security rules.
  • View jobs on a device.
  • Query and retrieve the following log-types: config, system, traffic, threat, wildfire, url, data.
  • Create multiple objects at once from a CSV file. You can also specify different device-groups you want the object to be created under (object overrides), as well as tag them.
  • Modify address and service groups using a CSV file.
  • Create, apply, and remove tags from objects and rules.
  • Create EDL's (External Dynamic List).
  • Add/remove objects from address/service groups and custom-url-categories.
  • Create templates, template stacks and assign devices and templates to them (Panorama).
  • Commit configurations and commit to device-groups (Panorama).
  • Apply a log forwarding or security profile to an entire policy or individual rules.
  • Manipulate any part the configuration using Xpath functions (advanced).

The following features are currently available only on the local firewall:

  • List the NAT policy.
  • View the entire routing table and details about each route.
  • Gather information about each session in the session table.
  • Get all of the interface information configured on a firewall.
  • Create interfaces (including sub-interfaces), zones, vlans, virtual-wires, virtual-routers and static routes.
  • Add and remove interfaces to zones, vlans and virtual-routers.
  • List all configured IPSec VPN tunnels, gateways, and crypto profiles.
  • Create IPSec VPN tunnels, gateways, and crypto profiles.
  • Add/delete proxy-id's to IPSec VPN tunnels.
  • Test URL's to see what they are being categorized under.
  • Test route lookup.

Installation

go get -u github.com/scottdware/go-panos

Usage

import "github.com/scottdware/go-panos"

Establishing A Session

There are two ways you can authenticate to a device: username and password, or using the API key. Here is an example of both methods.

// Username and password
creds := &panos.AuthMethod{
    Credentials: []string{"admin", "password"},
}

pan, err := panos.NewSession("pan-firewall.company.com", creds)
if err != nil {
    fmt.Println(err)
}

// API key
creds := &panos.AuthMethod{
    APIKey: "Awholemessofrandomcharactersandnumbers1234567890=",
}

pan, err := panos.NewSession("panorama.company.com", creds)
if err != nil {
    fmt.Println(err)
}

The moment you establish a successful connection to the device, various information and statistics are gathered. They are assigned to a field in the Palo Alto struct (click the link for the list of fields), and can then be iterated over.

// View the device's uptime
fmt.Println(pan.Uptime)

// View the device's application and threat version, as well as when they were released
fmt.Printf("App Version: %s (Released: %s)\n", pan.AppVersion, pan.AppReleaseDate)
fmt.Printf("Threat Version: %s (Released: %s)\n", pan.ThreatVersion, pan.ThreatReleaseDate)

Configuration Using Xpath

Outside of the built in functions that make working with the configuration simpler, there are also functions that allow you to modify any part of the configuration using Xpath. The following configuration actions are supported:

show, get, set, edit, delete, rename, override, move, clone, multi-move, multi-clone

NOTE: For specific examples of how to use xpath values when using these actions, visit the PAN-OS XML API configuration API.

The above actions are used in the following go-panos functions:

XpathConfig() XpathGetConfig() XpathClone() XpathMove() XpathMulti()
set, edit, delete, rename, override show/get active or candidate configuration clone move multi-move, multi-clone

NOTE: These functions are more suited for "power users," as there is a lot more that you have to know in regards to Xpath and XML, as well as knowing how the PANOS XML is structured.

Handling Shared objects on Panorama

By default, when you establish a session to a Panorama server, all object creation will be in the device-group you specify. If you want to create them as shared, you need to first tell your session that shared objects will be preferred by doing the following:

// Establish a session
creds := &panos.AuthMethod{
    Credentials: []string{"admin", "password"},
}

pan, err := panos.NewSession("panorama.company.com", creds)
if err != nil {
    fmt.Println(err)
}

// Enable shared object creation
pan.SetShared(true)

// Create an address object
pan.CreateAddress("test-ipv4-obj", "ip", "1.1.1.2/32", "A test object")

// Turn off shared object creation
pan.SetShared(false)

Retrieving Logs

You can retrieve logs from any Palo Alto device using the QueryLogs() and RetrieveLogs() functions. The QueryLogs() function is used to first specify what type of log you want to retrieve, as well as any optional parameters such as a query: (addr.src in 10.1.1.1) and (port.dst eq 443). These optional parameters are defined using the LogParameters struct.

When you run the QueryLogs() function, it will return a job ID. This job ID is then used by RetrieveLogs() to query the system to see if the job has completed, and the data is ready to be exported. If the job status is not FIN then you will need to run RetrieveLogs() again until it has finished.

NOTE: In regards to how long you should wait to run RetrieveLogs(), I have tested a query against a lot of data, both on Panorama and a local firewall, and waited up to 2 minutes before retrieving them. Most times, you will get results within 5-10 seconds depending on your query.

View the documentation for the LogParameters struct.

When iterating over the returned logs, there are many fields you can choose to display. View the documentation for the Log struct fields for a complete list.

Below is an example of how to retrieve traffic logs.

// Establish a session
creds := &panos.AuthMethod{
    Credentials: []string{"admin", "password"},
}

pan, err := panos.NewSession("panorama.company.com", creds)
if err != nil {
    fmt.Println(err)
}

// Query traffic logs for a specific source address, and return 20 logs.
params := &panos.LogParameters{
    Query: "(addr.src in 10.1.1.1) and (app eq ssl)",
    NLogs: 20,
}

jobID, err := pan.QueryLogs("traffic", params)
if err != nil {
    fmt.Println(err)
}

// Wait 5 seconds before retrieving the logs. If the job still has not finished, then you will have to 
// run this same function again until it does.
time.Sleep(5 * time.Second)

logs, err := pan.RetrieveLogs(jobID)
if err != nil {
    fmt.Println(err)
}

// Here, we are looping over every log returned, and just printing out the data. You can manipulate the data and
// choose to display any field that you want.
for _, log := range log.Logs {
    fmt.Printf("%+v\n", log)
}

Creating Objects from a CSV File

This example shows you how to create multiple address and service objects, as well as address and service groups using a CSV file. You can also do object overrides by creating an object in a parent device-group, then creating the same object in a child device-group with a different value. Tagging objects upon creation is supported as well.

The CSV file should be organized with the following columns:

name,type,value,description (optional),tag (optional),device-group.

NOTE: Here are a few things to keep in mind when creating objects:

  • For the name of the object, it cannot be longer than 63 characters, and must only include letters, numbers, spaces, hyphens, and underscores.
  • If you are tagging an object upon creation, please make sure that the tags exist prior to creating the objects.
  • When creating service groups, you DO NOT need to specify a description, as they do not have that capability.
  • When you create address or service groups, I would place them at the bottom of the CSV file, that way you don't risk adding a member that doesn't exist.
  • When creating objects on a local firewall, and not Panorama, you can leave the device-group column blank.

Creating Address Objects

When creating address objects:

Column Description
name Name of the object you wish to create.
type ip, range, or fqdn
value Must contain the IP address, FQDN, or IP range of the object.
description (Optional) A description of the object.
tag (Optional) Name of a pre-existing tag on the device to apply.
device-group Name of the device-group, or shared if creating a shared object.

When creating address groups:

Column Description
name Name of the address group you wish to create.
type static or dynamic
value * See below explanation
description (Optional) A description of the object.
tag (Optional) Name of a pre-existing tag on the device to apply.
device-group Name of the device-group, or shared if creating a shared object.

For a static address group, value must contain a comma-separated list of members to add to the group, enclosed in quotes "", e.g.:

"ip-host1, ip-net1, fqdn-example.com"

For a dynamic address group, value must contain the criteria (tags) to match on. This MUST be enclosed in quotes "", and each criteria (tag) must be surrounded by single-quotes ', e.g.:

"'web-servers' or 'db-servers' and 'linux'"

Creating Service Objects

When creating service objects:

Column Description
name Name of the object you wish to create.
type tcp or udp
value * See below
description (Optional) A description of the object.
tag (Optional) Name of a pre-existing tag on the device to apply.
device-group Name of the device-group, or shared if creating a shared object.
  • value must contain a single port number, range (1023-3000), or comma-separated list of ports, enclosed in quotes "" and separated by a comma, e.g.: "80, 443, 2000".

When creating service groups:

Column Description
name Name of the object you wish to create.
type service
value * See below
description Not available on service groups.
tag (Optional) Name of a pre-existing tag on the device to apply.
device-group Name of the device-group, or shared if creating a shared object.
  • value must contain a comma-separated list of service objects to add to the group, enclosed in quotes "", e.g.: "tcp_8080, udp_666, tcp_range".

Example

Address Object Creation on Panorama

Let's assume we have a CSV file called objects.csv that looks like the following:

alt-text

Running the below code against a Panorama device will create the objects above.

// Connect to Panorama
creds := &panos.AuthMethod{
    Credentials: []string{"admin", "password"},
}

pan, err := panos.NewSession("panorama.company.com", creds)
if err != nil {
    fmt.Println(err)
}

pan.CreateObjectsFromCsv("objects.csv")

If we take a look at Panorama, and view the Vader device-group address objects, we can see all of our objects:

alt-text

And here are our address group objects:

alt-text

We specified a web-server address object in the Vader device-group, as well as a web-server address object in the Luke device-group. This is an example of how you do object overrides. The Luke device-group is a child of the Vader device-group, but needs to have a different IP address assigned to the web-server object. This is visible by the override green/yellow icon next to the web-server object name.

alt-text

Modifying Object Groups from a CSV File

This example shows you how to modify address and service group objects using a CSV file.

The CSV file should be organized with the following columns:

grouptype,action,object-name,group-name,device-group.

Column Description
grouptype address or service
action add or remove
object-name Name of the object to add or remove from group.
group-name Name of the group to modify.
device-group Name of the device-group, or shared if creating a shared object.

Example

Group Modification on a Local Firewall

Let's assume we have a CSV file called modify.csv that looks like the following:

alt-text

Running the below code against a firewall will modify the groups either adding or removing objects that you specified.

// Connect to Panorama
creds := &panos.AuthMethod{
    Credentials: []string{"admin", "password"},
}

pan, err := panos.NewSession("firewall.company.com", creds)
if err != nil {
    fmt.Println(err)
}

pan.ModifyGroupsFromCsv("modify.csv")

Here is what the address group home_lab_group looks like before and after running the above script.

alt-text

alt-text

Here is what the service group tcp_services looks like before and after running the above script.

alt-text

alt-text