def __init__(self): self.fw = FirewallClient() self.config = self.fw.config() if not self.config: log.warning('FirewallD is not running attempting to start...') import subprocess import time subprocess.check_output( ['systemctl', 'enable', '--now', 'firewalld']) # firewall-cmd synchronously waits for FirewallD startup subprocess.check_output(['firewall-cmd', '--state']) self.fw = FirewallClient() self.config = self.fw.config()
def main(): module = AnsibleModule( argument_spec=dict( table=dict(required=False, default='filter'), chain=dict(required=True), priority=dict(required=False, default=0, type='int'), args=dict(required=True), type=dict(choices=['ipv4', 'ipv6', 'eb'], default='ipv4'), permanent=dict(type='bool', required=False, default=None), state=dict(choices=['present', 'absent'], required=True), ), supports_check_mode=True ) if not HAVE_FIREWALLD: module.fail_json(msg='firewalld and the python module are required ' 'for this module') if not FIREWALLD_RUNNING: module.fail_json(msg='firewalld is not running, and offline operations' ' are not supported yet') table = module.params['table'] chain = module.params['chain'] priority = module.params['priority'] args = module.params['args'].split(' ') address_type = module.params['type'] permanent = module.params['permanent'] state = module.params['state'] if permanent: fw = FirewallClient().config().direct() else: fw = FirewallClient() rules = fw.getRules(ipv=address_type, table=table, chain=chain) changed = False if state == 'present': if (priority, args) not in rules: fw.addRule(ipv=address_type, table=table, chain=chain, priority=priority, args=args) changed = True else: if (priority, args) in rules: fw.removeRule(ipv=address_type, table=table, chain=chain, priority=priority, args=args) changed = True result = dict(changed=changed) module.exit_json(**result)
def main(): module = AnsibleModule(argument_spec=dict( name=dict(required=True), state=dict(choices=['present', 'absent'], required=True), no_reload=dict(type='bool', default='no'), ), supports_check_mode=False) if not HAVE_FIREWALLD: module.fail_json(msg='firewalld and the python module are required ' 'for this module') if not FIREWALLD_RUNNING: module.fail_json(msg='firewalld is not running, and offline operations' ' are not supported yet') name = module.params['name'] state = module.params['state'] no_reload = module.params['no_reload'] fw = FirewallClient().config() zones = fw.getZoneNames() changed = False if state == 'present': if name not in zones: fw.addZone(name, FirewallClientZoneSettings()) changed = True else: if name in zones: z = fw.getZoneByName(name) z.remove() changed = True if changed and not no_reload: FirewallClient().reload() result = dict(changed=changed) module.exit_json(**result)
def __init__(self, rules_id, ipv4_public_addr=None, ipv4_private_addr=None): self.fw = FirewallClient() self.config = self.fw.config() self.fw_direct = self.config.direct() self.prio = 0 self.ipv = 'ipv4' self.table = 'filter' self.chain = 'FORWARD' self.rules_id = rules_id self.ipv4_public_addr = ipv4_public_addr self.ipv4_private_addr = ipv4_private_addr self.firewall_in_chain = FIREWALL_IN_NAME + str(rules_id) self.firewall_out_chain = FIREWALL_OUT_NAME + str(rules_id)
def __init__(self): try: from firewall.client import FirewallClient self._fw = FirewallClient() if not self._fw.connected: debugprint("FirewallD seems to be installed but not running") self._fw = None self._zone = None self.running = False return zone_name = self._get_active_zone() if zone_name: self._zone = self._fw.config().getZoneByName(zone_name) else: self._zone = None self.running = True debugprint("Using /org/fedoraproject/FirewallD1") except (ImportError, dbus.exceptions.DBusException): self._fw = None self._zone = None self.running = False
- firewalld: port=8081/tcp permanent=true state=disabled - firewalld: port=161-162/udp permanent=true state=enabled - firewalld: zone=dmz service=http permanent=true state=enabled - firewalld: rich_rule='rule service name="ftp" audit limit value="1/m" accept' permanent=true state=enabled - firewalld: source='192.168.1.0/24' zone=internal state=enabled ''' import os import re try: import firewall.config FW_VERSION = firewall.config.VERSION from firewall.client import FirewallClient fw = FirewallClient() HAS_FIREWALLD = True except ImportError: HAS_FIREWALLD = False ################ # port handling # def get_port_enabled(zone, port_proto): if port_proto in fw.getPorts(zone): return True else: return False
def main(): global module ## make module global so we don't have to pass it to action_handler every ## function call global module module = AnsibleModule(argument_spec=dict( service=dict(required=False, default=None), port=dict(required=False, default=None), rich_rule=dict(required=False, default=None), zone=dict(required=False, default=None), immediate=dict(type='bool', default=False), source=dict(required=False, default=None), permanent=dict(type='bool', required=False, default=None), state=dict(choices=['enabled', 'disabled'], required=True), timeout=dict(type='int', required=False, default=0), interface=dict(required=False, default=None), masquerade=dict(required=False, default=None), offline=dict(type='bool', required=False, default=None), ), supports_check_mode=True) ## Handle running (online) daemon vs non-running (offline) daemon global fw global fw_offline global Rich_Rule global FirewallClientZoneSettings ## Imports try: import firewall.config FW_VERSION = firewall.config.VERSION from firewall.client import Rich_Rule from firewall.client import FirewallClient fw = None fw_offline = False try: fw = FirewallClient() fw.getDefaultZone() except AttributeError: ## Firewalld is not currently running, permanent-only operations ## Import other required parts of the firewalld API ## ## NOTE: ## online and offline operations do not share a common firewalld API from firewall.core.fw_test import Firewall_test from firewall.client import FirewallClientZoneSettings fw = Firewall_test() fw.start() fw_offline = True except ImportError: ## Make python 2.4 shippable ci tests happy e = sys.exc_info()[1] module.fail_json( msg= 'firewalld and its python 2 module are required for this module, version 2.0.11 or newer required ' '(3.0.9 or newer for offline operations) \n %s' % e) if fw_offline: ## Pre-run version checking if FW_VERSION < "0.3.9": module.fail_json( msg= 'unsupported version of firewalld, offline operations require >= 3.0.9' ) else: ## Pre-run version checking if FW_VERSION < "0.2.11": module.fail_json( msg='unsupported version of firewalld, requires >= 2.0.11') ## Check for firewalld running try: if fw.connected is False: module.fail_json( msg= 'firewalld service must be running, or try with offline=true' ) except AttributeError: module.fail_json(msg="firewalld connection can't be established,\ installed version (%s) likely too old. Requires firewalld >= 2.0.11" % FW_VERSION) ## Verify required params are provided if module.params['source'] is None and module.params['permanent'] is None: module.fail_json(msg='permanent is a required parameter') if module.params['interface'] is not None and module.params['zone'] is None: module.fail(msg='zone is a required parameter') if module.params['immediate'] and fw_offline: module.fail( msg= 'firewall is not currently running, unable to perform immediate actions without a running firewall daemon' ) ## Global Vars changed = False msgs = [] service = module.params['service'] rich_rule = module.params['rich_rule'] source = module.params['source'] if module.params['port'] is not None: port, protocol = module.params['port'].split('/') if protocol is None: module.fail_json(msg='improper port format (missing protocol?)') else: port = None if module.params['zone'] is not None: zone = module.params['zone'] else: if fw_offline: zone = fw.get_default_zone() else: zone = fw.getDefaultZone() permanent = module.params['permanent'] desired_state = module.params['state'] immediate = module.params['immediate'] timeout = module.params['timeout'] interface = module.params['interface'] masquerade = module.params['masquerade'] modification_count = 0 if service is not None: modification_count += 1 if port is not None: modification_count += 1 if rich_rule is not None: modification_count += 1 if interface is not None: modification_count += 1 if masquerade is not None: modification_count += 1 if modification_count > 1: module.fail_json( msg= 'can only operate on port, service, rich_rule or interface at once' ) if service is not None: if immediate and permanent: is_enabled_permanent = action_handler( get_service_enabled_permanent, (zone, service)) is_enabled_immediate = action_handler(get_service_enabled, (zone, service)) msgs.append('Permanent and Non-Permanent(immediate) operation') if desired_state == "enabled": if not is_enabled_permanent or not is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if not is_enabled_permanent: action_handler(set_service_enabled_permanent, (zone, service)) changed = True if not is_enabled_immediate: action_handler(set_service_enabled, (zone, service, timeout)) changed = True elif desired_state == "disabled": if is_enabled_permanent or is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if is_enabled_permanent: action_handler(set_service_disabled_permanent, (zone, service)) changed = True if is_enabled_immediate: action_handler(set_service_disabled, (zone, service)) changed = True elif permanent and not immediate: is_enabled = action_handler(get_service_enabled_permanent, (zone, service)) msgs.append('Permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_service_enabled_permanent, (zone, service)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_service_disabled_permanent, (zone, service)) changed = True elif immediate and not permanent: is_enabled = action_handler(get_service_enabled, (zone, service)) msgs.append('Non-permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_service_enabled, (zone, service, timeout)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_service_disabled, (zone, service)) changed = True if changed is True: msgs.append("Changed service %s to %s" % (service, desired_state)) # FIXME - source type does not handle non-permanent mode, this was an # oversight in the past. if source is not None: is_enabled = action_handler(get_source, (zone, source)) if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(add_source, (zone, source)) changed = True msgs.append("Added %s to zone %s" % (source, zone)) elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(remove_source, (zone, source)) changed = True msgs.append("Removed %s from zone %s" % (source, zone)) if port is not None: if immediate and permanent: is_enabled_permanent = action_handler(get_port_enabled_permanent, (zone, [port, protocol])) is_enabled_immediate = action_handler(get_port_enabled, (zone, [port, protocol])) msgs.append('Permanent and Non-Permanent(immediate) operation') if desired_state == "enabled": if not is_enabled_permanent or not is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if not is_enabled_permanent: action_handler(set_port_enabled_permanent, (zone, port, protocol)) changed = True if not is_enabled_immediate: action_handler(set_port_enabled, (zone, port, protocol, timeout)) changed = True elif desired_state == "disabled": if is_enabled_permanent or is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if is_enabled_permanent: action_handler(set_port_disabled_permanent, (zone, port, protocol)) changed = True if is_enabled_immediate: action_handler(set_port_disabled, (zone, port, protocol)) changed = True elif permanent and not immediate: is_enabled = action_handler(get_port_enabled_permanent, (zone, [port, protocol])) msgs.append('Permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_port_enabled_permanent, (zone, port, protocol)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_port_disabled_permanent, (zone, port, protocol)) changed = True if immediate and not permanent: is_enabled = action_handler(get_port_enabled, (zone, [port, protocol])) msgs.append('Non-permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_port_enabled, (zone, port, protocol, timeout)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_port_disabled, (zone, port, protocol)) changed = True if changed is True: msgs.append("Changed port %s to %s" % ("%s/%s" % (port, protocol), \ desired_state)) if rich_rule is not None: if immediate and permanent: is_enabled_permanent = action_handler( get_rich_rule_enabled_permanent, (zone, rich_rule)) is_enabled_immediate = action_handler(get_rich_rule_enabled, (zone, rich_rule)) msgs.append('Permanent and Non-Permanent(immediate) operation') if desired_state == "enabled": if not is_enabled_permanent or not is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if not is_enabled_permanent: action_handler(set_rich_rule_enabled_permanent, (zone, rich_rule)) changed = True if not is_enabled_immediate: action_handler(set_rich_rule_enabled, (zone, rich_rule, timeout)) changed = True elif desired_state == "disabled": if is_enabled_permanent or is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if is_enabled_permanent: action_handler(set_rich_rule_disabled_permanent, (zone, rich_rule)) changed = True if is_enabled_immediate: action_handler(set_rich_rule_disabled, (zone, rich_rule)) changed = True if permanent and not immediate: is_enabled = action_handler(get_rich_rule_enabled_permanent, (zone, rich_rule)) msgs.append('Permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_rich_rule_enabled_permanent, (zone, rich_rule)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_rich_rule_disabled_permanent, (zone, rich_rule)) changed = True if immediate and not permanent: is_enabled = action_handler(get_rich_rule_enabled, (zone, rich_rule)) msgs.append('Non-permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_rich_rule_enabled, (zone, rich_rule, timeout)) changed = True elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_rich_rule_disabled, (zone, rich_rule)) changed = True if changed is True: msgs.append("Changed rich_rule %s to %s" % (rich_rule, desired_state)) if interface is not None: if immediate and permanent: is_enabled_permanent = action_handler(get_interface_permanent, (zone, interface)) is_enabled_immediate = action_handler(get_interface, (zone, interface)) msgs.append('Permanent and Non-Permanent(immediate) operation') if desired_state == "enabled": if not is_enabled_permanent or not is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if not is_enabled_permanent: change_zone_of_interface_permanent(zone, interface) changed = True if not is_enabled_immediate: change_zone_of_interface(zone, interface) changed = True if changed: msgs.append("Changed %s to zone %s" % (interface, zone)) elif desired_state == "disabled": if is_enabled_permanent or is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if is_enabled_permanent: remove_interface_permanent(zone, interface) changed = True if is_enabled_immediate: remove_interface(zone, interface) changed = True if changed: msgs.append("Removed %s from zone %s" % (interface, zone)) elif permanent and not immediate: is_enabled = action_handler(get_interface_permanent, (zone, interface)) msgs.append('Permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) change_zone_of_interface_permanent(zone, interface) changed = True msgs.append("Changed %s to zone %s" % (interface, zone)) elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) remove_interface_permanent(zone, interface) changed = True msgs.append("Removed %s from zone %s" % (interface, zone)) elif immediate and not permanent: is_enabled = action_handler(get_interface, (zone, interface)) msgs.append('Non-permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) change_zone_of_interface(zone, interface) changed = True msgs.append("Changed %s to zone %s" % (interface, zone)) elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) remove_interface(zone, interface) changed = True msgs.append("Removed %s from zone %s" % (interface, zone)) if masquerade is not None: if immediate and permanent: is_enabled_permanent = action_handler( get_masquerade_enabled_permanent, (zone, )) is_enabled_immediate = action_handler(get_masquerade_enabled, (zone, )) msgs.append('Permanent and Non-Permanent(immediate) operation') if desired_state == "enabled": if not is_enabled_permanent or not is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if not is_enabled_permanent: action_handler(set_masquerade_permanent, (zone, True)) changed = True if not is_enabled_immediate: action_handler(set_masquerade_enabled, (zone, )) changed = True if changed: msgs.append("Added masquerade to zone %s" % (zone)) elif desired_state == "disabled": if is_enabled_permanent or is_enabled_immediate: if module.check_mode: module.exit_json(changed=True) if is_enabled_permanent: action_handler(set_masquerade_permanent, (zone, False)) changed = True if is_enabled_immediate: action_handler(set_masquerade_disabled, (zone, )) changed = True if changed: msgs.append("Removed masquerade from zone %s" % (zone)) elif permanent and not immediate: is_enabled = action_handler(get_masquerade_enabled_permanent, (zone, )) msgs.append('Permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_masquerade_permanent, (zone, True)) changed = True msgs.append("Added masquerade to zone %s" % (zone)) elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_masquerade_permanent, (zone, False)) changed = True msgs.append("Removed masquerade from zone %s" % (zone)) elif immediate and not permanent: is_enabled = action_handler(get_masquerade_enabled, (zone, )) msgs.append('Non-permanent operation') if desired_state == "enabled": if is_enabled is False: if module.check_mode: module.exit_json(changed=True) action_handler(set_masquerade_enabled, (zone)) changed = True msgs.append("Added masquerade to zone %s" % (zone)) elif desired_state == "disabled": if is_enabled is True: if module.check_mode: module.exit_json(changed=True) action_handler(set_masquerade_disabled, (zone)) changed = True msgs.append("Removed masquerade from zone %s" % (zone)) if fw_offline: msgs.append("(offline operation: only on-disk configs were altered)") module.exit_json(changed=changed, msg=', '.join(msgs))
def setUp(self): unittest.TestCase.setUp(self) self.fw = FirewallClient()
def fw(retries=6): ''' firewalld interface is nice, but due to DBUS, it is a great field for various errors and hickups. We then try to get a viable connexion, but also be really smart on establishing one ''' # after 2 success full calls to the firewall # we assume it is correctly configured if _cache.get('f') is not None: if _cache.get('f_call', 0) < 2: try: if _cache['f'].getZones() is None: time.sleep(0.05) assert _cache['f'].getZones() is not None _cache.setdefault('f_call', 0) _cache['f_call'] += 1 except (Exception, ): remove_client() if _cache.get('f') is None: state = 'notready' ttl = time.time() + TIMEOUT attempt = 0 established = False loggued = False while time.time() < ttl: # if we have an instance, we have to wait until the firewall # is in the running state try: attempt += 1 remove_client() _cache['f'] = FirewallClient() state = _cache['f'].get_property('state') # if we have first contacted the firewall without being # in running mode, there is a great chance for the dbus # interface to be bugged. # So there are two cases, # - we assume that the connexion is established only if we # get directly a running state. # - In other cases, we assume the firewall to be ready for # commands only on the second successful connection # on the dbus interface. if state in RUNNINGS: stop = False if attempt == 1: stop = True elif not established: established = True else: stop = True if stop: log.info('firewalld seems now ready') break continue else: established = False time.sleep(0.4) except (Exception, ): log.error(traceback.format_exc()) state = 'unknown' # DBUS doent like at all retry spam time.sleep(5) if not loggued: log.error('firewalld is not ready yet,' ' waiting ({0})'.format(state)) loggued = True if _cache.get('f') is None: if not retries: raise IOError('Cant contact firewalld daemon interface') else: return fw(retries - 1) return _cache['f']
def uninstallFirewall(self): """uninstall firewall""" log.debug1("%s.uninstallFirewall()", self._log_prefix) # Removes the settings that have been added in the installFirewall call # get applied changes from installFirewall call if "firewall-changes" in self._settings: fw_changes = self._settings["firewall-changes"] else: # fallback if there was a severe error in deploy before or while # installing the firewall fw_changes = { } # only continue if there are any changes if len(fw_changes) < 1: return # create firewall client fw = FirewallClient() # for all zones for zone in fw_changes: z_perm = fw.config().getZoneByName(zone).getSettings() if "services" in fw_changes[zone]: services = fw_changes[zone]["services"] for service in services: if "runtime" in services[service]: try: fw.removeService(zone, service) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "permanent" in services[service]: try: z_perm.removeService(service) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "ports" in fw_changes[zone]: ports = fw_changes[zone]["ports"] for port_proto in ports: port, proto = port_proto.split("/") if "runtime" in ports[port_proto]: try: fw.removePort(zone, port, proto) except Exception as e: if not "NOT_ENABLED" in str(e): raise if "permanent" in ports[port_proto]: try: z_perm.removePort(port, proto) except Exception as e: if not "NOT_ENABLED" in str(e): raise fw.config().getZoneByName(zone).update(z_perm) # clear fw_changes and save it in _settings fw_changes.clear() self._settings["firewall-changes"] = fw_changes self._settings.write()
def installFirewall(self): """install firewall""" log.debug1("%s.installFirewall()", self._log_prefix) # are there any firewall settings to apply? if len(self._settings["firewall"]["services"]) + \ len(self._settings["firewall"]["ports"]) < 1: return # create firewall client fw = FirewallClient() log.debug2("TRACE: Firewall client created") # Make sure firewalld is running by getting the # default zone try: default_zone = fw.getDefaultZone() except DBusException: # firewalld is not running log.error("Firewalld is not running or rolekit cannot access it") raise # save changes to the firewall try: fw_changes = self._settings["firewall-changes"] except KeyError: fw_changes = { } log.debug2("TRACE: Checking for zones: {}".format(self._settings)) try: zones = self._settings["firewall_zones"] except KeyError: zones = [] # if firewall_zones setting is empty, use default zone if len(zones) < 1: zones = [ default_zone ] log.debug2("TRACE: default zone {}".format(zones[0])) for zone in zones: log.debug2("TRACE: Processing zone {0}".format(zone)) # get permanent zone settings, run-time settings do not need a # special treatment z_perm = fw.config().getZoneByName(zone).getSettings() for service in self._settings["firewall"]["services"]: try: fw.addService(zone, service, 0) except Exception as e: if not "ALREADY_ENABLED" in str(e): raise else: fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("runtime") if not z_perm.queryService(service): z_perm.addService(service) fw_changes.setdefault(zone, {}).setdefault("services", {}).setdefault(service, []).append("permanent") for port_proto in self._settings["firewall"]["ports"]: port, proto = port_proto.split("/") try: fw.addPort(zone, port, proto, 0) except Exception as e: if not "ALREADY_ENABLED" in str(e): raise else: fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("runtime") if not z_perm.queryPort(port, proto): z_perm.addPort(port, proto) fw_changes.setdefault(zone, {}).setdefault("ports", {}).setdefault(port_proto, []).append("permanent") fw.config().getZoneByName(zone).update(z_perm) self._settings["firewall-changes"] = fw_changes self._settings.write()
def main(): module = AnsibleModule( argument_spec=dict( service=dict(required=False, type="list", default=[]), port=dict(required=False, type="list", default=[]), trust=dict(required=False, type="list", default=[]), trust_by_mac=dict(required=False, type="list", default=[]), masq=dict(required=False, type="list", default=[]), masq_by_mac=dict(required=False, type="list", default=[]), forward_port=dict(required=False, type="list", default=[]), forward_port_by_mac=dict(required=False, type="list", default=[]), zone=dict(required=False, type="str", default=None), state=dict(choices=["enabled", "disabled"], required=True), ), required_one_of=([ "service", "port", "trust", "trust_by_mac", "masq", "masq_by_mac", "forward_prot", ], ), supports_check_mode=True, ) if not HAS_FIREWALLD and not HAS_SYSTEM_CONFIG_FIREWALL: module.fail_json(msg="No firewall backend could be imported.") service = module.params["service"] port = [] for port_proto in module.params["port"]: _port, _protocol = port_proto.split("/") if _protocol is None: module.fail_json(msg="improper port format (missing protocol?)") port.append((_port, _protocol)) trust = module.params["trust"] trust_by_mac = [] for item in module.params["trust_by_mac"]: _interface = get_device_for_mac(item) if _interface is None: module.fail_json(msg="MAC address not found %s" % item) trust_by_mac.append(_interface) masq = module.params["masq"] masq_by_mac = [] for item in module.params["masq_by_mac"]: _interface = get_device_for_mac(item) if _interface is None: module.fail_json(msg="MAC address not found %s" % item) masq_by_mac.append(_interface) forward_port = [] for item in module.params["forward_port"]: args = item.split(";") if len(args) == 4: _interface, __port, _to_port, _to_addr = args elif len(args) == 3: _interface = "" __port, _to_port, _to_addr = args else: module.fail_json(msg="improper forward_port format: %s" % item) _port, _protocol = __port.split("/") if _protocol is None: module.fail_json( msg="improper forward port format (missing protocol?)") if _to_port == "": _to_port = None if _to_addr == "": _to_addr = None forward_port.append((_interface, _port, _protocol, _to_port, _to_addr)) forward_port_by_mac = [] for item in module.params["forward_port_by_mac"]: args = item.split(";") if len(args) != 4: module.fail_json(msg="improper forward_port_by_mac format") _mac_addr, __port, _to_port, _to_addr = args _port, _protocol = __port.split("/") if _protocol is None: module.fail_json( msg="improper forward_port_by_mac format (missing protocol?)") if _to_port == "": _to_port = None if _to_addr == "": _to_addr = None _interface = get_device_for_mac(_mac_addr) if _interface is None: module.fail_json(msg="MAC address not found %s" % _mac_addr) forward_port_by_mac.append( (_interface, _port, _protocol, _to_port, _to_addr)) zone = module.params["zone"] if HAS_SYSTEM_CONFIG_FIREWALL and zone is not None: module.fail_json( msg="Zone can not be used with system-config-firewall/lokkit.") desired_state = module.params["state"] if HAS_FIREWALLD: fw = FirewallClient() def exception_handler(exception_message): module.fail_json(msg=exception_message) fw.setExceptionHandler(exception_handler) if not fw.connected: module.fail_json(msg="firewalld service must be running") trusted_zone = "trusted" external_zone = "external" if zone is not None: if zone not in fw.getZones(): module.fail_json(msg="Runtime zone '%s' does not exist." % zone) if zone not in fw.config().getZoneNames(): module.fail_json(msg="Permanent zone '%s' does not exist." % zone) else: zone = fw.getDefaultZone() fw_zone = fw.config().getZoneByName(zone) fw_settings = fw_zone.getSettings() changed = False changed_zones = {} # service for item in service: if desired_state == "enabled": if not fw.queryService(zone, item): fw.addService(zone, item) changed = True if not fw_settings.queryService(item): fw_settings.addService(item) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if fw.queryService(zone, item): fw.removeService(zone, item) if fw_settings.queryService(item): fw_settings.removeService(item) changed = True changed_zones[fw_zone] = fw_settings # port for _port, _protocol in port: if desired_state == "enabled": if not fw.queryPort(zone, _port, _protocol): fw.addPort(zone, _port, _protocol) changed = True if not fw_settings.queryPort(_port, _protocol): fw_settings.addPort(_port, _protocol) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if fw.queryPort(zone, _port, _protocol): fw.removePort(zone, _port, _protocol) changed = True if fw_settings.queryPort(_port, _protocol): fw_settings.removePort(_port, _protocol) changed = True changed_zones[fw_zone] = fw_settings # trust, trust_by_mac if len(trust) > 0 or len(trust_by_mac) > 0: items = trust if len(trust_by_mac) > 0: items.extend(trust_by_mac) if zone != trusted_zone: _fw_zone = fw.config().getZoneByName(trusted_zone) if _fw_zone in changed_zones: _fw_settings = changed_zones[_fw_zone] else: _fw_settings = _fw_zone.getSettings() else: _fw_zone = fw_zone _fw_settings = fw_settings for item in items: if desired_state == "enabled": if try_set_zone_of_interface(trusted_zone, item): changed = True else: if not fw.queryInterface(trusted_zone, item): fw.changeZoneOfInterface(trusted_zone, item) changed = True if not _fw_settings.queryInterface(item): _fw_settings.addInterface(item) changed = True changed_zones[_fw_zone] = _fw_settings elif desired_state == "disabled": if try_set_zone_of_interface("", item): if module.check_mode: module.exit_json(changed=True) else: if fw.queryInterface(trusted_zone, item): fw.removeInterface(trusted_zone, item) changed = True if _fw_settings.queryInterface(item): _fw_settings.removeInterface(item) changed = True changed_zones[_fw_zone] = _fw_settings # masq, masq_by_mac if len(masq) > 0 or len(masq_by_mac) > 0: items = masq if len(masq_by_mac) > 0: items.extend(masq_by_mac) if zone != external_zone: _fw_zone = fw.config().getZoneByName(external_zone) if _fw_zone in changed_zones: _fw_settings = changed_zones[_fw_zone] else: _fw_settings = _fw_zone.getSettings() else: _fw_zone = fw_zone _fw_settings = fw_settings for item in items: if desired_state == "enabled": if try_set_zone_of_interface(external_zone, item): changed = True else: if not fw.queryInterface(external_zone, item): fw.changeZoneOfInterface(external_zone, item) changed = True if not _fw_settings.queryInterface(item): _fw_settings.addInterface(item) changed = True changed_zones[_fw_zone] = _fw_settings elif desired_state == "disabled": if try_set_zone_of_interface("", item): if module.check_mode: module.exit_json(changed=True) else: if fw.queryInterface(external_zone, item): fw.removeInterface(external_zone, item) changed = True if _fw_settings.queryInterface(item): _fw_settings.removeInterface(item) changed = True changed_zones[_fw_zone] = _fw_settings # forward_port, forward_port_by_mac if len(forward_port) > 0 or len(forward_port_by_mac) > 0: items = forward_port if len(forward_port_by_mac) > 0: items.extend(forward_port_by_mac) for _interface, _port, _protocol, _to_port, _to_addr in items: if _interface != "": _zone = fw.getZoneOfInterface(_interface) else: _zone = zone if _zone != "" and _zone != zone: _fw_zone = fw.config().getZoneByName(_zone) if _fw_zone in changed_zones: _fw_settings = changed_zones[_fw_zone] else: _fw_settings = _fw_zone.getSettings() else: _fw_zone = fw_zone _fw_settings = fw_settings if desired_state == "enabled": if not fw.queryForwardPort(_zone, _port, _protocol, _to_port, _to_addr): fw.addForwardPort(_zone, _port, _protocol, _to_port, _to_addr) changed = True if not _fw_settings.queryForwardPort( _port, _protocol, _to_port, _to_addr): _fw_settings.addForwardPort(_port, _protocol, _to_port, _to_addr) changed = True changed_zones[_fw_zone] = _fw_settings elif desired_state == "disabled": if fw.queryForwardPort(_zone, _port, _protocol, _to_port, _to_addr): fw.removeForwardPort(_zone, _port, _protocol, _to_port, _to_addr) changed = True if _fw_settings.queryForwardPort(_port, _protocol, _to_port, _to_addr): _fw_settings.removeForwardPort(_port, _protocol, _to_port, _to_addr) changed = True changed_zones[_fw_zone] = _fw_settings # apply changes if changed: for _zone in changed_zones: _zone.update(changed_zones[_zone]) module.exit_json(changed=True) elif HAS_SYSTEM_CONFIG_FIREWALL: (config, old_config, _) = fw_lokkit.loadConfig(args=[], dbus_parser=True) changed = False # service for item in service: if config.services is None: config.services = [] if desired_state == "enabled": if item not in config.services: config.services.append(item) changed = True elif desired_state == "disabled": if item in config.services: config.services.remove(item) changed = True # port for _port, _protocol in port: if config.ports is None: config.ports = [] _range = getPortRange(_port) if _range < 0: module.fail_json(msg="invalid port definition %s" % _port) elif _range is None: module.fail_json(msg="port _range is not unique.") elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg="invalid port range %s" % _port) port_proto = (_range, _protocol) if desired_state == "enabled": if port_proto not in config.ports: config.ports.append(port_proto) changed = True elif desired_state == "disabled": if port_proto in config.ports: config.ports.remove(port_proto) changed = True # trust, trust_by_mac if len(trust) > 0 or len(trust_by_mac) > 0: if config.trust is None: config.trust = [] items = trust if len(trust_by_mac) > 0: items.extend(trust_by_mac) for item in items: if desired_state == "enabled": if item not in config.trust: config.trust.append(item) changed = True elif desired_state == "disabled": if item in config.trust: config.trust.remove(item) changed = True # masq, masq_by_mac if len(masq) > 0 or len(masq_by_mac) > 0: if config.masq is None: config.masq = [] items = masq if len(masq_by_mac) > 0: items.extend(masq_by_mac) for item in items: if desired_state == "enabled": if item not in config.masq: config.masq.append(item) changed = True elif desired_state == "disabled": if item in config.masq: config.masq.remove(item) changed = True # forward_port, forward_port_by_mac if len(forward_port) > 0 or len(forward_port_by_mac) > 0: if config.forward_port is None: config.forward_port = [] items = forward_port if len(forward_port_by_mac) > 0: items.extend(forward_port_by_mac) for _interface, _port, _protocol, _to_port, _to_addr in items: _range = getPortRange(_port) if _range < 0: module.fail_json(msg="invalid port definition") elif _range is None: module.fail_json(msg="port _range is not unique.") elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg="invalid port range") fwd_port = { "if": _interface, "port": _range, "proto": _protocol } if _to_port is not None: _range = getPortRange(_to_port) if _range < 0: module.fail_json(msg="invalid port definition %s" % _to_port) elif _range is None: module.fail_json(msg="port _range is not unique.") elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg="invalid port range") fwd_port["toport"] = _range if _to_addr is not None: fwd_port["toaddr"] = _to_addr if desired_state == "enabled": if fwd_port not in config.forward_port: config.forward_port.append(fwd_port) changed = True elif desired_state == "disabled": if fwd_port in config.forward_port: config.forward_port.remove(fwd_port) changed = True # apply changes if changed: fw_lokkit.updateFirewall(config, old_config) if module.check_mode: module.exit_json(changed=True) else: module.fail_json(msg="No firewalld and system-config-firewall") module.exit_json(changed=False)
def main(): module = AnsibleModule(argument_spec=dict( service=dict(required=False, type='list', default=[]), port=dict(required=False, type='list', default=[]), trust=dict(required=False, type='list', default=[]), trust_by_mac=dict(required=False, type='list', default=[]), masq=dict(required=False, type='list', default=[]), masq_by_mac=dict(required=False, type='list', default=[]), forward_port=dict(required=False, type='list', default=[]), forward_port_by_mac=dict(required=False, type='list', default=[]), state=dict(choices=['enabled', 'disabled'], required=True), ), required_one_of=([ 'service', 'port', 'trust', 'trust_by_mac', 'masq', 'masq_by_mac', 'forward_prot' ], ), supports_check_mode=True) if not HAS_FIREWALLD and not HAS_SYSTEM_CONFIG_FIREWALL: module.fail_json(msg='No firewall backend could be imported.') service = module.params['service'] port = [] for port_proto in module.params['port']: _port, _protocol = port_proto.split('/') if _protocol is None: module.fail_json(msg='improper port format (missing protocol?)') port.append((_port, _protocol)) trust = module.params['trust'] trust_by_mac = [] for item in module.params['trust_by_mac']: _interface = get_device_for_mac(item) if _interface is None: module.fail_json(msg='MAC address not found %s' % item) trust_by_mac.append(_interface) masq = module.params['masq'] masq_by_mac = [] for item in module.params['masq_by_mac']: _interface = get_device_for_mac(item) if _interface is None: module.fail_json(msg='MAC address not found %s' % item) masq_by_mac.append(_interface) forward_port = [] for item in module.params['forward_port']: args = item.split(";") if len(args) != 4: module.fail_json(msg='improper forward_port format: %s' % item) _interface, __port, _to_port, _to_addr = args _port, _protocol = __port.split('/') if _protocol is None: module.fail_json(msg='improper port format (missing protocol?)') if _to_port == "": _to_port = None if _to_addr == "": _to_addr = None forward_port.append((_interface, _port, _protocol, _to_port, _to_addr)) forward_port_by_mac = [] for item in module.params['forward_port_by_mac']: args = item.split(";") if len(args) != 4: module.fail_json(msg='improper forward_port_by_mac format') _mac_addr, __port, _to_port, _to_addr = args _port, _protocol = __port.split('/') if _protocol is None: module.fail_json(msg='improper port format (missing protocol?)') if _to_port == "": _to_port = None if _to_addr == "": _to_addr = None _interface = get_device_for_mac(_mac_addr) if _interface is None: module.fail_json(msg='MAC address not found %s' % _mac_addr) forward_port_by_mac.append( (_interface, _port, _protocol, _to_port, _to_addr)) desired_state = module.params['state'] if HAS_FIREWALLD: fw = FirewallClient() def exception_handler(exception_message): module.fail_json(msg=exception_message) fw.setExceptionHandler(exception_handler) if not fw.connected: module.fail_json(msg='firewalld service must be running') trusted_zone = "trusted" external_zone = "external" default_zone = fw.getDefaultZone() fw_zone = fw.config().getZoneByName(default_zone) fw_settings = fw_zone.getSettings() changed = False changed_zones = {} # service for item in service: if desired_state == "enabled": if not fw.queryService(default_zone, item): fw.addService(default_zone, item) changed = True if not fw_settings.queryService(item): fw_settings.addService(item) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if fw.queryService(default_zone, item): fw.removeService(default_zone, item) if fw_settings.queryService(item): fw_settings.removeService(item) changed = True changed_zones[fw_zone] = fw_settings # port for _port, _protocol in port: if desired_state == "enabled": if not fw.queryPort(default_zone, _port, _protocol): fw.addPort(default_zone, _port, _protocol) changed = True if not fw_settings.queryPort(_port, _protocol): fw_settings.addPort(_port, _protocol) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if fw.queryPort(default_zone, _port, _protocol): fw.removePort(default_zone, _port, _protocol) changed = True if fw_settings.queryPort(_port, _protocol): fw_settings.removePort(_port, _protocol) changed = True changed_zones[fw_zone] = fw_settings # trust, trust_by_mac if len(trust) > 0 or len(trust_by_mac) > 0: items = trust if len(trust_by_mac) > 0: items.extend(trust_by_mac) if default_zone != trusted_zone: fw_zone = fw.config().getZoneByName(trusted_zone) fw_settings = fw_zone.getSettings() for item in items: if desired_state == "enabled": if try_set_zone_of_interface(trusted_zone, item): changed = True else: if not fw.queryInterface(trusted_zone, item): fw.changeZoneOfInterface(trusted_zone, item) changed = True if not fw_settings.queryInterface(item): fw_settings.addInterface(item) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if try_set_zone_of_interface("", item): if module.check_mode: module.exit_json(changed=True) else: if fw.queryInterface(trusted_zone, item): fw.removeInterface(trusted_zone, item) changed = True if fw_settings.queryInterface(item): fw_settings.removeInterface(item) changed = True changed_zones[fw_zone] = fw_settings # masq, masq_by_mac if len(masq) > 0 or len(masq_by_mac) > 0: items = masq if len(masq_by_mac) > 0: items.extend(masq_by_mac) if default_zone != external_zone: fw_zone = fw.config().getZoneByName(external_zone) fw_settings = fw_zone.getSettings() for item in items: if desired_state == "enabled": if try_set_zone_of_interface(external_zone, item): changed = True else: if not fw.queryInterface(external_zone, item): fw.changeZoneOfInterface(external_zone, item) changed = True if not fw_settings.queryInterface(item): fw_settings.addInterface(item) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if try_set_zone_of_interface("", item): if module.check_mode: module.exit_json(changed=True) else: if fw.queryInterface(external_zone, item): fw.removeInterface(external_zone, item) changed = True if fw_settings.queryInterface(item): fw_settings.removeInterface(item) changed = True changed_zones[fw_zone] = fw_settings # forward_port, forward_port_by_mac if len(forward_port) > 0 or len(forward_port_by_mac) > 0: items = forward_port if len(forward_port_by_mac) > 0: items.extend(forward_port_by_mac) for _interface, _port, _protocol, _to_port, _to_addr in items: if _interface != "": _zone = fw.getZoneOfInterface(_interface) if _zone != "" and _zone != default_zone: fw_zone = fw.config().getZoneByName(_zone) fw_settings = fw_zone.getSettings() if desired_state == "enabled": if not fw.queryForwardPort(_zone, _port, _protocol, _to_port, _to_addr): fw.addForwardPort(_zone, _port, _protocol, _to_port, _to_addr) changed = True if not fw_settings.queryForwardPort( _port, _protocol, _to_port, _to_addr): fw_settings.addForwardPort(_port, _protocol, _to_port, _to_addr) changed = True changed_zones[fw_zone] = fw_settings elif desired_state == "disabled": if fw.queryForwardPort(_zone, _port, _protocol, _to_port, _to_addr): fw.removeForwardPort(_zone, _port, _protocol, _to_port, _to_addr) changed = True if fw_settings.queryForwardPort(_port, _protocol, _to_port, _to_addr): fw_settings.removeForwardPort(_port, _protocol, _to_port, _to_addr) changed = True changed_zones[fw_zone] = fw_settings # apply changes if changed: for _zone in changed_zones: _zone.update(changed_zones[_zone]) if module.check_mode: module.exit_json(changed=True) elif HAS_SYSTEM_CONFIG_FIREWALL: (config, old_config, _) = fw_lokkit.loadConfig(args=[], dbus_parser=True) changed = False # service for item in service: if config.services is None: config.services = [] if desired_state == "enabled": if item not in config.services: config.services.append(item) changed = True elif desired_state == "disabled": if item in config.services: config.services.remove(item) changed = True # port for _port, _protocol in port: if config.ports is None: config.ports = [] _range = getPortRange(_port) if _range < 0: module.fail_json(msg='invalid port definition %s' % _port) elif _range is None: module.fail_json(msg='port _range is not unique.') elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg='invalid port range %s' % _port) port_proto = (_range, _protocol) if desired_state == "enabled": if port_proto not in config.ports: config.ports.append(port_proto) changed = True elif desired_state == "disabled": if port_proto in config.ports: config.ports.remove(port_proto) changed = True # trust, trust_by_mac if len(trust) > 0 or len(trust_by_mac) > 0: if config.trust is None: config.trust = [] items = trust if len(trust_by_mac) > 0: items.extend(trust_by_mac) for item in items: if desired_state == "enabled": if item not in config.trust: config.trust.append(item) changed = True elif desired_state == "disabled": if item in config.trust: config.trust.remove(item) changed = True # masq, masq_by_mac if len(masq) > 0 or len(masq_by_mac) > 0: if config.masq is None: config.masq = [] items = masq if len(masq_by_mac) > 0: items.extend(masq_by_mac) for item in items: if desired_state == "enabled": if item not in config.masq: config.masq.append(item) changed = True elif desired_state == "disabled": if item in config.masq: config.masq.remove(item) changed = True # forward_port, forward_port_by_mac if len(forward_port) > 0 or len(forward_port_by_mac) > 0: if config.forward_port is None: config.forward_port = [] items = forward_port if len(forward_port_by_mac) > 0: items.extend(forward_port_by_mac) for _interface, _port, _protocol, _to_port, _to_addr in items: _range = getPortRange(_port) if _range < 0: module.fail_json(msg='invalid port definition') elif _range is None: module.fail_json(msg='port _range is not unique.') elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg='invalid port range') fwd_port = { "if": _interface, "port": _range, "proto": _protocol } if _to_port is not None: _range = getPortRange(_to_port) if _range < 0: module.fail_json(msg='invalid port definition %s' % \ _to_port) elif _range is None: module.fail_json(msg='port _range is not unique.') elif len(_range) == 2 and _range[0] >= _range[1]: module.fail_json(msg='invalid port range') fwd_port["toport"] = _range if _to_addr is not None: fwd_port["toaddr"] = _to_addr if desired_state == "enabled": if fwd_port not in config.forward_port: config.forward_port.append(fwd_port) changed = True elif desired_state == "disabled": if fwd_port in config.forward_port: config.forward_port.remove(fwd_port) changed = True # apply changes if changed: fw_lokkit.updateFirewall(config, old_config) if module.check_mode: module.exit_json(changed=True) else: module.fail_json(msg='No firewalld and system-config-firewall') module.exit_json(changed=False)
def getActiveZones(): fw = FirewallClient() zones = fw.getActiveZones() return zones
def addServiceToZone(service, zone): fw = FirewallClient() fw_zone = fw.config().getZoneByName(zone) fw_settings = fw_zone.getSettings() fw_settings.addService(service) fw_zone.update(fw_settings)
def main(): module_args = dict( name=dict(type="str", required=True), state=dict(choices=["present", "absent"], required=True), settype=dict( choices=[ "hash:ip", "hash:ip,port", "hash:ip,port,ip", "hash:ip,port,net", "hash:ip,mark", "hash:net", "hash:net,net", "hash:net,port", "hash:net,port,net", "hash:net,iface", "hash:mac", ], required=True, ), permanent=dict(type="bool", required=False, default=False), immediate=dict(type="bool", required=False, default=False), addresses=dict(type="list", required=False), ) module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) FirewallTransaction.sanity_check(module) # setup the FirewallDClient client = FirewallClient() sets = client.getIPSets() settings = FirewallClientIPSetSettings() settings.setType(module.params["settype"]) config = client.config() # construct return data result = {"firewalld_ipset_name": module.params["name"]} # Modifying a preexisting ipset if module.params["name"] in sets and module.params["state"] == "present": client_ipset_config = config.getIPSetByName(module.params["name"]) original_entries = client_ipset_config.getEntries() # when we're in check mode we shouldn't commit anything to the # state of the target. Just output what would happen. if module.check_mode: new_entries = module.params["addresses"] else: client_ipset_config.setEntries(module.params["addresses"]) firewalld_state(client, module.params) new_entries = client_ipset_config.getEntries() result["changed"] = new_entries != original_entries result["firewalld_ipset_addresses"] = new_entries # Creating a new ipset because the one proposed in the module declaration # does not exist already. elif module.params["name"] not in sets and module.params["state"] == "present": if module.check_mode: result["firewalld_ipset_addresses"] = module.params["addresses"] else: client_ipset_config = config.addIPSet(module.params["name"], settings) client_ipset_config.setEntries(module.params["addresses"]) firewalld_state(client, module.params) new_entries = client_ipset_config.getEntries() result["firewalld_ipset_addresses"] = new_entries result["changed"] = True # Removing an ipset that exists right now. If an ipset is asked to be # removed when it doesn't exist, we should just return an "unchanged" # state. elif module.params["name"] in sets and module.params["state"] == "absent": client_ipset_config = config.getIPSetByName(module.params["name"]) # avoid stateful actions in check mode if not module.check_mode: original_entries = client_ipset_config.remove() firewalld_state(client, module.params) result["changed"] = True result["firewalld_ipset_addresses"] = [] module.exit_json(**result)