Created
July 25, 2023 22:08
-
-
Save itsecworks/9974ff9b4239bf0807039ee2f8bd045d to your computer and use it in GitHub Desktop.
GP Gateway Split tunnel exclude routes updater
This file contains 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 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