Wednesday, February 15, 2023

Meraki Security Baseline

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:

  1. Import the necessary libraries, including the 'requests' library for making API calls and the 'prettytable' library for generating a table to display the results.
  2. Read the file containing the API keys and organization IDs of the Meraki organizations to be checked.
  3. Use the Meraki APIs to retrieve the list of networks in each organization.
  4. Filter the networks to find Meraki MX firewalls.
  5. For each firewall, make API calls to obtain the license edition, anti-malware, intrusion prevention, and spoof protection settings.
  6. 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.
  7. Print the table.
The end result will look like this:

Fig.1 Table with list of controls

Here comes the full script, which is also published on GitHub: Meraki-Security-Baseline. Comments under each section should give you an idea on what each part of the code is doing. 
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)

Future work


Please note that this script is the first version of our Meraki baseline security checks, which will be expanded in the future. I plan to include additional controls from Cisco Meraki's Best Practice Design for MX Security. 

Conclusion


In conclusion, the script provides a quick and easy way to check the security configuration and license of all the MX firewalls in different organizations, saving time and reducing the chances of security configuration issues going unnoticed. As a best practice, it is recommended to run this script on a regular basis to ensure that the firewall security configurations remain consistent and secure.

References