def main(): parser = argparse.ArgumentParser() parser.add_argument('--panorama', help='hostname or ip of panorama', required=True) parser.add_argument('--user', help='username for auth to panorama', required=True) parser.add_argument( '--out_file', help='filename for output csv e.g. mkey_status_prod.csv', required=True) args = parser.parse_args() try: panorama = Panorama(args.panorama, args.user, getpass()) except PanDeviceError as e: print(e.message) cmd = 'show devices connected' try: res = panorama.op(cmd, xml=True) except PanDeviceError as e: print(e.message) sys.exit(1) print('Authenticated to {}.'.format(args.panorama)) print( 'Generating master key status report on Panorama-connected firewalls...' ) devs_connected = xmltodict.parse( res)['response']['result']['devices']['entry'] master_key_props_list = [] for dev in devs_connected: firewall = Firewall(serial=dev['serial']) panorama.add(firewall) cmd = 'show system masterkey-properties' master_key_props = xmltodict.parse(firewall.op( cmd, xml=True))['response']['result'] master_key_props['hostname'] = dev['hostname'] master_key_props_list.append(master_key_props) with open(args.out_file, 'w', newline='') as file_obj: fieldnames = master_key_props_list[0].keys() writer_obj = csv.DictWriter(file_obj, fieldnames=fieldnames) writer_obj.writeheader() for dev_mkey_props in master_key_props_list: writer_obj.writerow(dev_mkey_props) print('Done.')
def start(self): # Get/Generate the firewall API key from the credentials stored in Splunk if self.firewall is None: apikey = self.connector.apikey(self.device) # Perform the tagging operation on the firewall self.firewall = Firewall(self.device, api_key=apikey) self.firewall.userid.batch_start()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--panorama', help='hostname or ip of panorama', required=True) parser.add_argument('--user', help='username for auth to panorama', required=True) args = parser.parse_args() try: panorama = Panorama(args.panorama, args.user, getpass()) except PanDeviceError as e: print(e.message) cmd = 'show devices connected' try: res = panorama.op(cmd, xml=True) except PanDeviceError as e: print(e.message) sys.exit(1) devs_connected = xmltodict.parse( res)['response']['result']['devices']['entry'] ha_devices_out_of_sync = [] for dev in devs_connected: firewall = Firewall(serial=dev['serial']) panorama.add(firewall) cmd = 'show high-availability state' ha_state = xmltodict.parse(firewall.op(cmd, xml=True))['response']['result'] if ha_state['enabled'] == 'yes': if ha_state['group']['running-sync'] != 'synchronized': ha_devices_out_of_sync.append(dev['hostname']) if ha_devices_out_of_sync: for dev in ha_devices_out_of_sync: print(dev) else: print('All HA devices configuration in sync!')
def main(): global pan_device, username, password, dry_run_flag if len(sys.argv) == 3 and sys.argv[2] == '--dry-run': dry_run_flag = True print( '\n\n\n******* Dry-run flag enabled - No chages will be made *******\n\n' ) elif len(sys.argv) == 2: pass else: time.sleep(.75) print( '\nERROR: The proper format is rename-addr-objects_multithreaded.py <addr-list.csv> [--dry-run]\n\n' ) exit() with open(sys.argv[1], 'r') as rfile: print(f"\n\nCSV file found...\n\n") addr_list_mods = [tuple(line.rstrip().split(',')) for line in rfile] check_list_validity(addr_list_mods) pan_addr = get_pan_addr() username, password = get_creds() # Determine whether this is a Panorama or firewall dev_type = get_dev_type(pan_addr) if dev_type == 'pano': while True: pan_device = Panorama(pan_addr, username, password) get_pano_dg() addr_list_names = match_address_objects(addr_list_mods) push_addr_changes(addr_list_names) dg_choice = input( '\n\nWould you like to run this script against another device group? [Y/n] ' ) if not dg_choice or dg_choice.lower() == 'y': new_list = input( '\n\nEnter the name of the address list for this device group, (leave blank to use the same list): ' ) if not new_list: new_list = sys.argv[1] with open(new_list, 'r') as rfile: print(f"\n\nCSV file found...\n\n") addr_list_mods = [ tuple(line.rstrip().split(',')) for line in rfile ] check_list_validity(addr_list_mods) elif dg_choice.lower() == 'n': break else: print("\n\nChoose '1' or '2', try again...\n") time.sleep(.75) else: pan_device = Firewall(pan_addr, username, password) addr_list_names = match_address_objects(addr_list_mods) push_addr_changes(addr_list_names) print('\n\n\nHave a great day!!\n\n')
def get_pandevice_parent(self, module, timeout=0): """Builds the pandevice object tree, returning the parent object. If pandevice is not installed, then module.fail_json() will be invoked. Arguments: * module(AnsibleModule): the ansible module. * timeout(int): Number of seconds to retry opening the connection to PAN-OS. Returns: * The parent pandevice object based on the spec given to get_connection(). """ # Sanity check. if not HAS_PANDEVICE: module.fail_json(msg='Missing required library "pandevice".') # Verify pandevice minimum version. if self.min_pandevice_version is not None: pdv = tuple(int(x) for x in pandevice.__version__.split('.')) if pdv < self.min_pandevice_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'pandevice', pandevice.__version__, _vstr(self.min_pandevice_version))) pan_device_auth, serial_number = None, None if module.params['provider'] and module.params['provider'][ 'ip_address']: pan_device_auth = ( module.params['provider']['ip_address'], module.params['provider']['username'], module.params['provider']['password'], module.params['provider']['api_key'], module.params['provider']['port'], ) serial_number = module.params['provider']['serial_number'] elif module.params.get('ip_address', None) is not None: pan_device_auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], module.params['port'], ) msg = 'Classic provider params are deprecated; use "provider" instead' module.deprecate(msg, '2.12') else: module.fail_json(msg='Provider params are required.') # Create the connection object. if not isinstance(timeout, int): raise ValueError('Timeout must be an int') elif timeout < 0: raise ValueError('Timeout must greater than or equal to 0') end_time = time.time() + timeout while True: try: self.device = PanDevice.create_from_device(*pan_device_auth) except PanDeviceError as e: if timeout == 0: module.fail_json(msg='Failed connection: {0}'.format(e)) elif time.time() >= end_time: module.fail_json(msg='Connection timeout: {0}'.format(e)) else: break # Verify PAN-OS minimum version. if self.min_panos_version is not None: if self.device._version_info < self.min_panos_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'PAN-OS', _vstr(self.device._version_info), _vstr(self.min_panos_version))) # Optional: Firewall via Panorama connectivity specified. if hasattr(self.device, 'refresh_devices') and serial_number: fw = Firewall(serial=serial_number) self.device.add(fw) self.device = fw parent = self.device no_shared = 'Scope "shared" is not allowed' not_found = '{0} "{1}" is not present.' pano_mia_param = 'Param "{0}" is required for Panorama but not specified.' ts_error = 'Specify either the template or the template stack{0}.' if hasattr(self.device, 'refresh_devices'): # Panorama connection. templated = False # Error if Panorama is not supported. if self.panorama_error is not None: module.fail_json(msg=self.panorama_error) # Spec: template stack. tmpl_required = False added_template = False if self.template_stack is not None: name = module.params[self.template_stack] if name is not None: templated = True stacks = TemplateStack.refreshall(parent, name_only=True) for ts in stacks: if ts.name == name: parent = ts added_template = True break else: module.fail_json(msg=not_found.format( 'Template stack', name, )) elif self.template is not None: tmpl_required = True else: module.fail_json( msg=pano_mia_param.format(self.template_stack)) # Spec: template. if self.template is not None: name = module.params[self.template] if name is not None: templated = True if added_template: module.fail_json(msg=ts_error.format(', not both')) templates = Template.refreshall(parent, name_only=True) for t in templates: if t.name == name: parent = t break else: module.fail_json(msg=not_found.format( 'Template', name, )) elif tmpl_required: module.fail_json(msg=ts_error.format('')) elif not added_template: module.fail_json(msg=pano_mia_param.format(self.template)) # Spec: vsys_dg or device_group. dg_name = self.vsys_dg or self.device_group if dg_name is not None: name = module.params[dg_name] if name not in (None, 'shared'): groups = DeviceGroup.refreshall(parent, name_only=True) for dg in groups: if dg.name == name: parent = dg break else: module.fail_json(msg=not_found.format( 'Device group', name, )) elif self.error_on_shared: module.fail_json(msg=no_shared) # Spec: vsys importable. vsys_name = self.vsys_importable or self.vsys or self.vsys_shared if dg_name is None and templated and vsys_name is not None: name = module.params[vsys_name] if name not in (None, 'shared'): vo = Vsys(name) parent.add(vo) parent = vo # Spec: rulebase. if self.rulebase is not None: if module.params[self.rulebase] in (None, 'pre-rulebase'): rb = PreRulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'rulebase': rb = Rulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'post-rulebase': rb = PostRulebase() parent.add(rb) parent = rb else: module.fail_json(msg=not_found.format( 'Rulebase', module.params[self.rulebase])) else: # Firewall connection. # Error if firewalls are not supported. if self.firewall_error is not None: module.fail_json(msg=self.firewall_error) # Spec: vsys or vsys_dg or vsys_importable. vsys_name = self.vsys_dg or self.vsys or self.vsys_importable or self.vsys_shared if vsys_name is not None: parent.vsys = module.params[vsys_name] if parent.vsys == 'shared' and self.error_on_shared: module.fail_json(msg=no_shared) # Spec: rulebase. if self.rulebase is not None: rb = Rulebase() parent.add(rb) parent = rb # Done. return parent
srv_matched = True break if rule.action == "allow": is_allowed = True if all([src_matched, dst_matched, app_matched, srv_matched, is_allowed]): return True return False if __name__ == "__main__": import config vsys = Firewall(config.host, config.api_username, config.api_password, serial=config.fw_serial, is_virtual=True, vsys=config.vsys) shared = Firewall(config.host, config.api_username, config.api_password, serial=config.fw_serial, is_virtual=True, vsys=config.shared_vsys) # Pull all address objects in vsys and shared configuration address = PanAddressObject.refreshall(shared) address.extend(PanAddressObject.refreshall(vsys)) # Pull all policies in vsys and filter security rules out rulebase = Rulebase.refreshall(vsys) security_rules = filter(lambda x: isinstance(x, SecurityRule), rulebase[0].children) # Pull all service objects from vsys and shared configuration all_services = ServiceObject.refreshall(vsys) all_services.extend(ServiceObject.refreshall(shared)) # Check if source ip address is included in any address objects
def main_splunk(): # Get arguments args, kwargs = splunk.Intersplunk.getKeywordsAndOptions() # Enable debugging by passing 'debug=yes' as an argument of # the command on the Splunk searchbar. debug = common.check_debug(kwargs) # kwargs contains important parameters. # parameters from splunk searchbar include: # action # device # panorama # serial # vsys # tag # tag_field # ip_field # debug # Verify required args were passed to command log(debug, "Determining if required arguments are present") if 'device' not in kwargs and 'panorama' not in kwargs: common.exit_with_error("Missing required command argument: device or panorama", 3) if 'tag' not in kwargs and 'tag_field' not in kwargs: common.exit_with_error("Missing required command argument: tag or tag_field", 3) # Assign defaults to fields that aren't specified action = kwargs['action'] if 'action' in kwargs else "addip" vsys = kwargs['vsys'] if 'vsys' in kwargs else None ip_field = kwargs['ip_field'] if 'ip_field' in kwargs else "src_ip" user_field = kwargs['user_field'] if 'user_field' in kwargs else "src_user" # Support 'field' argument (legacy syntax) if 'field' in kwargs and not 'ip_field' in kwargs: ip_field = kwargs['field'] tag = kwargs['tag'] if 'tag' in kwargs else None tag_field = kwargs['tag_field'] if 'tag_field' in kwargs else None # Determine if device hostname or serial was provided as argument or should be pulled from entries log(debug, "Determining how firewalls should be contacted based on arguments") use_panorama = False hostname = None serial = None if "device" in kwargs: hostname = kwargs['device'] if vsys is None: vsys = "vsys1" elif "panorama" in kwargs: use_panorama = True hostname = kwargs['panorama'] if "serial" in kwargs: serial = kwargs['serial'] if vsys is None: vsys = "vsys1" else: common.exit_with_error("Missing required command argument: device or panorama", 3) log(debug, "Use Panorama: %s" % use_panorama) log(debug, "VSys: %s" % vsys) log(debug, "Hostname: %s" % hostname) if use_panorama and serial is not None: log(debug, "Device Serial: %s" % serial) else: log(debug, "Using serials from logs") # Results contains the data from the search results and settings # contains the sessionKey that we can use to talk to Splunk results, unused1, settings = splunk.Intersplunk.getOrganizedResults() # Get the sessionKey sessionKey = settings['sessionKey'] log(debug, "Begin get API key") # Get the API key from the Splunk store or from the device at hostname if no apikey is stored apikey = common.apikey(sessionKey, hostname, debug) # Create the connection to the firewall or Panorama panorama = None if use_panorama: # For Panorama, create the Panorama object, and the firewall if only one serial panorama = Panorama(hostname, api_key=apikey) if serial is not None: firewall = {'firewall': Firewall(serial=serial, vsys=vsys)} panorama.add(firewall['firewall']) firewall['firewall'].userid.batch_start() else: firewall = {} else: firewall = {'firewall': Firewall(hostname, api_key=apikey, vsys=vsys)} firewall['firewall'].userid.batch_start() # Collect all the ip addresses and tags into firewall batch requests for result in results: ## Find the serial (if not a single firewall) if use_panorama and serial is None: try: this_serial = result['serial_number'] this_vsys = result['vsys'] except KeyError as e: result['status'] = "ERROR: Unable to determine serial number or vsys of device" continue else: ## Create the firewall object if using multiple serials if this_serial in firewall: this_firewall = firewall[(this_serial, this_vsys)] else: # Create the firewall object for this serial firewall[(this_serial, this_vsys)] = Firewall(serial=this_serial, vsys=this_vsys) this_firewall = firewall[(this_serial, this_vsys)] panorama.add(this_firewall) this_firewall.userid.batch_start() else: this_firewall = firewall['firewall'] ## Find the tag (if a tag_field was specified) this_tag = [] if tag_field is not None: try: this_tag.append(result[tag_field]) except KeyError as e: result['status'] = "ERROR: Unable to determine tag from field: %s" % tag_field continue if tag is not None: this_tag.append(tag) ## Find the field try: if action in ("adduser", "removeuser"): this_field = result[user_field] else: this_field = result[ip_field] except KeyError as e: result['status'] = "ERROR: Unable to determine value from field: %s" % this_field ## Create a request in the batch user-id update for the firewall ## No API call to the firewall happens until all batch requests are created. if action in ("add", "addip"): log(debug, "Registering tags on firewall %s: %s - %s" % (this_firewall, this_field, this_tag)) this_firewall.userid.register(this_field, this_tag) elif action in ("remove", "removeip"): log(debug, "Unregistering tags on firewall %s: %s - %s" % (this_firewall, this_field, this_tag)) this_firewall.userid.unregister(this_field, this_tag) elif action == "adduser": log(debug, "Registering tags on firewall %s: %s - %s" % (this_firewall, this_field, this_tag)) this_firewall.userid.tag_user(this_field, this_tag) elif action == "removeuser": log(debug, "Unregistering tags on firewall %s: %s - %s" % (this_firewall, this_field, this_tag)) this_firewall.userid.untag_user(this_field, this_tag) result['status'] = "Submitted successfully" ## Make the API calls to the User-ID API of each firewall try: for fw in list(firewall.values()): fw.userid.batch_end() except pan.xapi.PanXapiError as e: common.exit_with_error(str(e)) except Exception as e: common.exit_with_error(str(e)) # output results splunk.Intersplunk.outputResults(results)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--panorama', help='hostname or ip of panorama', required=True) parser.add_argument( '--master_device', help='hostname or ip of firewall to retrieve group-mappings', required=True) parser.add_argument( '--dg', help= 'device group of the pre-rulebase that contain user-group-based policies', required=True) args = parser.parse_args() try: panorama = Panorama(args.panorama, input('Panorama username: '******'Panorama password: '******'show devices connected' try: res = panorama.op(cmd, xml=True) except PanDeviceError as e: print(e.message) sys.exit(1) devs_connected = xmltodict.parse( res)['response']['result']['devices']['entry'] firewall = None for dev in devs_connected: if dev['hostname'] == args.master_device or dev[ 'ip-address'] == args.master_device: firewall = Firewall(serial=dev['serial']) break if firewall is not None: try: panorama.add(firewall) except PanDeviceError as e: print(e.message) else: print( 'Master device (firewall) is not managed by Panorama. Attempting direct connection to firewall...' ) try: firewall = Firewall(args.master_device, input('Firewall username: '******'Firewall password: '******'Retrieving user-group-mappings on master device: "{}"...'.format( args.master_device)) cmd = 'show user group list' try: res = firewall.op(cmd, xml=True) except PanDeviceError as e: print(e.message) user_group_data = xmltodict.parse(res)['response']['result'] user_group_list = re.findall(r'cn=.*?dc=com', user_group_data) print('Number of mapped user-groups found: {}\n'.format( len(user_group_list))) print('Currently mapped user-groups: ') for user_group in user_group_list: print('"{}"'.format(user_group)) print('\n') try: DeviceGroup.refreshall(panorama) target_dg = panorama.find(args.dg, DeviceGroup) if target_dg is None: print( 'Device group "{}" not found on Panorama device. Aborting...'. format(args.dg)) sys.exit() prb = PreRulebase() target_dg.add(prb) dg_pre_rules = SecurityRule.refreshall(prb) except PanDeviceError as e: print(e.message) print('Retrieving user-based security policy from device-group: "{}"...'. format(args.dg)) user_based_rules = [] for rule in dg_pre_rules: if not 'any' in rule.source_user: user_based_rules.append(rule) print('Number of user-based security rules found: {}\n'.format( len(user_based_rules))) for rule in user_based_rules: print('Validating user-based security rule: "{}"...'.format(rule.name)) for user in rule.source_user: if not user in user_group_list: print('Invalid user-group: "{}"'.format(user)) print('\n')
def get_firewall(device, serialnum): Firewall.refreshall(device, add=True) f = device.find(serialnum) return f
def main(): argument_spec = dict(ip_address=dict(required=True), username=dict(default='admin'), password=dict(default='admin', no_log=True), api_key=dict(no_log=True), serialnum=dict(required=True), devicegroup=dict(), templatestack=dict(), state=dict(default='present')) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=[['api_key', 'password']]) if not HAS_LIB: module.fail_json( msg='pan-python and pandevice are required for this module') serialnum = module.params["serialnum"] devicegroup = module.params['devicegroup'] templatestack = module.params['templatestack'] state = module.params['state'] # Get the authentication params auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], ) # Open the connection to the PAN-OS device device = None try: device = PanDevice.create_from_device(*auth) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Ensure we're not connected to a firewall if isinstance(device, Firewall): module.fail_json( msg='This module is only supported on Panorama instances') # Set our change flag changed = False # Add to Panorama if not already connected fw = get_firewall(device, serialnum) if fw is None and state == 'present' and not module.check_mode: fw = Firewall(serial=serialnum) device.add(fw) fw.create() changed = True # Process the DeviceGroup if devicegroup: dg = get_devicegroup(device, devicegroup) if dg is None: module.fail_json( msg="DeviceGroup not found: {0}".format(devicegroup)) elif dg.find( fw.serial, Firewall ) is None and state == 'present' and not module.check_mode: dg.add(fw) fw.create() changed = True elif dg.find(fw.serial, Firewall) and state == 'absent' and not module.check_mode: dg.remove(dg.find(fw.serial)) dg.apply() changed = True # Add to the Template Stack if templatestack: ts = get_templatestack(device, templatestack) if ts is None: module.fail_json( msg="TemplateStack not found: {0}".format(templatestack)) else: listify(ts) if fw.serial not in ts.devices and state == 'present' and not module.check_mode: ts.devices.append(serialnum) ts.create() changed = True elif fw.serial in ts.devices and state == 'absent' and not module.check_mode: ts.devices.remove(fw.serial) ts.apply() changed = True # Remove from Panorama if (device.find(fw.serial, Firewall)) and (state == 'absent'): device.remove(fw) device.apply() changed = True module.exit_json(changed=changed)
def main_splunk(): # Get arguments args, kwargs = splunk.Intersplunk.getKeywordsAndOptions() # Enable debugging by passing 'debug=yes' as an argument of # the command on the Splunk searchbar. debug = common.check_debug(kwargs) # kwargs contains important parameters. # parameters from splunk searchbar include: # action # device # panorama # serial # vsys # user_field # ip_field # debug # Verify required args were passed to command log(debug, "Determining if required arguments are present") if 'device' not in kwargs and 'panorama' not in kwargs: common.exit_with_error( "Missing required command argument: device or panorama", 3) if 'panorama' in kwargs and 'serial' not in kwargs: common.exit_with_error( "Found 'panorama' arguments, but missing 'serial' argument", 3) # Assign defaults to fields that aren't specified action = kwargs['action'] if 'action' in kwargs else "login" vsys = kwargs['vsys'] if 'vsys' in kwargs else "vsys1" ip_field = kwargs['ip_field'] if 'ip_field' in kwargs else "src_ip" user_field = kwargs['user_field'] if 'user_field' in kwargs else "user" # Determine if device hostname or serial was provided as argument or should be pulled from entries log(debug, "Determining how firewalls should be contacted based on arguments") use_panorama = False hostname = None serial = None if "device" in kwargs: hostname = kwargs['device'] elif "panorama" in kwargs: use_panorama = True hostname = kwargs['panorama'] serial = kwargs['serial'] else: common.exit_with_error( "Missing required command argument: device or panorama", 3) log(debug, "Use Panorama: %s" % use_panorama) log(debug, "VSys: %s" % vsys) log(debug, "Hostname: %s" % hostname) if use_panorama and serial is not None: log(debug, "Device Serial: %s" % serial) # Results contains the data from the search results and settings # contains the sessionKey that we can use to talk to Splunk results, unused1, settings = splunk.Intersplunk.getOrganizedResults() # Get the sessionKey sessionKey = settings['sessionKey'] log(debug, "Begin get API key") # Get the API key from the Splunk store or from the device at hostname if no apikey is stored apikey = common.apikey(sessionKey, hostname, debug) # Create the connection to the firewall or Panorama panorama = None if use_panorama: # For Panorama, create the Panorama object, and the firewall object panorama = Panorama(hostname, api_key=apikey) firewall = Firewall(panorama=panorama, serial=serial, vsys=vsys) firewall.userid.batch_start() else: # No Panorama, so just create the firewall object firewall = Firewall(hostname, api_key=apikey, vsys=vsys) firewall.userid.batch_start() # Collect all the ip addresses and users into firewall batch requests for result in results: ## Find the user (if a user_field was specified) try: this_user = result[user_field] except KeyError as e: result[ 'status'] = "ERROR: Unable to determine user from field: %s" % user_field continue ## Find the IP try: this_ip = result[ip_field] except KeyError as e: result[ 'status'] = "ERROR: Unable to determine ip from field: %s" % ip_field ## Create a request in the batch user-id update for the firewall ## No API call to the firewall happens until all batch requests are created. if action == "login": log( debug, "Login event on firewall %s: %s - %s" % (firewall, this_ip, this_user)) firewall.userid.login(this_user, this_ip) else: log( debug, "Logout event on firewall %s: %s - %s" % (firewall, this_ip, this_user)) firewall.userid.logout(this_user, this_ip) result['status'] = "Submitted successfully" ## Make the API calls to the User-ID API of each firewall try: firewall.userid.batch_end() except pan.xapi.PanXapiError as e: common.exit_with_error(str(e)) except Exception as e: common.exit_with_error(str(e)) # output results splunk.Intersplunk.outputResults(results)