def rules(self, ipv, rules): _rules = [] for rule in rules: # replace %%REJECT%% try: i = rule.index("%%REJECT%%") except ValueError: pass else: if ipv in ["ipv4", "ipv6"]: rule[i:i + 1] = [ "REJECT", "--reject-with", ipXtables.DEFAULT_REJECT_TYPE[ipv] ] else: raise FirewallError(errors.EBTABLES_NO_REJECT, "'%s' not in {'ipv4'|'ipv6'}" % ipv) # replace %%ICMP%% try: i = rule.index("%%ICMP%%") except ValueError: pass else: if ipv in ["ipv4", "ipv6"]: rule[i] = ipXtables.ICMP[ipv] else: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'}" % ipv) # replace %%LOGTYPE%% try: i = rule.index("%%LOGTYPE%%") except ValueError: pass else: if self._log_denied == "off": continue if ipv not in ["ipv4", "ipv6"]: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'}" % ipv) if self._log_denied in ["unicast", "broadcast", "multicast"]: rule[i:i + 1] = [ "-m", "pkttype", "--pkt-type", self._log_denied ] else: rule.pop(i) _rules.append(rule) backend = None if ipv == "ipv4": if self.ip4tables_enabled: # do not call if disabled backend = self.ip4tables_backend elif ipv == "ipv6": if self.ip6tables_enabled: # do not call if disabled backend = self.ip6tables_backend elif ipv == "eb": if self.ebtables_enabled: # do not call if disabled backend = self.ebtables_backend else: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'|'eb'}" % ipv) if not backend: return "" if self._individual_calls or \ not backend.restore_command_exists or \ (ipv == "eb" and not self.ebtables_backend.restore_noflush_option): for i, rule in enumerate(_rules): # remove leading and trailing '"' for use with execve j = 0 while j < len(rule): x = rule[j] if len(x) > 2 and x[0] == '"' and x[-1] == '"': rule[j] = x[1:-1] j += 1 try: backend.set_rule(rule) except Exception as msg: log.error( "Failed to apply rules. A firewall reload might solve the issue if the firewall has been modified using ip*tables or ebtables." ) log.error(msg) for rule in reversed(_rules[:i]): try: backend.set_rule(reverse_rule(rule)) except Exception: # ignore errors here pass return False return True else: return backend.set_rules(_rules)
def rules(self, ipv, rules): _rules = [ ] for rule in rules: # replace %%REJECT%% try: i = rule.index("%%REJECT%%") except ValueError: pass else: if ipv in [ "ipv4", "ipv6" ]: rule[i:i+1] = [ "REJECT", "--reject-with", ipXtables.DEFAULT_REJECT_TYPE[ipv] ] else: raise FirewallError(errors.EBTABLES_NO_REJECT, "'%s' not in {'ipv4'|'ipv6'}" % ipv) # replace %%ICMP%% try: i = rule.index("%%ICMP%%") except ValueError: pass else: if ipv in [ "ipv4", "ipv6" ]: rule[i] = ipXtables.ICMP[ipv] else: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'}" % ipv) # replace %%LOGTYPE%% try: i = rule.index("%%LOGTYPE%%") except ValueError: pass else: if self._log_denied == "off": continue if ipv not in [ "ipv4", "ipv6" ]: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'}" % ipv) if self._log_denied in [ "unicast", "broadcast", "multicast" ]: rule[i:i+1] = [ "-m", "pkttype", "--pkt-type", self._log_denied ] else: rule.pop(i) _rules.append(rule) backend = None if ipv == "ipv4": if self.ip4tables_enabled: # do not call if disabled backend = self.ip4tables_backend elif ipv == "ipv6": if self.ip6tables_enabled: # do not call if disabled backend = self.ip6tables_backend elif ipv == "eb": if self.ebtables_enabled: # do not call if disabled backend = self.ebtables_backend else: raise FirewallError(errors.INVALID_IPV, "'%s' not in {'ipv4'|'ipv6'|'eb'}" % ipv) if not backend: return "" if self._individual_calls or \ not backend.restore_command_exists or \ (ipv == "eb" and not self.ebtables_backend.restore_noflush_option): for i,rule in enumerate(_rules): # remove leading and trailing '"' for use with execve j = 0 while j < len(rule): x = rule[j] if len(x) > 2 and x[0] == '"' and x[-1] == '"': rule[j] = x[1:-1] j += 1 try: backend.set_rule(rule) except Exception as msg: log.error("Failed to apply rules. A firewall reload might solve the issue if the firewall has been modified using ip*tables or ebtables.") log.error(msg) for rule in reversed(_rules[:i]): try: backend.set_rule(reverse_rule(rule)) except Exception: # ignore errors here pass return False return True else: return backend.set_rules(_rules)