Network security is an essential aspect of any organization, and with the increasing threat of cyber-attacks, it is imperative to ensure that the firewall security features are enabled and functioning correctly. However, manually checking the security status of firewalls can be a time-consuming task, especially when dealing with multiple firewalls across multiple organizations. This is a challenge that most Managed Service Providers like ourselves face. The purpose of this blog post is to start building a security baseline, which can help standardize and audit security configurations on customers based on the MX Security Best Practice Design document published by Cisco Meraki. In this post, we will go over the steps to accomplish this using Python.
Overview of the Script
The script uses the Meraki REST API to check the security settings of MX firewalls in a list of organizations. The script reads the API keys and org IDs from a file, and then retrieves the list of networks for the selected organization. It filters the list to find the MX firewalls and then retrieves the license edition, anti-malware, intrusion prevention and IP spoofing protection settings for each firewall. The results are displayed in a table format, showing the organization name, network name, license edition, anti-malware status, intrusion prevention status and spoof protection status.
Prerequisites
- A Meraki Dashboard account with API access enabled
- Python 3.x installed
- The 'requests' and 'prettytable' libraries installed
- A file containing the API keys and organization IDs of the Meraki organizations to be checked
The Code
The code consists of the following steps:
- Import the necessary libraries, including the 'requests' library for making API calls and the 'prettytable' library for generating a table to display the results.
- Read the file containing the API keys and organization IDs of the Meraki organizations to be checked.
- Use the Meraki APIs to retrieve the list of networks in each organization.
- Filter the networks to find Meraki MX firewalls.
- For each firewall, make API calls to obtain the license edition, anti-malware, intrusion prevention, and spoof protection settings.
- Format the results as a table, with the organization name, network name, license edition, anti-malware status, intrusion prevention status, and spoof protection status as columns.
- Print the table.
import requests
from prettytable import PrettyTable
table= PrettyTable()
# API endpoint for organizations
org_url = 'https://api.meraki.com/api/v1/organizations'
# API endpoint for firewalls
fw_url = 'https://api.meraki.com/api/v1/networks/{}/appliance/'
# Read the file containing the API keys and org IDs
with open("C:/MerakiAutomation/api_keys_org_ids.txt", "r") as f:
lines = f.readlines()
print(lines)
# Create a table header
table.field_names = ["Organization", "Network", "License Edition", "Anti-Malware", "Intrusion Prevention", "Spoof Protection"]
table.align["Organization"] = "l"
table.align["Network"] = "l"
table.align["License Edition"] = "l"
table.align["Anti-Malware"] = "l"
table.align["Intrusion Prevention"] = "l"
table.align["Spoof Protection"] = "l"
# Loop through each line in the file
for line in lines:
api_key, org_id = line.strip().split(",")
# Get list of networks for the selected organization
networks_url = f"https://api.meraki.com/api/v1/organizations/{org_id}/networks"
response = requests.get(networks_url, headers={'X-Cisco-Meraki-API-Key': api_key})
networks = response.json()
# Filter the networks to find MX firewalls
mx_firewalls = [network for network in networks if network['productTypes'][0] == 'appliance']
# Loop through the firewall list
for firewall in mx_firewalls:
# Get the organization name
org_response = requests.get(f"{org_url}/{org_id}", headers={'X-Cisco-Meraki-API-Key': api_key})
org = org_response.json()
org_name = org['name']
# Network Name
network_name = firewall['name']
# Get the current license version for the MX
licenses_response = requests.get(f"{org_url}/{org_id}/licensing/coterm/licenses/", headers={'X-Cisco-Meraki-API-Key': api_key}).json()
license_edition = "Enterprise"
for item in licenses_response:
counts = item.get('counts')
for count in counts:
if count.get('model').startswith('MX'):
editions = item.get('editions')
for edition in editions:
if 'Advanced Security' in edition.get('edition'):
license_edition = 'Advanced Security'
break
# Get anti-malware settings
fw_url_antimalware = (fw_url + "security//malware")
firewall_settings = requests.get(fw_url_antimalware.format(firewall['id']), headers={'X-Cisco-Meraki-API-Key': api_key}).json()
anti_malware_enabled = firewall_settings['mode']
# Get intrusion prevention settings
fw_url_intrusion = (fw_url + "security//intrusion")
firewall_settings = requests.get(fw_url_intrusion.format(firewall['id']), headers={'X-Cisco-Meraki-API-Key': api_key}).json()
if 'mode' in firewall_settings:
intrusion_prevention_enabled = firewall_settings['mode']
else:
intrusion_prevention_enabled = "Not Supported"
# Get Ip Spoof Protection settings
fw_url_spoof = (fw_url + "firewall//settings")
firewall_settings = requests.get(fw_url_spoof.format(firewall['id']), headers={'X-Cisco-Meraki-API-Key': api_key}).json()
spoof_protection_enabled = firewall_settings['spoofingProtection']['ipSourceGuard']['mode']
# Add rows to the table
table.add_row([org_name, network_name, license_edition, anti_malware_enabled, intrusion_prevention_enabled, spoof_protection_enabled ])
# Print the results
print (table)