def parse(src_format, src_config, routing_info=""): logger.log( 2, "DirectFire.Converter.parse: loading parser module for " + src_format) if src_format == "ciscoasa": ## Cisco ASA from DirectFire.Converter.parsers.ciscoasa import parse elif src_format == "ciscoasa_pre83": ## Cisco ASA pre 8.3 from DirectFire.Converter.parsers.ciscoasa_pre83 import parse elif src_format == "fortigate": ## Fortinet FortiGate from DirectFire.Converter.parsers.fortigate import parse elif src_format == "junipersrx": ## Juniper SRX (JunOS) from DirectFire.Converter.parsers.junipersrx import parse elif src_format == "watchguard": ## WatchGuard from DirectFire.Converter.parsers.watchguard import parse else: logger.log( 2, "DirectFire.Converter.parse: failed to load parser module for " + src_format, ) print( f"{Fore.RED}Error: failed to load parser module.{Style.RESET_ALL}") exit() logger.log( 2, "DirectFire.Converter.parse: loaded parser module for " + src_format) logger.log( 2, "DirectFire.Converter.parse: starting parse of source configuration") parsed_data = parse(logger, src_config, routing_info) logger.log( 2, "DirectFire.Converter.parse: completed parse of source configuration") return parsed_data
def generate(dst_format, parsed_data): logger.log( 2, "DirectFire.Converter.generate: loading generator module for " + dst_format) if dst_format == "ciscoasa": ## Cisco ASA post 8.3 from DirectFire.Converter.generators.ciscoasa import generate elif dst_format == "data": ## JSON Data from DirectFire.Converter.generators.data import generate elif dst_format == "fortigate": ## Fortinet FortiGate from DirectFire.Converter.generators.fortigate import generate else: logger.log( 2, "DirectFire.Converter.parse: failed to load generator module for " + dst_format, ) print( f"{Fore.RED}Error: failed to load generator module.{Style.RESET_ALL}" ) exit() logger.log( 2, "DirectFire.Converter.generate: loaded generator module for " + dst_format) logger.log( 2, "DirectFire.Converter.generate: starting generation of destination output" ) dst_config = generate(logger, parsed_data) logger.log( 2, "DirectFire.Converter.generate: completed generation of destination output" ) return dst_config
def generate(logger, parsed_data): logger.log(2, __name__ + ": generator module started") # Initialise variables dst_config = [] # Generator specific variables """ Generator specific variables """ # Generate data logger.log(2, __name__ + ": generate data") formatted_data = json.dumps(parsed_data, indent=2) dst_config.append(formatted_data) # Return generated data logger.log(2, __name__ + ": generator module finished") return dst_config
def parse(logger, src_config, routing_info=""): logger.log(2, __name__ + ": parser module started") # Initialise data """ May need to process XML to ET, JSON etc here """ # Initialise variables data = {} data["system"] = {} data["interfaces"] = {} data["zones"] = {} data["routes"] = [] data["routes6"] = [] data["network_objects"] = {} data["network6_objects"] = {} data["network_groups"] = {} data["network6_groups"] = {} data["service_objects"] = {} data["service_groups"] = {} data["policies"] = [] data["nat"] = [] # Parser specific variables """ Parser specific variables """ # Parse system logger.log(2, __name__ + ": parse system") re_match = re.search('(?:set hostname "(.*?)"\n)', src_config) data["system"]["hostname"] = re_match.group(1) # Parse interfaces logger.log(2, __name__ + ": parse interfaces - not yet supported") """ Parse interfaces """ # Parse zones logger.log(2, __name__ + ": parse zones - not yet supported") """ Parse zones """ # Parse static routes logger.log(2, __name__ + ": parse static routes") re_match = re.search("\nconfig router static\n(?:.*?)\nend", src_config, re.DOTALL) routes_block = re_match.group(0).strip() for route_match in re.finditer(" edit [0-9]{1,}\n(?:.*?)\n next", routes_block, re.DOTALL): route_config = route_match.group(0) if ("set virtual-wan-link enable" not in route_config): ### need to add vwl support route = {} re_match = re.search( "set dst (" + common.common_regex.ipv4_address + ") (" + common.common_regex.ipv4_mask + ")\n", route_config, ) route["network"] = re_match.group(1) route["mask"] = re_match.group(2) re_match = re.search( "set gateway ([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3})\n", route_config, ) route["gateway"] = re_match.group(1) re_match = re.search('set device "?(.*?)"?\n', route_config) route["interface"] = re_match.group(1) re_match = re.search("set distance ([0-9]{1,})\n", route_config) route["distance"] = re_match.group(1) route["source"] = [] route["type"] = "static" data["routes"].append(route) # Parse IPv4 network objects logger.log(2, __name__ + ": parse IPv4 network objects") re_match = re.search("\nconfig firewall address\n(?:.*?)\nend", src_config, re.DOTALL) network_objects_block = re_match.group(0).strip() for network_object_match in re.finditer( ' edit "?(.*?)"?\n(?:.*?)?\n? next', network_objects_block, re.DOTALL): network_object = network_object_match.group(0) network_object_name = network_object_match.group(1) data["network_objects"][network_object_name] = {} re_match = re.search("set type (.*?)\n", network_object) if re_match: network_object_type = re_match.group(1) if network_object_type == "fqdn": data["network_objects"][network_object_name]["type"] = "fqdn" re_match = re.search( 'set fqdn "?(' + common.common_regex.fqdn + ')"?\n', network_object) data["network_objects"][network_object_name][ "fqdn"] = re_match.group(1) elif network_object_type == "geography": data["network_objects"][network_object_name][ "type"] = "geography" re_match = re.search( "set country (" + common.common_regex.country_code + ")\n", network_object, ) data["network_objects"][network_object_name][ "country_code"] = re_match.group(1) elif network_object_type == "ipmask": re_match = re.search( "set subnet (" + common.common_regex.ipv4_address + ") (" + common.common_regex.ipv4_mask + ")\n", network_object, ) if re_match: # if a subnet is found network_object_network = re_match.group(1) network_object_mask = re_match.group(2) if (network_object_mask == "255.255.255.255" ): # if mask is 255.255.255.255 then its a host data["network_objects"][network_object_name][ "type"] = "host" data["network_objects"][network_object_name][ "network"] = network_object_network data["network_objects"][network_object_name][ "mask"] = network_object_mask else: # else its a network data["network_objects"][network_object_name][ "type"] = "network" data["network_objects"][network_object_name][ "network"] = network_object_network data["network_objects"][network_object_name][ "mask"] = network_object_mask else: # default is 0.0.0.0 0.0.0.0 network_object_network = re_match.group(1) network_object_mask = re_match.group(2) data["network_objects"][network_object_name][ "type"] = "network" data["network_objects"][network_object_name][ "network"] = network_object_network data["network_objects"][network_object_name][ "mask"] = network_object_mask elif network_object_type == "iprange": data["network_objects"][network_object_name]["type"] = "range" re_match = re.search( "set start-ip (" + common.common_regex.ipv4_address + ")\n", network_object, ) data["network_objects"][network_object_name][ "address_first"] = re_match.group(1) re_match = re.search( "set end-ip (" + common.common_regex.ipv4_address + ")\n", network_object, ) data["network_objects"][network_object_name][ "address_last"] = re_match.group(1) elif network_object_type == "mac": data["network_objects"][network_object_name]["type"] = "mac" re_match = re.search( "set start-mac (" + common.common_regex.mac_address + ")\n", network_object, ) data["network_objects"][network_object_name][ "mac_first"] = re_match.group(1) re_match = re.search( "set end-mac (" + common.common_regex.mac_address + ")\n", network_object, ) data["network_objects"][network_object_name][ "mac_last"] = re_match.group(1) ### add support for other types - dynamic, interface-subnet, wildcard else: # default type is ipmask re_match = re.search( "set subnet (" + common.common_regex.ipv4_address + ") (" + common.common_regex.ipv4_mask + ")\n", network_object, ) if re_match: # if a subnet is found network_object_network = re_match.group(1) network_object_mask = re_match.group(2) if (network_object_network != "0.0.0.0" and network_object_mask == "255.255.255.255" ): # if mask is 255.255.255.255 then its a host data["network_objects"][network_object_name][ "type"] = "host" data["network_objects"][network_object_name][ "network"] = network_object_network data["network_objects"][network_object_name][ "mask"] = network_object_mask else: # else its a network data["network_objects"][network_object_name][ "type"] = "network" data["network_objects"][network_object_name][ "network"] = network_object_network data["network_objects"][network_object_name][ "mask"] = network_object_mask else: # default is 0.0.0.0 0.0.0.0 data["network_objects"][network_object_name][ "type"] = "network" data["network_objects"][network_object_name][ "network"] = "0.0.0.0" data["network_objects"][network_object_name][ "mask"] = "0.0.0.0" # Parse IPv6 network objects logger.log(2, __name__ + ": parse IPv6 network objects") re_match = re.search("\nconfig firewall address6\n(?:.*?)\nend", src_config, re.DOTALL) network6_objects_block = re_match.group(0).strip() for network6_object_match in re.finditer( ' edit "?(.*?)"?\n(?:.*?)?\n? next', network6_objects_block, re.DOTALL): network6_object = network6_object_match.group(0) network6_object_name = network6_object_match.group(1) data["network6_objects"][network6_object_name] = {} re_match = re.search("set type (.*?)\n", network6_object) if re_match: network6_object_type = re_match.group(1) if network6_object_type == "fqdn": data["network6_objects"][network6_object_name]["type"] = "fqdn" re_match = re.search( 'set fqdn "?(' + common.common_regex.fqdn + ')"?\n', network6_object) data["network6_objects"][network6_object_name][ "fqdn"] = re_match.group(1) elif network6_object_type == "ipprefix": re_match = re.search( "set ip6 (" + common.common_regex.ipv6_address + ")(" + common.common_regex.ipv6_mask + ")\n", network6_object, ) if re_match: # if a subnet is found network6_object_network = re_match.group(1) network6_object_mask = re_match.group(2) data["network6_objects"][network6_object_name][ "type"] = "network" data["network6_objects"][network6_object_name][ "network"] = network6_object_network data["network6_objects"][network6_object_name][ "mask"] = network6_object_mask else: # ::/0 is default data["network6_objects"][network6_object_name][ "type"] = "network" data["network6_objects"][network6_object_name][ "network"] = "::" data["network6_objects"][network6_object_name][ "mask"] = "/0" elif network6_object_type == "iprange": data["network6_objects"][network6_object_name][ "type"] = "range" re_match = re.search( "set start-ip (" + common.common_regex.ipv6_address + ")\n", network6_object, ) data["network6_objects"][network6_object_name][ "address_first"] = re_match.group(1) re_match = re.search( "set end-ip (" + common.common_regex.ipv6_address + ")\n", network6_object, ) data["network6_objects"][network6_object_name][ "address_last"] = re_match.group(1) ### add support for other types - dynamic, template else: # default type is ipprefix re_match = re.search( "set ip6 (" + common.common_regex.ipv6_address + ")(" + common.common_regex.ipv6_mask + ")\n", network6_object, ) if re_match: # if a subnet is found network6_object_network = re_match.group(1) network6_object_mask = re_match.group(2) data["network6_objects"][network6_object_name][ "type"] = "network" data["network6_objects"][network6_object_name][ "network"] = network6_object_network data["network6_objects"][network6_object_name][ "mask"] = network6_object_mask else: # ::/0 is default data["network6_objects"][network6_object_name][ "type"] = "network" data["network6_objects"][network6_object_name][ "network"] = "::" data["network6_objects"][network6_object_name]["mask"] = "/0" # Parse IPv4 network groups logger.log(2, __name__ + ": parse IPv4 network groups") re_match = re.search("\nconfig firewall addrgrp\n(?:.*?)\nend", src_config, re.DOTALL) network_groups_block = re_match.group(0).strip() for network_group_match in re.finditer( ' edit "?(.*?)"?\n(?:.*?)?\n? next', network_groups_block, re.DOTALL): network_group = network_group_match.group(0) network_group_name = network_group_match.group(1) data["network_groups"][network_group_name] = {} data["network_groups"][network_group_name]["type"] = "group" re_match = re.search('set member(?: "?(?:.*?)"?){1,}\n', network_group) if re_match: network_group_members = (re_match.group(0).replace( "set member ", "").replace('"', "").rstrip().split(" ")) data["network_groups"][network_group_name][ "members"] = network_group_members # Parse IPv6 network groups logger.log(2, __name__ + ": parse IPv6 network groups") re_match = re.search("\nconfig firewall addrgrp6\n(?:.*?)(?:\n)?end", src_config, re.DOTALL) network6_groups_block = re_match.group(0).strip() for network6_group_match in re.finditer( ' edit "?(.*?)"?\n(?:.*?)?\n? next', network6_groups_block, re.DOTALL): network6_group = network6_group_match.group(0) network6_group_name = network6_group_match.group(1) data["network6_groups"][network6_group_name] = {} data["network6_groups"][network6_group_name]["type"] = "group" re_match = re.search('set member(?: "?(?:.*?)"?){1,}\n', network6_group) if re_match: network6_group_members = (re_match.group(0).replace( "set member ", "").replace('"', "").rstrip().split(" ")) data["network6_groups"][network6_group_name][ "members"] = network6_group_members # Parse service objects logger.log(2, __name__ + ": parse service objects - not yet supported") """ Parse service objects """ # Parse service groups logger.log(2, __name__ + ": parse service groups - not yet supported") """ Parse service groups """ # Parse firewall policies logger.log(2, __name__ + ": parse firewall policies - not yet supported") """ Parse firewall policies """ # Parse NAT logger.log(2, __name__ + ": parse NAT - not yet supported") """ Parse NAT policies """ # Return parsed data logger.log(2, __name__ + ": parser module finished") return data
def generate(logger, parsed_data): logger.log(2, __name__ + ": generator module started") # Initialise variables dst_config = [] # Generator specific variables """ Generator specific variables """ # Generate system logger.log(2, __name__ + ": generate system") """ Generate system objects such as hostname, DNS """ # Generate interfaces logger.log(2, __name__ + ": generate interfaces") """ Generate interfaces """ # Generate zones logger.log(2, __name__ + ": generate zones") """ Generate zones """ # Generate static routes logger.log(2, __name__ + ": generate static routes") """ Generate static routes """ # Generate network objects logger.log(2, __name__ + ": generate network objects") """ Generate network objects """ # Generate network groups logger.log(2, __name__ + ": generate network groups") """ Generate network groups """ # Generate service objects logger.log(2, __name__ + ": generate service objects") """ Generate service objects """ # Generate service groups logger.log(2, __name__ + ": generate service groups") """ Generate service groups """ # Generate policies logger.log(2, __name__ + ": generate policies") """ Generate firewall policies """ # Generate NAT logger.log(2, __name__ + ": generate NAT") """ Generate NAT policies """ # Return generated config logger.log(2, __name__ + ": generator module finished") return dst_config
def main(src_format, dst_format, routing_info=""): # Load source configuration file logger.log( 2, "DirectFire.Converter.main: loading source configuration from " + args.config) try: with open(args.config) as config_file: src_config = config_file.read() except: logger.log( 4, "DirectFire.Converter.main: source file either not found or not readable " + args.config, ) print( f"{Fore.RED}Error: source file either not found or not readable.{Style.RESET_ALL}" ) exit() if routing_info: try: with open(args.routing) as routing_file: routing_info = routing_file.read() except: logger.log( 4, "DirectFire.Converter.main: routing file either not found or not readable " + args.config, ) print( f"{Fore.RED}Error: routing file either not found or not readable.{Style.RESET_ALL}" ) exit() # Run configuration parser logger.log(2, "DirectFire.Converter.main: running configuration parser") parsed_data = parse(src_format=src_format, src_config=src_config, routing_info=routing_info) logger.log(2, "DirectFire.Converter.main: configuration parser finished") # Output logger.log(2, "DirectFire.Converter.main: running configuration generator") dst_config = generate(dst_format=dst_format, parsed_data=parsed_data) for line in dst_config: print(line) ### add support for output to file logger.log(2, "DirectFire.Converter.main: configuration generator finished") logger.log(2, "DirectFire.Converter.main: converter exiting")
help="destination format", required=True, ) arg_parser.add_argument( "-r", "--routing", help="path to supplemental routing information csv file") args = arg_parser.parse_args() # Initiate logging logger = logger(args.source, args.destination) logger.log(2, "DirectFire.Converter.main: converter starting") logger.log(2, "DirectFire.Converter.main: source format is " + args.source) def parse(src_format, src_config, routing_info=""): logger.log( 2, "DirectFire.Converter.parse: loading parser module for " + src_format) if src_format == "ciscoasa": ## Cisco ASA from DirectFire.Converter.parsers.ciscoasa import parse elif src_format == "ciscoasa_pre83": ## Cisco ASA pre 8.3 from DirectFire.Converter.parsers.ciscoasa_pre83 import parse
def generate(logger, parsed_data): logger.log(2, __name__ + ": generator module started") # Initialise variables dst_config = [] # Generator specific variables """ Generator specific variables """ # Generate system logger.log(2, __name__ + ": generate system") try: dst_config.append("hostname " + parsed_data["system"]["hostname"]) except: logger.log(3, __name__ + ": hostname not found in parsed data") pass try: dst_config.append("domain-name " + data["system"]["domain"]) except: logger.log(3, __name__ + ": domain name not found in parsed data") pass # Generate interfaces logger.log(3, __name__ + ": generate interfaces - not yet supported") """ Generate interfaces """ # Generate zones logger.log(3, __name__ + ": generate zones - not yet supported") """ Generate zones """ # Generate static routes logger.log(2, __name__ + ": generate static routes") for route_id, attributes in enumerate(parsed_data["routes"]): if attributes["gateway"] != "0.0.0.0": dst_config.append("route " + attributes["interface"] + " " + attributes["network"] + " " + attributes["mask"] + " " + attributes["gateway"] + " " + attributes["distance"]) # Generate network objects logger.log(2, __name__ + ": generate network objects") for address, attributes in parsed_data["network_objects"].items(): if attributes["type"] == "host": dst_config.append("object network " + address) dst_config.append(" host " + attributes["host"]) elif attributes["type"] == "network": dst_config.append("object network " + address) dst_config.append(" subnet " + attributes["network"] + " " + attributes["mask"]) elif attributes["type"] == "range": dst_config.append("object network " + address) dst_config.append(" range " + attributes["address_first"] + " " + attributes["address_last"]) elif attributes["type"] == "domain": dst_config.append("object network " + address) dst_config.append(" fqdn " + attributes["fqdn"]) # Generate network groups logger.log(2, __name__ + ": generate network groups") for group, attributes in parsed_data["network_groups"].items(): dst_config.append("object-group network " + group) for member in attributes["members"]: dst_config.append(" network-object object " + member) # Generate service objects logger.log(2, __name__ + ": generate service objects") for service, attributes in parsed_data["service_objects"].items(): if attributes["type"] == "service": if attributes["protocol"] == "6": dst_config.append("object service " + service) dst_config.append(" service tcp destination eq " + attributes["dst_port"]) elif attributes["protocol"] == "17": dst_config.append("object service " + service) dst_config.append(" service udp destination eq " + attributes["dst_port"]) elif attributes["protocol"] == "1": dst_config.append("object service " + service) dst_config.append(" service icmp " + attributes["icmp_type"] + " " + attributes["icmp_code"]) elif attributes["type"] == "range": if attributes["protocol"] == "6": dst_config.append("object service " + service) dst_config.append(" service tcp destination range " + attributes["dst_port_first"] + " " + attributes["dst_port_last"]) elif attributes["protocol"] == "17": dst_config.append("object service " + service) dst_config.append(" service udp destination range " + attributes["dst_port_first"] + " " + attributes["dst_port_last"]) # Generate service groups logger.log(2, __name__ + ": generate service groups") for group, attributes in parsed_data["service_groups"].items(): dst_config.append("object-group service " + group) for member in attributes["members"]: dst_config.append(" service-object object " + member) # Generate policies logger.log(2, __name__ + ": generate policies - not yet supported") # access_lists = {} for policy_id, attributes in enumerate(parsed_data["policies"]): rule_command = "" if attributes["action"] == "allow": rule_action = "permit" else: rule_action = "deny" rule_command = "extended " + rule_action ## generate destination services if len(attributes["dst_services"]) == 1: if attributes["dst_services"][0]["name"] == "any": rule_command = rule_command + " ip" else: if attributes["dst_services"][0]["type"] == "service": rule_command = (rule_command + " object " + attributes["dst_services"][0]["name"]) ### range needed here? elif attributes["dst_services"][0]["type"] == "group": rule_command = (rule_command + " object-group " + attributes["dst_services"][0]["name"]) else: ## need to create object group and reference here pass ## generate source address if len(attributes["src_addresses"]) == 1: if attributes["src_addresses"][0]["name"] == "any": rule_command = rule_command + " any" elif attributes["dst_services"][0]["type"] == "host": rule_command = (rule_command + " object " + attributes["src_addresses"][0]["name"]) elif attributes["dst_services"][0]["type"] == "range": rule_command = (rule_command + " object " + attributes["src_addresses"][0]["name"]) elif attributes["dst_services"][0]["type"] == "network": rule_command = (rule_command + " object " + attributes["src_addresses"][0]["name"]) elif attributes["dst_services"][0]["type"] == "group": rule_command = (rule_command + " object-group " + attributes["src_addresses"][0]["name"]) else: ## need to create object group and reference here pass ## generate destination address if len(attributes["src_addresses"]) == 1: if attributes["dst_addresses"][0]["name"] == "any": rule_command = rule_command + " any" elif attributes["dst_addresses"][0]["type"] == "host": rule_command = (rule_command + " object " + attributes["dst_addresses"][0]["name"]) elif attributes["dst_addresses"][0]["type"] == "range": rule_command = (rule_command + " object " + attributes["dst_addresses"][0]["name"]) elif attributes["dst_addresses"][0]["type"] == "network": rule_command = (rule_command + " object " + attributes["dst_addresses"][0]["name"]) elif attributes["dst_addresses"][0]["type"] == "group": rule_command = (rule_command + " object-group " + attributes["dst_addresses"][0]["name"]) else: ## need to create object group and reference here pass ## generate policy flags if attributes["logging"] == True: rule_command = rule_command + " log" if attributes["enabled"] == False: rule_command = rule_command + " inactive" ## add to acl if attributes["policy_set"]: rule_command = ("access-list " + attributes["policy_set"] + " " + rule_command) dst_config.append(rule_command) else: for interface in attributes["src_interfaces"]: rule_command = "access-list " + interface + "_in " + rule_command dst_config.append(rule_command) # if attributes["src_interface"] not in access_lists: # access_lists[attributes["src_interface"]] = [] # access_lists[attributes["src_interface"]].append(rule_command) # for access_list, commands in access_lists.items(): # for command in commands: # dst_config.append(command) # for access_list in access_lists.keys(): # dst_config.append( # "access-group " + access_list + "_in in interface " + access_list # ) # Generate NAT logger.log(3, __name__ + ": generate NAT - not yet supported") """ Generate NAT policies """ # Return generated config logger.log(2, __name__ + ": generator module finished") return dst_config
def parse(logger, src_config, routing_info=""): logger.log(2, __name__ + ": parser module started") # Initialise data """ May need to process XML to ET, JSON etc here """ # Initialise variables data = {} data["system"] = {} data["interfaces"] = {} data["zones"] = {} data["routes"] = [] data["routes6"] = [] data["network_objects"] = {} data["network6_objects"] = {} data["network_groups"] = {} data["network6_groups"] = {} data["service_objects"] = {} data["service_groups"] = {} data["policies"] = [] data["nat"] = [] # Parser specific variables """ Parser specific variables """ # Parse system logger.log(2, __name__ + ": parse system") """ Parse system objects such as hostname, DNS """ # Parse interfaces logger.log(2, __name__ + ": parse interfaces") """ Parse interfaces """ # Parse zones logger.log(2, __name__ + ": parse zones") """ Parse zones """ # Parse static routes logger.log(2, __name__ + ": parse static routes") """ Parse static routes """ # Parse IPv4 network objects logger.log(2, __name__ + ": parse IPv4 network objects") """ Parse IPv4 network objects """ # Parse IPv6 network objects logger.log(2, __name__ + ": parse IPv6 network objects") """ Parse IPv6 network objects """ # Parse IPv4 network groups logger.log(2, __name__ + ": parse IPv4 network groups") """ Parse IPv4 network groups """ # Parse IPv6 network groups logger.log(2, __name__ + ": parse IPv6 network groups") """ Parse IPv6 network groups """ # Parse service objects logger.log(2, __name__ + ": parse service objects") """ Parse service objects """ # Parse service groups logger.log(2, __name__ + ": parse service groups") """ Parse service groups """ # Parse firewall policies logger.log(2, __name__ + ": parse firewall policies") """ Parse firewall policies """ # Parse NAT logger.log(2, __name__ + ": parse NAT") """ Parse NAT policies """ # Return parsed data logger.log(2, __name__ + ": parser module finished") return data
def parse(logger, src_config, routing_info=""): logger.log(2, __name__ + ": parser module started") # Initialise data src_config_xml = ET.ElementTree(ET.fromstring(src_config)) # Initialise variables data = {} data["system"] = {} data["interfaces"] = {} data["zones"] = {} data["routes"] = [] data["routes6"] = [] data["network_objects"] = {} data["network6_objects"] = {} data["network_groups"] = {} data["network6_groups"] = {} data["service_objects"] = {} data["service_groups"] = {} data["policies"] = [] data["nat"] = [] # Parser specific variables """ Parser specific variables """ # Parse system logger.log(2, __name__ + ": parse system") src_system = src_config_xml.find("system-parameters").find("device-conf") data["system"]["hostname"] = src_system.find("system-name").text data["system"]["domain"] = src_system.find("domain-name").text # Parse interfaces logger.log(2, __name__ + ": parse interfaces") interface_routes = [] interfaces = src_config_xml.findall("./interface-list/interface") for interface in interfaces: interface_name = interface.find("name").text data["interfaces"][interface_name] = {} data["interfaces"][interface_name]["enabled"] = True data["interfaces"][interface_name]["description"] = ( interface.find("description").text if interface.find("description") else "") data["interfaces"][interface_name]["ipv4_config"] = [] data["interfaces"][interface_name]["mtu"] = "" data["interfaces"][interface_name]["physical_interfaces"] = [] data["interfaces"][interface_name]["type"] = "interface" data["interfaces"][interface_name]["vlan_id"] = "" data["interfaces"][interface_name]["vlan_name"] = "" if interface_name not in [ "Any", "Any-BOVPN", "Any-External", "Any-Multicast", "Any-MUVPN", "Any-Optional", "Any-Trusted", "Any-VPN", "Firebox", "Tunnel-Switch", ]: data["interfaces"][interface_name] = {} data["interfaces"][interface_name]["enabled"] = True data["interfaces"][interface_name]["description"] = ( interface.find("description").text if interface.find("description") else "") data["interfaces"][interface_name]["ipv4_config"] = [] data["interfaces"][interface_name]["ipv6_config"] = [] data["interfaces"][interface_name]["mtu"] = "" data["interfaces"][interface_name]["physical_interfaces"] = [] data["interfaces"][interface_name]["vlan_id"] = "" data["interfaces"][interface_name]["vlan_name"] = "" interface_items = interface.findall("./if-item-list/item") for item in interface_items: physical_interface = item.find("physical-if") if physical_interface: # find interface enabled if physical_interface.find("mtu").text == "0": data["interfaces"][interface_name]["enabled"] = False else: data["interfaces"][interface_name]["enabled"] = True # if ipv4 if physical_interface.find( "ip-node-type").text == "IP4_ONLY": # find interface primary ip config interface_ip_member = {} interface_ip_member[ "ip_address"] = physical_interface.find("ip").text interface_ip_member["mask"] = physical_interface.find( "netmask").text interface_ip_member["type"] = "primary" if interface_ip_member["ip_address"] not in [ "", "0.0.0.0" ]: data["interfaces"][interface_name][ "ipv4_config"].append(interface_ip_member) # find interface secondary ip config secondary_ip = physical_interface.findall( "./secondary-ip-list/secondary-ip") for ipv4_config in secondary_ip: interface_ip_member = {} interface_ip_member[ "ip_address"] = ipv4_config.find("ip").text interface_ip_member["mask"] = ipv4_config.find( "netmask").text if (len(data["interfaces"][interface_name] ["ipv4_config"]) == 0): interface_ip_member["type"] = "primary" else: interface_ip_member["type"] = "secondary" if interface_ip_member["ip_address"] not in [ "", "0.0.0.0" ]: data["interfaces"][interface_name][ "ipv4_config"].append(interface_ip_member) ### need to add ipv6 support # find interface mtu data["interfaces"][interface_name][ "mtu"] = physical_interface.find("mtu").text # if an external interface add an interface route external_interface = physical_interface.find("external-if") if external_interface: interface_route = {} interface_route["gateway"] = physical_interface.find( "default-gateway").text interface_route["interface"] = interface_name interface_routes.append(interface_route) # set type data["interfaces"][interface_name]["type"] = "interface" else: # probably a VPN tunnel interface data["interfaces"][interface_name]["type"] = "vpn" # Parse zones logger.log(2, __name__ + ": parse zones - not yet supported") """ Parse zones """ # Parse static routes logger.log(2, __name__ + ": parse static routes") src_routes = src_config_xml.findall( "./system-parameters/route/route-entry") for interface_route_config in interface_routes: route = {} route["network"] = "0.0.0.0" route["mask"] = "0.0.0.0" route["gateway"] = interface_route_config["gateway"] route["interface"] = interface_route_config["interface"] route["distance"] = "1" data["routes"].append(route) for route_config in src_routes: route_gateway = route_config.find("gateway-ip").text route = {} route["network"] = route_config.find("dest-address").text route["mask"] = route_config.find("mask").text route["gateway"] = route_gateway route["interface"] = interface_lookup(route_gateway, data["interfaces"], data["routes"]) route["distance"] = route_config.find("metric").text data["routes"].append(route) # Parse network groups logger.log(2, __name__ + ": parse network groups") src_addr_grp = src_config_xml.findall("./address-group-list/address-group") for addr_grp in src_addr_grp: grp_name = cleanse_names(addr_grp.find("name").text) data["network_groups"][grp_name] = {} data["network_groups"][grp_name]["type"] = "group" data["network_groups"][grp_name]["description"] = addr_grp.find( "description").text data["network_groups"][grp_name]["members"] = [] members = addr_grp.findall("./addr-group-member/member") for member in members: mbr_type = member.find("type").text if mbr_type == "1": # host mbr_host = member.find("host-ip-addr").text mbr_name = "host_" + mbr_host data["network_objects"][mbr_name] = {} data["network_objects"][mbr_name]["type"] = "host" data["network_objects"][mbr_name]["host"] = mbr_host data["network_objects"][mbr_name]["description"] = "" data["network_groups"][grp_name]["members"].append(mbr_name) elif mbr_type == "2": # network mbr_network = member.find("ip-network-addr").text mbr_mask = member.find("ip-mask").text mbr_name = "net_" + mbr_network + "_" + mbr_mask data["network_objects"][mbr_name] = {} data["network_objects"][mbr_name]["type"] = "network" data["network_objects"][mbr_name]["network"] = mbr_network data["network_objects"][mbr_name]["mask"] = mbr_mask data["network_objects"][mbr_name]["description"] = "" data["network_groups"][grp_name]["members"].append(mbr_name) elif mbr_type == "3": # ip range mbr_address_first = member.find("start-ip-addr").text mbr_address_last = member.find("end-ip-addr").text mbr_name = "range_" + mbr_address_first + "-" + mbr_address_last data["network_objects"][mbr_name] = {} data["network_objects"][mbr_name]["type"] = "range" data["network_objects"][mbr_name][ "address_first"] = mbr_address_first data["network_objects"][mbr_name][ "address_last"] = mbr_address_last data["network_objects"][mbr_name]["description"] = "" data["network_groups"][grp_name]["members"].append(mbr_name) # Parse service groups logger.log(2, __name__ + ": parse service groups") src_services = src_config_xml.findall("./service-list/service") for svc_group in src_services: grp_name = cleanse_names(svc_group.find("name").text) data["service_groups"][grp_name] = {} data["service_groups"][grp_name]["type"] = "group" data["service_groups"][grp_name]["description"] = svc_group.find( "description").text data["service_groups"][grp_name]["members"] = [] members = svc_group.findall("./service-item/member") protocols_with_ports = ["6", "17"] for member in members: mbr_protocol = member.find("protocol").text mbr_type = member.find("type").text if mbr_protocol in protocols_with_ports: if mbr_type == "1": # single port mbr_port = member.find("server-port").text mbr_name = "svc_" + mbr_protocol + "_" + mbr_port data["service_objects"][mbr_name] = {} data["service_objects"][mbr_name]["type"] = "service" data["service_objects"][mbr_name][ "protocol"] = mbr_protocol data["service_objects"][mbr_name]["dst_port"] = mbr_port data["service_objects"][mbr_name]["description"] = "" data["service_groups"][grp_name]["members"].append( mbr_name) elif mbr_type == "2": # port range mbr_port_first = member.find("start-server-port").text mbr_port_last = member.find("end-server-port").text mbr_name = ("svc_" + mbr_protocol + "_" + mbr_port_first + "-" + mbr_port_last) data["service_objects"][mbr_name] = {} data["service_objects"][mbr_name]["type"] = "range" data["service_objects"][mbr_name][ "protocol"] = mbr_protocol data["service_objects"][mbr_name][ "dst_port_first"] = mbr_port_first data["service_objects"][mbr_name][ "dst_port_last"] = mbr_port_last data["service_objects"][mbr_name]["description"] = "" data["service_groups"][grp_name]["members"].append( mbr_name) elif mbr_protocol == "1": if mbr_type == "1": # single type / code mbr_icmp_type = member.find("icmp_type").text mbr_icmp_code = member.find("icmp_code").text mbr_name = ("svc_" + mbr_protocol + "_" + mbr_icmp_type + "_" + mbr_icmp_code) data["service_objects"][mbr_name] = {} data["service_objects"][mbr_name]["type"] = "service" data["service_objects"][mbr_name][ "protocol"] = mbr_protocol data["service_objects"][mbr_name][ "icmp_type"] = mbr_icmp_type data["service_objects"][mbr_name][ "icmp_code"] = mbr_icmp_code data["service_objects"][mbr_name]["description"] = "" data["service_groups"][grp_name]["members"].append( mbr_name) # Parse firewall policies logger.log(2, __name__ + ": parse firewall policies") src_policies = src_config_xml.findall("./policy-list/policy") for policy_config in src_policies: policy = {} policy["action"] = "" policy["description"] = policy_config.find("description").text policy["dst_addresses"] = [] policy["dst_interfaces"] = [] policy["dst_services"] = [] policy["enabled"] = False if policy_config.find( "enable").text == "0" else True policy["logging"] = False if policy_config.find( "log").text == "0" else True policy["name"] = policy_config.find("name").text policy[ "nat"] = "" ### many values here - nat, global-1to1-nat, global-dnat policy["policy_set"] = "" policy["protocol"] = "any" policy["schedule"] = policy_config.find("schedule").text policy["src_addresses"] = [] policy["src_interfaces"] = [] policy["src_services"] = ["any"] policy["type"] = "policy" policy["users_excluded"] = [] policy["users_included"] = [] ## find desination addresses for dst_alias_name in policy_config.find("to-alias-list").findall( "alias"): if dst_alias_name.text == "Any": dst_address = {} dst_address["name"] = "any" dst_address["type"] = "any" policy["dst_addresses"].append(dst_address) else: dst_address = {} dst_address["name"] = dst_alias_name.text dst_address["type"] = "network" ## need to check if a group policy["dst_addresses"].append(dst_address) ## find desination services for dst_service_name in policy_config.findall("service"): if dst_service_name.text == "Any": dst_service = {} dst_service["name"] = "any" dst_service["type"] = "any" policy["dst_services"].append(dst_service) else: dst_service = {} dst_service["name"] = dst_service_name.text dst_service["type"] = "network" ## need to check if a group policy["dst_services"].append(dst_service) ## find source addresses for src_alias_name in policy_config.find("from-alias-list").findall( "alias"): if src_alias_name.text == "Any": src_address = {} src_address["name"] = "any" src_address["type"] = "any" policy["src_addresses"].append(src_address) else: src_address = {} src_address["name"] = src_alias_name.text src_address["type"] = "network" ## need to check if a group policy["src_addresses"].append(src_address) ### need to lookup interface for destination alias ### need to lookup interface for source alias data["policies"].append(policy) # Parse NAT logger.log(3, __name__ + ": parse NAT - not yet supported") # Return parsed data logger.log(2, __name__ + ": parser module finished") return data
def generate(logger, parsed_data): logger.log(2, __name__ + ": generator module started") # Initialise variables dst_config = [] # Generator specific variables cfglvl1 = " " cfglvl2 = " " cfglvl3 = " " cfglvl4 = " " cfglvl5 = " " # Generate system logger.log(2, __name__ + ": generate system") dst_config.append("config system global") if "hostname" in parsed_data["system"]: dst_config.append(cfglvl1 + "set hostname " + parsed_data["system"]["hostname"]) else: logger.log(3, __name__ + ": hostname not found in parsed data") dst_config.append("end") dst_config.append("config system dns") if "domain" in parsed_data["system"]: dst_config.append(cfglvl1 + "set domain " + parsed_data["system"]["domain"]) else: logger.log(3, __name__ + ": domain name not found in parsed data") dst_config.append("end") # Generate interfaces logger.log(2, __name__ + ": generate interfaces") dst_config.append("config system interface") for interface, attributes in parsed_data["interfaces"].items(): if attributes["type"] == "interface": dst_config.append(cfglvl1 + "edit " + interface) dst_config.append(cfglvl2 + "set vdom root") if attributes["ipv4_config"]: dst_config.append(cfglvl2 + "set mode static") last_ipv4 = len(attributes["ipv4_config"]) - 1 for i in range(len(attributes["ipv4_config"])): if i == 0: dst_config.append( cfglvl2 + "set ip " + attributes["ipv4_config"][i]["ip_address"] + " " + attributes["ipv4_config"][i]["mask"] ) else: if i == 1: dst_config.append(cfglvl2 + "set secondary-IP enable") dst_config.append(cfglvl2 + "config secondaryip") dst_config.append(cfglvl3 + "edit " + str(i)) dst_config.append( cfglvl4 + "set ip " + attributes["ipv4_config"][i]["ip_address"] + " " + attributes["ipv4_config"][i]["mask"] ) dst_config.append(cfglvl3 + "next") if i == last_ipv4: dst_config.append(cfglvl2 + "end") dst_config.append(cfglvl1 + "next") ### need to add support for sub interfaces and switch interfaces dst_config.append("end") # Generate zones logger.log(3, __name__ + ": generate zones - not yet supported") """ Generate zones """ # Generate static routes logger.log(2, __name__ + ": generate static routes") dst_config.append("config router static") for route_id, attributes in enumerate(parsed_data["routes"]): dst_config.append(cfglvl1 + "edit " + str(route_id)) dst_config.append( cfglvl2 + "set dst " + attributes["network"] + " " + attributes["mask"] ) dst_config.append(cfglvl2 + "set device " + attributes["interface"]) dst_config.append(cfglvl2 + "set gateway " + attributes["gateway"]) dst_config.append(cfglvl2 + "set distance " + attributes["distance"]) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate network objects logger.log(2, __name__ + ": generate network objects") dst_config.append("config firewall address") for address, attributes in parsed_data["network_objects"].items(): dst_config.append(cfglvl1 + 'edit "' + address + '"') if attributes["type"] == "host": dst_config.append(cfglvl2 + "set type ipmask") dst_config.append( cfglvl2 + "set subnet " + attributes["host"] + " 255.255.255.255" ) elif attributes["type"] == "network": dst_config.append(cfglvl2 + "set type ipmask") dst_config.append( cfglvl2 + "set subnet " + attributes["network"] + " " + attributes["mask"] ) elif attributes["type"] == "range": dst_config.append(cfglvl2 + "set type iprange") dst_config.append(cfglvl2 + "set start-ip " + attributes["address_first"]) dst_config.append(cfglvl2 + "set end-ip " + attributes["address_last"]) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate network groups logger.log(2, __name__ + ": generate network groups") dst_config.append("config firewall addrgrp") for group, attributes in parsed_data["network_groups"].items(): grp_members = "" if attributes["type"] == "group": dst_config.append(' edit "' + group + '"') for member in attributes["members"]: grp_members = grp_members + ' "' + member + '"' if grp_members: dst_config.append(cfglvl2 + "set member" + grp_members) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate service objects logger.log(2, __name__ + ": generate service objects") dst_config.append("config firewall service custom") for service, attributes in parsed_data["service_objects"].items(): dst_config.append(' edit "' + service + '"') if attributes["type"] == "service": if attributes["protocol"] in ["1", "icmp", "Icmp", "ICMP"]: dst_config.append(cfglvl2 + "set protocol ICMP") if attributes["icmp_type"]: dst_config.append( cfglvl2 + "set icmptype " + attributes["icmp_type"] ) if attributes["icmp_code"]: dst_config.append( cfglvl2 + "set icmpcode " + attributes["icmp_code"] ) elif attributes["protocol"] in ["6", "tcp", "Tcp", "TCP"]: dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP") if attributes["dst_port"]: dst_config.append( cfglvl2 + "set tcp-portrange " + attributes["dst_port"] ) elif attributes["protocol"] in ["17", "udp", "Udp", "UDP"]: dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP") if attributes["dst_port"]: dst_config.append( cfglvl2 + "set udp-portrange " + attributes["dst_port"] ) else: dst_config.append(cfglvl2 + "set protocol IP") dst_config.append( cfglvl2 + "set protocol-number " + attributes["protocol"] ) if attributes["type"] == "range": if attributes["protocol"] in ["6", "tcp", "Tcp", "TCP"]: dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP") dst_config.append( cfglvl2 + "set tcp-portrange " + attributes["dst_port_first"] + "-" + attributes["dst_port_last"] ) elif attributes["protocol"] in ["17", "udp", "Udp", "UDP"]: dst_config.append(cfglvl2 + "set protocol TCP/UDP/SCTP") dst_config.append( cfglvl2 + "set udp-portrange " + attributes["dst_port_first"] + "-" + attributes["dst_port_last"] ) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate service groups logger.log(2, __name__ + ": generate service groups") dst_config.append("config firewall service group") for group, attributes in parsed_data["service_groups"].items(): grp_members = "" if attributes["type"] == "group": dst_config.append(' edit "' + group + '"') for member in attributes["members"]: grp_members = grp_members + ' "' + member + '"' if grp_members: dst_config.append(cfglvl2 + "set member" + grp_members) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate policies logger.log(3, __name__ + ": generate policies - not yet supported") dst_config.append("config firewall policy") for policy_id, attributes in enumerate(parsed_data["policies"]): dst_config.append(cfglvl1 + "edit " + str(policy_id)) dst_config.append( cfglvl2 + "set srcintf " + " ".join(list(map(str, attributes["src_interfaces"]))) ) dst_config.append( cfglvl2 + "set dstintf " + " ".join(list(map(str, attributes["dst_interfaces"]))) ) # dst_config.append( # cfglvl2 # + "set srcaddr " # + " ".join(list(map(str, attributes["src_addresses"]))) # ) # dst_config.append( # cfglvl2 # + "set dstaddr " # + " ".join(list(map(str, attributes["dst_addresses"]))) # ) if attributes["description"]: dst_config.append(cfglvl2 + "set description " + attributes["description"]) dst_config.append(cfglvl1 + "next") dst_config.append("end") # Generate NAT logger.log(3, __name__ + ": generate NAT - not yet supported") # Return generated config logger.log(2, __name__ + ": generator module finished") return dst_config