Last active
November 1, 2022 02:34
-
-
Save yujiterada/419b40231ea8cdd293d96fd94507cd5a to your computer and use it in GitHub Desktop.
Create a guest subnet for all Meraki MXs in an organization. This guest subnet will have a group policy applied which will deny all private IP addresses.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
from datetime import date | |
import meraki | |
def is_vlan_used(vlans, vlan_id): | |
for vlan in vlans: | |
if vlan['id'] == vlan_id: | |
return True | |
return False | |
def is_subnet_used(vlans, subnet): | |
for vlan in vlans: | |
if vlan['subnet'] == subnet: | |
return True | |
return False | |
def is_group_policy_name_used(group_policies, name): | |
for gp in group_policies: | |
if gp['name'] == name: | |
return True | |
return False | |
MERAKI_API_KEY = os.environ.get('MERAKI_API_KEY', None) | |
MERAKI_ORG_ID = os.environ.get('MERAKI_ORGANIZATION_ID', None) | |
GUEST_VLAN_ID = '999' | |
GUEST_VLAN_SUBNET = '192.168.99.0/24' | |
GUEST_VLAN_DEFAULT_GW = '192.168.99.254' | |
GROUP_POLCIY_NAME = 'Guest_{}'.format(date.today().strftime("%Y%m%d")) | |
FIREWALL_AND_TRAFFIC_SHAPING = { | |
"settings": "custom", | |
"trafficShapingRules": [], | |
"l3FirewallRules": [ | |
{ | |
"comment": "Deny class A private IP", | |
"policy": "deny", | |
"protocol": "any", | |
"destPort": "any", | |
"destCidr": "10.0.0.0/8" | |
}, | |
{ | |
"comment": "Deny class B private IP", | |
"policy": "deny", | |
"protocol": "any", | |
"destPort": "any", | |
"destCidr": "172.16.0.0/12" | |
}, | |
{ | |
"comment": "Deny class C private IP", | |
"policy": "deny", | |
"protocol": "any", | |
"destPort": "any", | |
"destCidr": "192.168.0.0/16" | |
} | |
], | |
"l7FirewallRules": [] | |
} | |
if MERAKI_API_KEY: | |
# Initialize Meraki API Client | |
dashboard = meraki.DashboardAPI(api_key=MERAKI_API_KEY, suppress_logging=True, output_log=False) | |
# Obtain all networks in organization | |
networks = dashboard.organizations.getOrganizationNetworks(organizationId=MERAKI_ORG_ID) | |
# Iterate through the networks and check if MX exists in network | |
for network in networks: | |
network_id = network['id'] | |
print('{} ({})'.format(network['name'], network['id'])) | |
if 'appliance' in network['productTypes']: | |
vlans = None | |
mx_settings = dashboard.appliance.getNetworkApplianceSettings(network_id) | |
# If MX is in NAT mode, then create guest VLAN | |
if mx_settings['deploymentMode'] == 'routed': | |
# Check group policy for guest VLAN | |
group_policies = dashboard.networks.getNetworkGroupPolicies(networkId=network_id) | |
if not is_group_policy_name_used(group_policies, GROUP_POLCIY_NAME): | |
group_policy = dashboard.networks.createNetworkGroupPolicy(networkId=network_id, name=GROUP_POLCIY_NAME, firewallAndTrafficShaping=FIREWALL_AND_TRAFFIC_SHAPING) | |
group_policy_id = group_policy['groupPolicyId'] | |
# Check if VLANs are enabled | |
vlans_are_enabled = (dashboard.appliance.getNetworkApplianceVlansSettings(network_id))['vlansEnabled'] | |
# If VLANs are disabled, then enable VLANs | |
if not vlans_are_enabled: | |
# Enable VLANs | |
dashboard.appliance.updateNetworkApplianceVlansSettings(networkId=network_id, vlansEnabled=True) | |
# Obtain VLANs (should be only VLAN ID 1) | |
vlans = dashboard.appliance.getNetworkApplianceVlans(network_id) | |
# Obtain list of ports to configure ports to not drop untagged traffic | |
mx_ports = dashboard.appliance.getNetworkAppliancePorts(networkId=network_id) | |
for port in mx_ports: | |
dashboard.appliance.updateNetworkAppliancePort(networkId=network_id, portId=port['number'], dropUntaggedTraffic=False, vlan=vlans[0]['id']) | |
# Obtain VLANs if not already | |
if not vlans: | |
vlans = dashboard.appliance.getNetworkApplianceVlans(network_id) | |
# Create guest VLAN if VLAN and subnet is used | |
if not is_vlan_used(vlans, GUEST_VLAN_ID) and not is_subnet_used(vlans, GUEST_VLAN_SUBNET): | |
try: | |
dashboard.appliance.createNetworkApplianceVlan(networkId=network_id, id=GUEST_VLAN_ID, name='Guest', subnet=GUEST_VLAN_SUBNET, applianceIp=GUEST_VLAN_DEFAULT_GW, groupPolicyId=group_policy_id) | |
print(' Configured guest VLAN') | |
except Exception as e: | |
print(' {}'.format(e.message['errors'][0])) | |
else: | |
print(' VLAN or subnet is used') | |
# sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment