Skip to main content

You can use NQE to examine the firewall rules in all firewalls in a network. However, you will need to use a different approach depending on what you want to audit in your security rules.

Forward Enterprise collects and parses the ACLs and security rules from all devices: firewalls, routers, switches, and so on. The data is then parsed and normalized. This data is stored in a database in a custom format that allows the Forward application to perform path analysis.

The following NQE query uses the Forward Enterprise aclEntry object to provide consistent output from any vendor Firewall. Note that the scope of device types in the output is limited by using the where statement and filtering to DeviceType.FIREWALL.

This query will work for every ACL/security rule on any Firewall in the network. However, because the query is working on normalized data, each security rule in a firewall may be broken up into multiple aclEntry objects. The results of this query may therefore have multiple lines with the same “Rule Name”. One aclEntry could show traffic permitted for TCP port 80, while another aclEntry could show ICMP traffic being permitted on the same rule from the firewall.

 

foreach device in network.devices
where device.platform.deviceType == DeviceType.FIREWALL
foreach aclEntry in device.aclEntries
select {
"Rule Name": aclEntry.name,
"Source IPs": aclEntry.headerMatches.ipv4Src,
"Destination IPs": aclEntry.headerMatches.ipv4Dst,
"Protocol": max(aclEntry.headerMatches.ipProtocol),
"Destination Ports": aclEntry.headerMatches.tpDst,
"Action": when aclEntry.action is
DENY -> "DENY";
PBR -> "PBR";
PERMIT -> "PERMIT"
}

While this provides an accurate model, it may not be the most intuitive way to list firewall rules.

An alternate approach would be to parse the raw data collected from the devices of a certain hardware model and OS. In this way, the user could display the NQE query output in a table where each line represents a single security rule.

The following NQE query is designed to parse the security rules from a Palo Alto firewall by looking for a defined pattern in the config hierarchy and assigning the data for each rule entry to a series of variables. The select statement creates a table of entries that are based on each unique block of data that matches the pattern.

This output may be more readable than iterating through the normalized data, but the script will have to be customized for every type of firewall in the network. Even devices of the same type could deviate from the pattern (For example, not all Palo Alto firewalls will have the “rule-type” setting). The output results of the NQE query should be compared against a sample device of each type of config to ensure that no data pattern is missing.

pattern =
```
config
devices
localhost.localdomain
vsys
{vsysName: string}
rulebase
security
rules
{ruleName:string}
rule-type {ruletype:string}
description {description: string}
source {srcIps: string}
from {fromZone:string}
to {toZone:string}
destination {dstIps:string}
application {app:string}
service {service:string}
action {action:string}
```;


foreach device in network.devices
where device.platform.os == OS.PAN_OS
foreach match in blockMatches(device.files.config, pattern)

select {
device: device.name,
os: device.platform.os,
vsys: match.data.vsysName,
"Rule Name": match.data.ruleName,
"Source IPs": match.data.srcIps,
"Dest IPs": match.data.dstIps,
"from Zone": match.data.fromZone,
"to Zone": match.data.toZone,
"App": match.data.app,
"Service": match.data.service,
"Action": match.data.action
}

 

 

 

 

This is a very helpful capability and good example of the power of NQE.  Is it possible to share examples for other firewall platforms such as Fortinet FortiOS and Cisco ASA and/or Firepower?


The key to auditing configuration files is understanding how to use the blockMatches function.

The blockMatches function takes two arguments, a config file and a pattern to find in the config file.

The function matches the pattern based on indentation.

For example,

Let’s take a hypothetical fireball brand X, and the configuration file contains firewall rules in the following format:

config
firewall
system-config
device-name my-firewall
security-rules
rule1
from 10.0.0.0/8
to 172.16.0.0/16
protocol tcp
port 80
action permit
rule2
description "block port 53"
from 10.0.0.0/8
to 192.168.0.0/24
protocol udp
port 53
action deny

If we want to write a config pattern to capture the firewall rules in NQE, we need to make sure match the indentation of the hierarchy in the config file with our pattern. Note also that the device config file may contain brackets { } for each section of the firewall, but you do NOT need brackets in the pattern.

pattern =
```
config
firewall
security-rules
{ruleName:string}
from {scrIps: string}
to {dstIps: string}
protocol {protocol: string}
port {port: number}
action {action: string}
```;

Note that our pattern does NOT need the system-config section or the description line because there is nothing within those sections we need to parse. However, we must include firewall and security-rules, because they contain the data we need. 

If we DID put description {desc: string} in our pattern match, rule1 would not be captured by the pattern, since it doesn’t contain a description.

We use {ruleName: string} in place of the rule name, since the name changes, and we want to capture each match. The blockMatches function will capture both rule1 and rule2, because each BLOCK matches the pattern.

This logic can be applied to any vendor to capture firewall rules, or any other data in the configuration.

 


Reply