Skip to content

Instantly share code, notes, and snippets.

@itsecworks
Created July 25, 2023 22:08
Show Gist options
  • Save itsecworks/9974ff9b4239bf0807039ee2f8bd045d to your computer and use it in GitHub Desktop.
Save itsecworks/9974ff9b4239bf0807039ee2f8bd045d to your computer and use it in GitHub Desktop.
GP Gateway Split tunnel exclude routes updater
import os
import pdb
import requests
import json
# key gen link
# https://192.168.150.200/api/?type=keygen&user=admin&password=yourpassword
# Step 1.: Set your variables and file: Panorama IP, Globalprotect gateway name, GP agent config in GP Gateway, template name and vsys name
# Office 365 EDL from Palo Alto
o365url = "https://saasedl.paloaltonetworks.com/feeds/m365/worldwide/any/optimize/ipv4"
# Cache file location for o365 IP addresses
filepath = 'C://temp//'
# Address object name prefix of o365 ip addresses
name_prefix = "o365-ww-any-opt-ipv4-"
# Palo Alto configurations to modify
panorama = "192.168.150.200"
panoramaipd2 = os.environ.get('panoramaipd2')
vars_example = [{
"name": "mygateway",
"template": "t_newyork",
"device-group": "dg-newyork",
"vsys": "vsys1",
"remote-user-tunnel-configs": {
"entry": [{
"name": "myagentsconfig"
}
]
}
}
]
myvars = [{
"name": "mygateway",
"template": "t_newyork",
"device-group": "dg-newyork",
"vsys": "vsys1",
"remote-user-tunnel-configs": {
"entry": [{
"name": "myagentsconfig"
}
]
}
}, {
"name": "mygateway",
"template": "t_Mobile_Users",
"device-group": "dg-newyork",
"vsys": "vsys1",
"remote-user-tunnel-configs": {
"entry": [{
"name": "myagentsconfig"
}, {
"name": "myagentsconfig2"
}
]
}
}
]
# Step 2.: grab the ip list from palo alto o365 edl link and find the diffs between old and new list
page = requests.get(o365url, verify=False)
print(page.status_code)
elementstoadd = []
elementstodel = []
if not os.path.isfile(filepath + 'o365ips.txt'):
with open(filepath + 'o365ips.txt', 'w') as f:
f.write(page.text)
elementstoadd = page.text.splitlines()
else:
with open(filepath + 'o365ips.txt', 'r+') as f:
oldpage = f.read()
if oldpage == page.text:
print('no change on o365 side...')
exit()
else:
print('we have change on o365 side...')
for element in page.text.splitlines():
if element not in oldpage.splitlines():
elementstoadd.append(element)
for element in oldpage.splitlines():
if element not in page.text.splitlines():
elementstodel.append(element)
print('to delete: ', elementstodel)
print('to add: ', elementstoadd)
with open(filepath + 'o365ips.txt', 'w') as f:
f.write(page.text)
with open(filepath + 'o365ips_old.txt', 'w') as f:
f.write(oldpage)
#Step 3.: Create the address object to use them with name in GP GAteway configuration later
headers = {'X-PAN-KEY': panoramaipd2}
dg_list = []
objectlist = []
object = {}
object['entry'] = {}
for line in page.text.splitlines():
name = name_prefix + line.replace('/', '_')
objectlist.append(name)
for entry in myvars:
api_url = "https://{ipaddress}/restapi/v10.1/Objects/Addresses".format(ipaddress=panorama)
if not entry['device-group'] in dg_list:
params = {'location': 'device-group', 'device-group': entry['device-group']}
object = {}
object['entry'] = {}
for line in elementstoadd:
name = name_prefix + line.replace('/', '_')
params['name'] = name
object['entry']['@name'] = name
object['entry']['ip-netmask'] = line
# Converts input dictionary into string, that follows the json syntax
json_string = json.dumps(object)
r = requests.post(api_url, params=params, verify=False, headers=headers, data=json_string)
print(r.text)
for line in elementstodel:
name = name_prefix + line.replace('/', '_')
params['name'] = name
r = requests.delete(api_url, params=params, verify=False, headers=headers)
print(r.text)
dg_list.append(entry['device-group'])
# Step 4.: Get the current GP gateway configuration with the panorama variable you set
api_url = "https://{ipaddress}/restapi/v10.1/Network/GlobalProtectGateways".format(ipaddress=panorama)
params = {'location': 'template', 'template': entry['template'], 'vsys': entry['vsys']}
r = requests.get(api_url, params=params, verify=False, headers=headers)
print(r.text)
response = json.loads(r.text)
# Step 5.: update the GP Gateway configuration, extended with the office 365 IPs
for subentry in entry['remote-user-tunnel-configs']['entry']:
gp_gateway_config = {}
gp_gateway_config['entry'] = response['result']['entry']
i = 0
j = 0
for config_entry in gp_gateway_config['entry']:
if config_entry['@name'] == entry['name']:
for config_subentry in config_entry['remote-user-tunnel-configs']['entry']:
if config_subentry['@name'] == subentry['name']:
old_list = gp_gateway_config['entry'][i]['remote-user-tunnel-configs']['entry'][j]['split-tunneling']['exclude-access-route']['member']
new_list = []
for element in old_list:
if name_prefix not in element:
new_list.append(element)
new_list.extend(objectlist)
gp_gateway_config['entry'][i]['remote-user-tunnel-configs']['entry'][j]['split-tunneling']['exclude-access-route']['member'] = new_list
j += 1
i += 1
# Step 6.: Upload the new GP configuration via REST API to Panorama
params = {'location': 'template', 'template': entry['template'], 'vsys': entry['vsys'], 'name': entry['name']}
r2 = requests.put(api_url, params=params, verify=False, headers=headers, data=json.dumps(gp_gateway_config))
print(r2.text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment