- Network
- A
Migration from Juniper SRX firewall to PaloAlto using python
PaloAlto has a special migration tool called Expedition. It can convert configuration files from various firewalls to PaloAlto. But its source code is closed, you will not be able to understand its logic, and it will no longer be supported in 2025.
My Python program is open source. You can read, use, update, add your own functions.
The program converts structured text to another structured text and is under development.
To understand this program, you need to know the basic operations in Python, text, list, and dictionary.
I am writing this text for network engineers who are learning Python, I want to show you the direction of development.
I have added as many comments as possible to the text for better understanding.
Both Juniper Firewall and PaloAlto use address objects (set address) and address group objects (set address-group).
In both firewalls, address objects are used as source IP addresses or destination IP addresses in policies or rules.
Here we see address objects (set address). On the left is Juniper, on the right are the same objects converted to PaloAlto.
The program reads the Juniper configuration text and looks for the words "set security address-book global address",
then the program finds the object name and object prefix.
Here we see address group objects (set address-group). On the left is Juniper, on the right converted to PaloAlto.
In Juniper, the address-set can consist of several objects in several lines, in PaloAlto in one line several objects in square brackets.
And then python converts "security policies global", as it is called in SRX, to "rulebase security rules" in PaloAlto.
For simplicity, I use "global security policies", which means that it is not related to any zone,
it applies from any zone to any zone.
#!/usr/bin/python3
# usage " python srx_to_pa.py fw_name " ---- SRX convert address objects to PaloAlto
import csv, sys
################# main
args = sys.argv # Set the input and output file names from command line argument
input_file = args[1] +'.conf' # read " juniper_srx.conf"
pa_output_file = args[1] +'_pa.conf' # write PA config
# Open the input files ---- convert 'address-book global address'
with open(input_file, "r") as f:
reader = csv.reader(f, delimiter=" ") # read Juniper config into dictionary of lists
for row in reader: # loop for each line, list of separate words from SRX config
if (len(row) == 7):
if ((row[0] == "set") and (row[1] == "security") and (row[2] == "address-book")):
if (("address" in row) and not ("address-set" in row) and not ("dns-name" in row) and not ("description" in row)):
add_name = row[(row.index('address')+1)]
ip_address = row[(row.index('address')+2)]
pa_str = 'set address ' + add_name +' ip-netmask '+ ip_address
print(pa_str)
# Open the input files ---- convert 'address-book global address-set address'
with open(input_file, "r") as f:
add_name , pa_str_list = '' , [] # add_name -- name of address-set object, pa_str_list -- list containing addresses
reader = csv.reader(f, delimiter=" ")
for row in reader: # list of separate words from SRX config
if (len(row) == 8):
if ((row[0] == "set") and (row[1] == "security") and (row[2] == "address-book")):
if (("address" in row) and ("address-set" in row) and not ("description" in row)):
if add_name == row[(row.index('address-set')+1)]:
add_name = row[(row.index('address-set')+1)]
ip_address = row[(row.index('address' )+1)]
pa_str_list.append(ip_address)
else:
if not add_name == '':
pri = 'set address-group ' + add_name + ' static '+ str(pa_str_list)
pri = pri.replace("'",' ')
pri = pri.replace(", ",'')
print(pri)
add_name , pa_str_list = '' , []
add_name = row[(row.index('address-set')+1)]
ip_address = row[(row.index('address' )+1)]
pa_str_list.append(ip_address)
if ((row.count('address-set') == 2) and not ("description" in row)):
if add_name == row[(row.index('address-set')+1)]:
first = row.index('address-set')
sec_name = row[(row.index('address-set',(first+1))+1)]
pa_str_list.append(sec_name)
else:
if not add_name == '':
pri = 'set address-group ' + add_name + ' static '+ str(pa_str_list)
pri = pri.replace("'",' ')
pri = pri.replace(", ",'')
print(pri)
add_name , pa_str_list = '' , []
add_name = row[(row.index('address-set')+1)]
first = row.index('address-set')
sec_name = row[(row.index('address-set',(first+1))+1)]
pa_str_list.append(sec_name)
pri = 'set address-group ' + add_name + ' static '+ str(pa_str_list)
pri = pri.replace("'",' ')
pri = pri.replace(", ",'')
print(pri)
print(' ')
# Open the input files ---- convert 'security policies global policy' to 'rulebase security rules '
with open(input_file, "r") as f:
sec_name , pa_source_list , pa_dest_list , pa_app_list = '' , [] , [] , []
reader = csv.reader(f, delimiter=" ")
for row in reader:
if (len(row) == 9):
if ((row[0] == "set") and (row[1] == "security") and (row[2] == "policies")):
if (("policy" in row) and not ("description" in row)):
if sec_name == row[(row.index('policy')+1)]:
if (row[(row.index('policy')+3)] == "source-address"):
pa_source_list.append(row[(row.index('policy')+4)])
if (row[(row.index('policy')+3)] == "destination-address"):
pa_dest_list.append(row[(row.index('policy')+4)])
if (row[(row.index('policy')+3)] == "application"):
pa_app_list.append(row[(row.index('policy')+4)])
else:
if not sec_name == '':
pri_1 = 'set rulebase security rules ' + sec_name + ' from any'
pri_2 = 'set rulebase security rules ' + sec_name + ' to any'
pri_3 = 'set rulebase security rules ' + sec_name + ' application any'
pri_4 = 'set rulebase security rules ' + sec_name + ' action allow'
pri_5 = 'set rulebase security rules ' + sec_name + ' service application-default'
pri_s = 'set rulebase security rules ' + sec_name + ' source ' + str(pa_source_list)
pri_s = pri_s.replace("'",' ')
pri_s = pri_s.replace(", ",'')
print(pri_1)
print(pri_s)
print(pri_2)
pri_d = 'set rulebase security rules ' + sec_name + ' destination ' + str(pa_dest_list)
pri_d = pri_d.replace("'",' ')
pri_d = pri_d.replace(", ",'')
print(pri_d)
print(pri_3)
print(pri_4)
print(pri_5)
sec_name , pa_source_list , pa_dest_list , pa_app_list = '' , [] , [] , []
sec_name = row[(row.index('policy')+1)]
if (row[(row.index('policy')+3)] == "source-address"):
pa_source_list.append(row[(row.index('policy')+4)])
if (row[(row.index('policy')+3)] == "destination-address"):
pa_dest_list.append(row[(row.index('policy')+4)])
if (row[(row.index('policy')+3)] == "application"):
pa_app_list.append(row[(row.index('policy')+4)])
pri_1 = 'set rulebase security rules ' + sec_name + ' from any' # from any zone
pri_2 = 'set rulebase security rules ' + sec_name + ' to any' # to any zone
pri_3 = 'set rulebase security rules ' + sec_name + ' application any'
pri_4 = 'set rulebase security rules ' + sec_name + ' action allow' # "action allow" the same as "permit" in SRX
pri_5 = 'set rulebase security rules ' + sec_name + ' service application-default'
pri_s = 'set rulebase security rules ' + sec_name + ' source ' + str(pa_source_list)
pri_s = pri_s.replace("'",' ')
pri_s = pri_s.replace(", ",'')
print(pri_1)
print(pri_s)
print(pri_2)
pri_d = 'set rulebase security rules ' + sec_name + ' destination ' + str(pa_dest_list)
pri_d = pri_d.replace("'",' ')
pri_d = pri_d.replace(", ",'')
print(pri_d)
print(pri_3)
print(pri_4)
print(pri_5)
Write comment