Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Palo Alto HTTP API model (panos_api) #2739

Merged
merged 1 commit into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

- model for PanOS & Panorama via HTTP API (@pv2b, @sts)
- model for MikroTik SwOS devicse (@sm-nessus)
- model for TrueNAS devices (@neilschelly)
- model for Acme Packet devices (@ha36d)
Expand Down
28 changes: 28 additions & 0 deletions docs/Model-Notes/PanOS_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# PanOS API

Backup Palo Alto XML configuration via the HTTP API. Works for PanOS and Panorama.

Logs in using username and password and fetches an API key.

## Requirements

- Create a user with a `Superuser (read-only)` admin role in Panorama or PanOS
- Make sure the `nokogiri` gem is installed with your oxidized host

## Configuration

Make sure the following is configured in the oxidized config:

```yaml
# allow ssl host name verification
resolve_dns: false
input:
default: ssh, http
http:
secure: true
ssl_verify: true

# model specific configuration
#model:
# panos_api:
```
3 changes: 2 additions & 1 deletion docs/Supported-OS-Types.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@
* [OpenWRT](/lib/oxidized/model/openwrt.rb)
* [OPNsense](/lib/oxidized/model/opnsense.rb)
* Palo Alto
* [PANOS](/lib/oxidized/model/panos.rb)
* [PanOS API](/lib/oxidized/model/panos_api.rb)
* [PanOS](/lib/oxidized/model/panos.rb)
* [PLANET SG/SGS Switches](/lib/oxidized/model/planet.rb)
* [pfSense](/lib/oxidized/model/pfsense.rb)
* Pure Storage
Expand Down
71 changes: 71 additions & 0 deletions lib/oxidized/model/panos_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# PanOS API-based model for Oxidized
#
# The API-based model produced an XML configuration file that can actually be
# restored as a configuration backup. Make sure to use the "http" input for
# this module.

begin
# Nokogiri is required because the PanOS API, as well as the
# configuration file format uses XML. It is required to parse API
# responses, as well as to pretty-print the configuration XML file
# when saving it.
require 'nokogiri'
rescue LoadError
# Oxidized itself depends on mechanize, which in turn depends on
# nokogiri, so this should never happen.
raise Oxidized::OxidizedError, 'nokogiri not found: sudo gem install nokogiri'
end

class PanOS_API < Oxidized::Model # rubocop:disable Naming/ClassAndModuleCamelCase
# Callback function for getting the configuration file.
cfg_cb = lambda do
url_param = URI.encode_www_form(
user: @node.auth[:username],
password: @node.auth[:password],
type: 'keygen'
)

kg_r = get_http "/api?#{url_param}"

# Parse the XML API response for the keygen request.
kg_x = Nokogiri::XML(kg_r)

# Check if keygen was successful. If not we'll throw an error.
status = kg_x.xpath('//response/@status').first
if status.to_s != 'success'
msg = kg_x.xpath('//response/result/msg').text
raise Oxidized::OxidizedError, "Could not generate PanOS API key: #{msg}"
end

# If we reach here, keygen was successful, so get the API key
# out of the keygen XML response.
apikey = kg_x.xpath('//response/result/key').text.to_s

# Now that we have the API key, we can request a configuration
# export.
url_param = URI.encode_www_form(
key: apikey,
category: 'configuration',
type: 'export'
)

cfg = get_http "/api?#{url_param}"

# The configuration export is in XML format. Unfortunately,
# it's just one long line of XML that's not especially human
# readable or diffable.
#
# Thus, we will load the XML document and then emit it again
# with indentation set up, so that it's still a valid
# configuration, and also possible to read.
Nokogiri::XML(cfg).to_xml(indent: 2)
end

# Define the command based on the callback above.
cmd cfg_cb

cfg :http do
# Palo Alto's API always requires HTTPS as far as I know.
@secure = true
end
end