Closed bradrel closed 2 years ago
Hey @bradrel it's been a while since I've worked on this; however, the script was written to take any items provided via the API as source/destination networks and put them into a list (example: item1, item2, item3, etc.
). This worked in my initial testing, as can be seen in this example.
This could be due to differences in the API's returned data after some FMC upgrades. The relevant code for this is here if you want to mess with it and see if you can get it to work the way you'd like. https://github.com/rnwolfe/fmc-tools/blob/e0ff19cd21e458bb4dbaec98b470d62653947d8e/export-acp-to-csv.py#L76-L92
You could probably put a print(rule['sourceNetworks'])
what the data is getting is and then tweak as needed.
Hopefully, this points you in the right direction as I haven't messed with this in a good while, and don't have a readily available test environment for me to work against.
Let me know if you need further help.
I created a GitHub just to show the changes I made to this script.
I examined the JSON output from my FMC API request and these are the elements that I've seen so far:
sourceZones
objects
id
name
type #eg SecurityZone
destinationZones
objects
id
name
type #eg SecurityZone
sourceNetworks
objects
id
name
overridable #true;false
type #network;Host;NetworkGroup
literals
type #host
value
destinationNetworks
objects
id
name
overridable #true;false
type #network;NetworkGroup;FQDN;Range
literals
type #host
value #eg 10.10.10.10
sourcePorts
objects
id
name #eg MSRDP, rdp, SCCM-Remote-Assistance
overridable #true;false
[protocol] #(May not be present) eg TCP
type #ProtocolPortObject;
literals
[port] #(May not be present) eg 8880
protocol ###Represented as a number corresponding to list found here https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
type #eg PortLiteral
destinationPorts
objects
id
name
overridable
[protocol]
type
literals
port
protocol
type
I had to do a bit of change to get mine working correctly. Excuse any weird coding as I have not coded since highschool 20 years ago and this is the first I've done since then:
#Add these as needed from https://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
portTypes = {'1': 'ICMP','6': 'TCP','17': 'UDP','50': 'ESP'}
# Source Networks
line['sourceNetworks'] = []
if 'sourceNetworks' in rule:
for srcNets in rule['sourceNetworks']:
if 'objects' in srcNets:
for item in rule['sourceNetworks']['objects']:
# Put each object in a list, will join to str when printing to CSV
line['sourceNetworks'].append(item['name'])
if 'literals' in srcNets:
for item in rule['sourceNetworks']['literals']:
# Put each object in a list, will join to str when printing to CSV
line['sourceNetworks'].append(item['value'])
else:
line['sourceNetworks'] = ['any']
# Destination Networks
line['destNetworks'] = []
if 'destinationNetworks' in rule:
for dstNets in rule['destinationNetworks']:
if 'objects' in dstNets:
for item in rule['destinationNetworks']['objects']:
# Put each object in a list, will join to str when printing to CSV
line['destNetworks'].append(item['name'])
if 'literals' in dstNets:
for item in rule['destinationNetworks']['literals']:
# Put each object in a list, will join to str when printing to CSV
line['destNetworks'].append(item['value'])
else:
line['destNetworks'] = ['any']
# Source Ports
line['sourcePorts'] = []
if 'sourcePorts' in rule:
for srcPorts in rule['sourcePorts']:
if 'objects' in srcPorts:
for item in rule['sourcePorts']['objects']:
try:
# line['sourcePorts'].append(item['protocol']+"_"+item['name'])
line['sourcePorts'].append(item['name'])
except KeyError:
line['sourcePorts'].append(item['name'])
for srcPorts in rule['sourcePorts']:
if 'literals' in srcPorts:
for item in rule['sourcePorts']['literals']:
try:
line['sourcePorts'].append(portTypes[item['protocol']]+"_"+item['port'])
except KeyError:
line['sourcePorts'].append(portTypes[item['protocol']])
else:
line['sourcePorts'] = ['any']
# Destination Ports
line['destPorts'] = []
if 'destinationPorts' in rule:
for dstPorts in rule['destinationPorts']:
if 'objects' in dstPorts:
for item in rule['destinationPorts']['objects']:
try:
# line['destPorts'].append(item['protocol']+"_"+item['name'])
line['destPorts'].append(item['name'])
except KeyError:
line['destPorts'].append(item['name'])
for dstPorts in rule['destinationPorts']:
if 'literals' in dstPorts:
for item in rule['destinationPorts']['literals']:
try:
line['destPorts'].append(portTypes[item['protocol']]+"_"+item['port'])
except KeyError:
line['destPorts'].append(portTypes[item['protocol']])
else:
line['destPorts'] = ['any']
These changes were required because sometimes you have objects, sometimes you have literals, sometimes you have both.
Sometimes source/dest port objects don't have protocol, sometimes the literals don't have port number. I like the readability of the final output like this.
@Westy-87 Thanks for the code extension provided here.
You are right, there can be multiple things provided from/to the API for objects, literals, etc.
It wasn't something I was concerned with at the time I used this, but it will be nice to others to reference this if needed!
Also, welcome to GitHub, @Westy-87!
@Westy-87 THANK YOU! This worked great.
The only think I changed was to add some more portTypes:
portTypes = {'1': 'ICMP','2': 'IGMP','6': 'TCP','17': 'UDP','47': 'GRE','50': 'ESP'}
Hello! We are trying to use the export-acp-to-csv.py script but seem to have an issue with the entries that have multiple Source or Destination Network addresses. When these entries are export, they are listed in the csv file as 'any'. In the FMC interface, this is done by adding multiple IP addresses in the "Networks" section. Is there any way to get these entries exported properly with this script? Thanks in advance.