Пример #1
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            rules = backend.build_default_rules(self._log_denied)
            transaction.add_rules(backend, rules)

        ipv6_backend = self.get_backend_by_ipv("ipv6")
        if "raw" in ipv6_backend.get_available_tables():
            if self.ipv6_rpfilter_enabled:
                rules = ipv6_backend.build_rpfilter_rules(self._log_denied)
                transaction.add_rules(ipv6_backend, rules)

        if self._rfc3964_ipv4:
            # Flush due to iptables-restore (nftables) bug tiggered when
            # specifying same index multiple times in same batch
            # rhbz 1647925
            transaction.execute(True)
            transaction.clear()

            rules = ipv6_backend.build_rfc3964_ipv4_rules()
            transaction.add_rules(ipv6_backend, rules)

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #2
0
    def set_policy(self, policy, which="used", use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Setting policy to '%s'", policy)

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv4 firewall: %s" % e)

        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Пример #3
0
    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv4 firewall: %s" % e)
        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Пример #4
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in ["ipv4", "ipv6", "eb"]:
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_available_tables("ipv6"):
            # here is no check for ebtables.restore_noflush_option needed
            # as ebtables is not used in here
            transaction.add_rule("ipv6", [
                "-I", "PREROUTING", "1", "-t", "raw", "-p", "ipv6-icmp",
                "--icmpv6-type=router-advertisement", "-j", "ACCEPT"
            ])  # RHBZ#1058505
            transaction.add_rule("ipv6", [
                "-I", "PREROUTING", "2", "-t", "raw", "-m", "rpfilter",
                "--invert", "-j", "DROP"
            ])
            if self._log_denied != "off":
                transaction.add_rule("ipv6", [
                    "-I", "PREROUTING", "2", "-t", "raw", "-m", "rpfilter",
                    "--invert", "-j", "LOG", "--log-prefix", "rpfilter_DROP: "
                ])

        if use_transaction is None:
            transaction.execute(True)
Пример #5
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in [ "ipv4", "ipv6", "eb" ]:
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_available_tables("ipv6"):
            # here is no check for ebtables.restore_noflush_option needed
            # as ebtables is not used in here
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "1", "-t", "raw",
                                   "-p", "ipv6-icmp",
                                   "--icmpv6-type=router-advertisement",
                                   "-j", "ACCEPT" ]) # RHBZ#1058505
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "2", "-t", "raw",
                                   "-m", "rpfilter", "--invert", "-j", "DROP" ])
            if self._log_denied != "off":
                transaction.add_rule("ipv6",
                                     [ "-I", "PREROUTING", "2", "-t", "raw",
                                       "-m", "rpfilter", "--invert",
                                       "-j", "LOG",
                                       "--log-prefix", "rpfilter_DROP: " ])

        if use_transaction is None:
            transaction.execute(True)
Пример #6
0
    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv4 firewall: %s" % e)
        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.flush(transaction)
            except Exception as e:
                log.error("Failed to flush eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Пример #7
0
    def set_policy(self, policy, which="used", use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Setting policy to '%s'", policy)

        if self.ip4tables_enabled:
            try:
                self.ip4tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv4 firewall: %s" % e)

        if self.ip6tables_enabled:
            try:
                self.ip6tables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of ipv6 firewall: %s" % e)
        if self.ebtables_enabled:
            try:
                self.ebtables_backend.set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of eb firewall: %s" % e)

        if use_transaction is None:
            transaction.execute(True)
Пример #8
0
    def apply_default_tables(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            transaction.add_rules(backend, backend.build_default_tables())

        if use_transaction is None:
            transaction.execute(True)
Пример #9
0
    def set_policy(self, policy, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Setting policy to '%s'", policy)

        for backend in self.enabled_backends():
            rules = backend.build_set_policy_rules(policy)
            transaction.add_rules(backend, rules)

        if use_transaction is None:
            transaction.execute(True)
Пример #10
0
    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        for backend in self.all_backends():
            rules = backend.build_flush_rules()
            transaction.add_rules(backend, rules)

        if use_transaction is None:
            transaction.execute(True)
Пример #11
0
    def set_policy(self, policy, which="used", use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Setting policy to '%s'", policy)

        for ipv in self.enabled_backends():
            try:
                self.get_ipv_backend(ipv).set_policy(policy, which, transaction)
            except Exception as e:
                log.error("Failed to set policy of %s firewall: %s" % (ipv, e))

        if use_transaction is None:
            transaction.execute(True)
Пример #12
0
    def flush(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        log.debug1("Flushing rule set")

        for ipv in self.enabled_backends():
            try:
                self.get_ipv_backend(ipv).flush(transaction)
            except Exception as e:
                log.error("Failed to flush %s firewall: %s" % (ipv, e))

        if use_transaction is None:
            transaction.execute(True)
Пример #13
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in self.enabled_backends():
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_ipv_backend("ipv6").get_available_tables():

            # Execute existing transaction
            transaction.execute(True)
            # Start new transaction
            transaction.clear()

            self.ip6tables_backend.apply_rpfilter_rules(transaction, self._log_denied)

            # Execute ipv6_rpfilter transaction, it might fail
            try:
                transaction.execute(True)
            except FirewallError as msg:
                log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
            # Start new transaction
            transaction.clear()

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #14
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            rules = backend.build_default_rules(self._log_denied)
            transaction.add_rules(backend, rules)

        ipv6_backend = self.get_backend_by_ipv("ipv6")
        if self.ipv6_rpfilter_enabled and \
           "raw" in ipv6_backend.get_available_tables():

            # Execute existing transaction
            transaction.execute(True)
            # Start new transaction
            transaction.clear()

            rules = ipv6_backend.build_rpfilter_rules(self._log_denied)
            transaction.add_rules(ipv6_backend, rules)

            # Execute ipv6_rpfilter transaction, it might fail
            try:
                transaction.execute(True)
            except FirewallError as msg:
                log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
            # Start new transaction
            transaction.clear()

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #15
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in [ "ipv4", "ipv6", "eb" ]:
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_available_tables("ipv6"):

            # Execute existing transaction
            transaction.execute(True)
            # Start new transaction
            transaction.clear()

            self.ip6tables_backend.apply_rpfilter_rules(transaction, self._log_denied)

            # Execute ipv6_rpfilter transaction, it might fail
            try:
                transaction.execute(True)
            except FirewallError as msg:
                log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
            # Start new transaction
            transaction.clear()

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #16
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for backend in self.enabled_backends():
            rules = backend.build_default_rules(self._log_denied)
            transaction.add_rules(backend, rules)

        if self.is_ipv_enabled("ipv6"):
            ipv6_backend = self.get_backend_by_ipv("ipv6")
            if "raw" in ipv6_backend.get_available_tables():
                if self.ipv6_rpfilter_enabled:
                    rules = ipv6_backend.build_rpfilter_rules(self._log_denied)
                    transaction.add_rules(ipv6_backend, rules)

        if self.is_ipv_enabled("ipv6") and self._rfc3964_ipv4:
            rules = ipv6_backend.build_rfc3964_ipv4_rules()
            transaction.add_rules(ipv6_backend, rules)

        if use_transaction is None:
            transaction.execute(True)
Пример #17
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in [ "ipv4", "ipv6", "eb" ]:
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_available_tables("ipv6"):

            # Execute existing transaction
            transaction.execute(True)
            # Start new transaction
            transaction.clear()

            # here is no check for ebtables.restore_noflush_option needed
            # as ebtables is not used in here
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "1", "-t", "raw",
                                   "-p", "ipv6-icmp",
                                   "--icmpv6-type=router-advertisement",
                                   "-j", "ACCEPT" ]) # RHBZ#1058505
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "2", "-t", "raw",
                                   "-m", "rpfilter", "--invert", "-j", "DROP" ])
            if self._log_denied != "off":
                transaction.add_rule("ipv6",
                                     [ "-I", "PREROUTING", "2", "-t", "raw",
                                       "-m", "rpfilter", "--invert",
                                       "-j", "LOG",
                                       "--log-prefix", "rpfilter_DROP: " ])

            # Execute ipv6_rpfilter transaction, it might fail
            try:
                transaction.execute(True)
            except FirewallError as msg:
                log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
            # Start new transaction
            transaction.clear()

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #18
0
    def apply_default_rules(self, use_transaction=None):
        if use_transaction is None:
            transaction = FirewallTransaction(self)
        else:
            transaction = use_transaction

        for ipv in [ "ipv4", "ipv6", "eb" ]:
            self.__apply_default_rules(ipv, transaction)

        if self.ipv6_rpfilter_enabled and \
           "raw" in self.get_available_tables("ipv6"):

            # Execute existing transaction
            transaction.execute(True)
            # Start new transaction
            transaction.clear()

            # here is no check for ebtables.restore_noflush_option needed
            # as ebtables is not used in here
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "1", "-t", "raw",
                                   "-p", "ipv6-icmp",
                                   "--icmpv6-type=router-advertisement",
                                   "-j", "ACCEPT" ]) # RHBZ#1058505
            transaction.add_rule("ipv6",
                                 [ "-I", "PREROUTING", "2", "-t", "raw",
                                   "-m", "rpfilter", "--invert", "-j", "DROP" ])
            if self._log_denied != "off":
                transaction.add_rule("ipv6",
                                     [ "-I", "PREROUTING", "2", "-t", "raw",
                                       "-m", "rpfilter", "--invert",
                                       "-j", "LOG",
                                       "--log-prefix", "rpfilter_DROP: " ])

            # Execute ipv6_rpfilter transaction, it might fail
            try:
                transaction.execute(True)
            except FirewallError as msg:
                log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
            # Start new transaction
            transaction.clear()

        else:
            if use_transaction is None:
                transaction.execute(True)
Пример #19
0
    def _start(self, reload=False, complete_reload=False):
        # initialize firewall
        default_zone = config.FALLBACK_ZONE

        # load firewalld config
        log.debug1("Loading firewalld config file '%s'", config.FIREWALLD_CONF)
        try:
            self._firewalld_conf.read()
        except Exception as msg:
            log.warning(msg)
            log.warning("Using fallback firewalld configuration settings.")
        else:
            if self._firewalld_conf.get("DefaultZone"):
                default_zone = self._firewalld_conf.get("DefaultZone")

            if self._firewalld_conf.get("MinimalMark"):
                self._min_mark = int(self._firewalld_conf.get("MinimalMark"))

            if self._firewalld_conf.get("CleanupOnExit"):
                value = self._firewalld_conf.get("CleanupOnExit")
                if value is not None and value.lower() in ["no", "false"]:
                    self.cleanup_on_exit = False
                log.debug1("CleanupOnExit is set to '%s'",
                           self.cleanup_on_exit)

            if self._firewalld_conf.get("Lockdown"):
                value = self._firewalld_conf.get("Lockdown")
                if value is not None and value.lower() in ["yes", "true"]:
                    log.debug1("Lockdown is enabled")
                    try:
                        self.policies.enable_lockdown()
                    except FirewallError:
                        # already enabled, this is probably reload
                        pass

            if self._firewalld_conf.get("IPv6_rpfilter"):
                value = self._firewalld_conf.get("IPv6_rpfilter")
                if value is not None:
                    if value.lower() in ["no", "false"]:
                        self.ipv6_rpfilter_enabled = False
                    if value.lower() in ["yes", "true"]:
                        self.ipv6_rpfilter_enabled = True
            if self.ipv6_rpfilter_enabled:
                log.debug1("IPv6 rpfilter is enabled")
            else:
                log.debug1("IPV6 rpfilter is disabled")

            if self._firewalld_conf.get("IndividualCalls"):
                value = self._firewalld_conf.get("IndividualCalls")
                if value is not None and value.lower() in ["yes", "true"]:
                    log.debug1("IndividualCalls is enabled")
                    self._individual_calls = True

            if self._firewalld_conf.get("LogDenied"):
                value = self._firewalld_conf.get("LogDenied")
                if value is None or value.lower() == "no":
                    self._log_denied = "off"
                else:
                    self._log_denied = value.lower()
                    log.debug1("LogDenied is set to '%s'", self._log_denied)

            if self._firewalld_conf.get("AutomaticHelpers"):
                value = self._firewalld_conf.get("AutomaticHelpers")
                if value is not None:
                    if value.lower() in ["no", "false"]:
                        self._automatic_helpers = "no"
                    elif value.lower() in ["yes", "true"]:
                        self._automatic_helpers = "yes"
                    else:
                        self._automatic_helpers = value.lower()
                    log.debug1("AutomaticHelpers is set to '%s'",
                               self._automatic_helpers)

            if self._firewalld_conf.get("FirewallBackend"):
                self._firewall_backend = self._firewalld_conf.get(
                    "FirewallBackend")
                log.debug1("FirewallBackend is set to '%s'",
                           self._firewall_backend)

            if self._firewalld_conf.get("FlushAllOnReload"):
                value = self._firewalld_conf.get("FlushAllOnReload")
                if value.lower() in ["no", "false"]:
                    self._flush_all_on_reload = False
                else:
                    self._flush_all_on_reload = True
                log.debug1("FlushAllOnReload is set to '%s'",
                           self._flush_all_on_reload)

        self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))

        self._select_firewall_backend(self._firewall_backend)

        self._start_check()

        # load lockdown whitelist
        log.debug1("Loading lockdown whitelist")
        try:
            self.policies.lockdown_whitelist.read()
        except Exception as msg:
            if self.policies.query_lockdown():
                log.error("Failed to load lockdown whitelist '%s': %s",
                          self.policies.lockdown_whitelist.filename, msg)
            else:
                log.debug1("Failed to load lockdown whitelist '%s': %s",
                           self.policies.lockdown_whitelist.filename, msg)

        # copy policies to config interface
        self.config.set_policies(copy.deepcopy(self.policies))

        # load ipset files
        self._loader(config.FIREWALLD_IPSETS, "ipset")
        self._loader(config.ETC_FIREWALLD_IPSETS, "ipset")

        # load icmptype files
        self._loader(config.FIREWALLD_ICMPTYPES, "icmptype")
        self._loader(config.ETC_FIREWALLD_ICMPTYPES, "icmptype")

        if len(self.icmptype.get_icmptypes()) == 0:
            log.error("No icmptypes found.")

        # load helper files
        self._loader(config.FIREWALLD_HELPERS, "helper")
        self._loader(config.ETC_FIREWALLD_HELPERS, "helper")

        # load service files
        self._loader(config.FIREWALLD_SERVICES, "service")
        self._loader(config.ETC_FIREWALLD_SERVICES, "service")

        if len(self.service.get_services()) == 0:
            log.error("No services found.")

        # load zone files
        self._loader(config.FIREWALLD_ZONES, "zone")
        self._loader(config.ETC_FIREWALLD_ZONES, "zone")

        if len(self.zone.get_zones()) == 0:
            log.fatal("No zones found.")
            sys.exit(1)

        # check minimum required zones
        error = False
        for z in ["block", "drop", "trusted"]:
            if z not in self.zone.get_zones():
                log.fatal("Zone '%s' is not available.", z)
                error = True
        if error:
            sys.exit(1)

        # check if default_zone is a valid zone
        if default_zone not in self.zone.get_zones():
            if "public" in self.zone.get_zones():
                zone = "public"
            elif "external" in self.zone.get_zones():
                zone = "external"
            else:
                zone = "block"  # block is a base zone, therefore it has to exist

            log.error("Default zone '%s' is not valid. Using '%s'.",
                      default_zone, zone)
            default_zone = zone
        else:
            log.debug1("Using default zone '%s'", default_zone)

        # load direct rules
        obj = Direct(config.FIREWALLD_DIRECT)
        if os.path.exists(config.FIREWALLD_DIRECT):
            log.debug1("Loading direct rules file '%s'" % \
                       config.FIREWALLD_DIRECT)
            try:
                obj.read()
            except Exception as msg:
                log.error("Failed to load direct rules file '%s': %s",
                          config.FIREWALLD_DIRECT, msg)
        self.direct.set_permanent_config(obj)
        self.config.set_direct(copy.deepcopy(obj))

        # automatic helpers
        #
        # NOTE: must force loading of nf_conntrack to make sure the values are
        # available in /proc
        module_return = self.handle_modules(["nf_conntrack"], True)
        if module_return:
            log.error("Failed to load nf_conntrack module: %s" %
                      module_return[1])
            sys.exit(1)
        if self._automatic_helpers != "system":
            functions.set_nf_conntrack_helper_setting(
                self._automatic_helpers == "yes")
        self.nf_conntrack_helper_setting = \
            functions.get_nf_conntrack_helper_setting()

        # check if needed tables are there
        self._check_tables()

        if log.getDebugLogLevel() > 0:
            # get time before flushing and applying
            tm1 = time.time()

        # Start transaction
        transaction = FirewallTransaction(self)

        # flush rules
        self.flush(use_transaction=transaction)

        # If modules need to be unloaded in complete reload or if there are
        # ipsets to get applied, limit the transaction to flush.
        #
        # Future optimization for the ipset case in reload: The transaction
        # only needs to be split here if there are conflicting ipset types in
        # exsting ipsets and the configuration in firewalld.
        if (reload and complete_reload) or \
           (self.ipset_enabled and self.ipset.has_ipsets()):
            transaction.execute(True)
            transaction.clear()

        # complete reload: unload modules also
        if reload and complete_reload:
            log.debug1("Unloading firewall modules")
            self.modules_backend.unload_firewall_modules()

        self.apply_default_tables(use_transaction=transaction)
        transaction.execute(True)
        transaction.clear()

        # apply settings for loaded ipsets while reloading here
        if self.ipset_enabled and self.ipset.has_ipsets():
            log.debug1("Applying ipsets")
            self.ipset.apply_ipsets()

        # Start or continue with transaction

        # apply default rules
        log.debug1("Applying default rule set")
        self.apply_default_rules(use_transaction=transaction)

        # apply settings for loaded zones
        log.debug1("Applying used zones")
        self.zone.apply_zones(use_transaction=transaction)

        self._default_zone = self.check_zone(default_zone)
        self.zone.change_default_zone(None,
                                      self._default_zone,
                                      use_transaction=transaction)

        # Execute transaction
        transaction.execute(True)

        # Start new transaction for direct rules
        transaction.clear()

        # apply direct chains, rules and passthrough rules
        if self.direct.has_configuration():
            log.debug1("Applying direct chains rules and passthrough rules")
            self.direct.apply_direct(transaction)

            # since direct rules are easy to make syntax errors lets highlight
            # the cause if the transaction fails.
            try:
                transaction.execute(True)
                transaction.clear()
            except FirewallError as e:
                raise FirewallError(e.code,
                                    "Direct: %s" % (e.msg if e.msg else ""))
            except Exception:
                raise

        del transaction

        if log.getDebugLogLevel() > 1:
            # get time after flushing and applying
            tm2 = time.time()
            log.debug2("Flushing and applying took %f seconds" % (tm2 - tm1))
Пример #20
0
    def _start(self, reload=False, complete_reload=False):
        # initialize firewall
        default_zone = config.FALLBACK_ZONE

        # load firewalld config
        log.debug1("Loading firewalld config file '%s'", config.FIREWALLD_CONF)
        try:
            self._firewalld_conf.read()
        except Exception as msg:
            log.warning(msg)
            log.warning("Using fallback firewalld configuration settings.")
        else:
            if self._firewalld_conf.get("DefaultZone"):
                default_zone = self._firewalld_conf.get("DefaultZone")

            if self._firewalld_conf.get("MinimalMark"):
                self._min_mark = int(self._firewalld_conf.get("MinimalMark"))

            if self._firewalld_conf.get("CleanupOnExit"):
                value = self._firewalld_conf.get("CleanupOnExit")
                if value is not None and value.lower() in [ "no", "false" ]:
                    self.cleanup_on_exit = False

            if self._firewalld_conf.get("Lockdown"):
                value = self._firewalld_conf.get("Lockdown")
                if value is not None and value.lower() in [ "yes", "true" ]:
                    log.debug1("Lockdown is enabled")
                    try:
                        self.policies.enable_lockdown()
                    except FirewallError:
                        # already enabled, this is probably reload
                        pass

            if self._firewalld_conf.get("IPv6_rpfilter"):
                value = self._firewalld_conf.get("IPv6_rpfilter")
                if value is not None:
                    if value.lower() in [ "no", "false" ]:
                        self.ipv6_rpfilter_enabled = False
                    if value.lower() in [ "yes", "true" ]:
                        self.ipv6_rpfilter_enabled = True
            if self.ipv6_rpfilter_enabled:
                log.debug1("IPv6 rpfilter is enabled")
            else:
                log.debug1("IPV6 rpfilter is disabled")

            if self._firewalld_conf.get("IndividualCalls"):
                value = self._firewalld_conf.get("IndividualCalls")
                if value is not None and value.lower() in [ "yes", "true" ]:
                    log.debug1("IndividualCalls is enabled")
                    self._individual_calls = True

            if self._firewalld_conf.get("LogDenied"):
                value = self._firewalld_conf.get("LogDenied")
                if value is None or value.lower() == "no":
                    self._log_denied = "off"
                else:
                    self._log_denied = value.lower()
                    log.debug1("LogDenied is set to '%s'", self._log_denied)

            if self._firewalld_conf.get("AutomaticHelpers"):
                value = self._firewalld_conf.get("AutomaticHelpers")
                if value is not None:
                    if value.lower() in [ "no", "false" ]:
                        self._automatic_helpers = "no"
                    elif value.lower() in [ "yes", "true" ]:
                        self._automatic_helpers = "yes"
                    else:
                        self._automatic_helpers = value.lower()
                    log.debug1("AutomaticHelpers is set to '%s'",
                               self._automatic_helpers)

        self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))

        self._start_check()

        # load lockdown whitelist
        log.debug1("Loading lockdown whitelist")
        try:
            self.policies.lockdown_whitelist.read()
        except Exception as msg:
            if self.policies.query_lockdown():
                log.error("Failed to load lockdown whitelist '%s': %s",
                          self.policies.lockdown_whitelist.filename, msg)
            else:
                log.debug1("Failed to load lockdown whitelist '%s': %s",
                           self.policies.lockdown_whitelist.filename, msg)

        # copy policies to config interface
        self.config.set_policies(copy.deepcopy(self.policies))

        # load ipset files
        self._loader(config.FIREWALLD_IPSETS, "ipset")
        self._loader(config.ETC_FIREWALLD_IPSETS, "ipset")

        # load icmptype files
        self._loader(config.FIREWALLD_ICMPTYPES, "icmptype")
        self._loader(config.ETC_FIREWALLD_ICMPTYPES, "icmptype")

        if len(self.icmptype.get_icmptypes()) == 0:
            log.error("No icmptypes found.")

        # load helper files
        self._loader(config.FIREWALLD_HELPERS, "helper")
        self._loader(config.ETC_FIREWALLD_HELPERS, "helper")

        # load service files
        self._loader(config.FIREWALLD_SERVICES, "service")
        self._loader(config.ETC_FIREWALLD_SERVICES, "service")

        if len(self.service.get_services()) == 0:
            log.error("No services found.")

        # load zone files
        self._loader(config.FIREWALLD_ZONES, "zone")
        self._loader(config.ETC_FIREWALLD_ZONES, "zone")

        if len(self.zone.get_zones()) == 0:
            log.fatal("No zones found.")
            sys.exit(1)

        # check minimum required zones
        error = False
        for z in [ "block", "drop", "trusted" ]:
            if z not in self.zone.get_zones():
                log.fatal("Zone '%s' is not available.", z)
                error = True
        if error:
            sys.exit(1)

        # check if default_zone is a valid zone
        if default_zone not in self.zone.get_zones():
            if "public" in self.zone.get_zones():
                zone = "public"
            elif "external" in self.zone.get_zones():
                zone = "external"
            else:
                zone = "block" # block is a base zone, therefore it has to exist

            log.error("Default zone '%s' is not valid. Using '%s'.",
                      default_zone, zone)
            default_zone = zone
        else:
            log.debug1("Using default zone '%s'", default_zone)

        # load direct rules
        obj = Direct(config.FIREWALLD_DIRECT)
        if os.path.exists(config.FIREWALLD_DIRECT):
            log.debug1("Loading direct rules file '%s'" % \
                       config.FIREWALLD_DIRECT)
            try:
                obj.read()
            except Exception as msg:
                log.debug1("Failed to load direct rules file '%s': %s",
                           config.FIREWALLD_DIRECT, msg)
        self.direct.set_permanent_config(obj)
        self.config.set_direct(copy.deepcopy(obj))

        # automatic helpers
        if self._automatic_helpers != "system":
            functions.set_nf_conntrack_helper_setting(self._automatic_helpers == "yes")
        self.nf_conntrack_helper_setting = \
            functions.get_nf_conntrack_helper_setting()

        # check if needed tables are there
        self._check_tables()

        if log.getDebugLogLevel() > 0:
            # get time before flushing and applying
            tm1 = time.time()

        # Start transaction
        transaction = FirewallTransaction(self)

        if reload:
            self.set_policy("DROP", use_transaction=transaction)

        # flush rules
        self.flush(use_transaction=transaction)

        # If modules need to be unloaded in complete reload or if there are
        # ipsets to get applied, limit the transaction to set_policy and flush.
        #
        # Future optimization for the ipset case in reload: The transaction
        # only needs to be split here if there are conflicting ipset types in
        # exsting ipsets and the configuration in firewalld.
        if (reload and complete_reload) or \
           (self.ipset_enabled and self.ipset.has_ipsets()):
            transaction.execute(True)
            transaction.clear()

        # complete reload: unload modules also
        if reload and complete_reload:
            log.debug1("Unloading firewall modules")
            self.modules_backend.unload_firewall_modules()

        # apply settings for loaded ipsets while reloading here
        if self.ipset_enabled and self.ipset.has_ipsets():
            log.debug1("Applying ipsets")
            self.ipset.apply_ipsets()

        # Start or continue with transaction

        # apply default rules
        log.debug1("Applying default rule set")
        self.apply_default_rules(use_transaction=transaction)

        # apply settings for loaded zones
        log.debug1("Applying used zones")
        self.zone.apply_zones(use_transaction=transaction)

        self._default_zone = self.check_zone(default_zone)
        self.zone.change_default_zone(None, self._default_zone,
                                      use_transaction=transaction)

        # Execute transaction
        transaction.execute(True)

        # Start new transaction for direct rules
        transaction.clear()

        # apply direct chains, rules and passthrough rules
        if self.direct.has_configuration():
            transaction.enable_generous_mode()
            log.debug1("Applying direct chains rules and passthrough rules")
            self.direct.apply_direct(transaction)

            # Execute transaction
            transaction.execute(True)
            transaction.disable_generous_mode()
            transaction.clear()

        del transaction

        if log.getDebugLogLevel() > 1:
            # get time after flushing and applying
            tm2 = time.time()
            log.debug2("Flushing and applying took %f seconds" % (tm2 - tm1))

        self._state = "RUNNING"