diff --git a/0001-fw_zone-consider-destination-for-protocols.patch b/0001-fw_zone-consider-destination-for-protocols.patch new file mode 100644 index 0000000..ad9379b --- /dev/null +++ b/0001-fw_zone-consider-destination-for-protocols.patch @@ -0,0 +1,47 @@ +From e9eede7766610d5b632087783761f93334bdd47e Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 29 Aug 2018 10:19:11 -0400 +Subject: [PATCH 1/4] fw_zone: consider destination for protocols + +destinations were ignore if protocols were specified. This fixes that. + +(cherry picked from commit 8d863e8a1c78cb93cb4823cd1824776dba1d9d34) +--- + src/firewall/core/fw_zone.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index 7c7653fe..155b8b7f 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -1640,7 +1640,7 @@ class FirewallZone(object): + if enable and type(rule.action) == Rich_Mark: + zone_transaction.add_chain("mangle", "PREROUTING") + rules = backend.build_zone_protocol_rules( +- enable, zone, proto, rule) ++ enable, zone, proto, destination, rule) + zone_transaction.add_rules(backend, rules) + + # create rules +@@ -1677,7 +1677,7 @@ class FirewallZone(object): + zone_transaction.add_chain("mangle", "PREROUTING") + + rules = backend.build_zone_protocol_rules( +- enable, zone, protocol, rule) ++ enable, zone, protocol, None, rule) + zone_transaction.add_rules(backend, rules) + + # MASQUERADE +@@ -1852,7 +1852,8 @@ class FirewallZone(object): + zone_transaction.add_rules(backend, rules) + + for protocol in svc.protocols: +- rules = backend.build_zone_protocol_rules(enable, zone, protocol) ++ rules = backend.build_zone_protocol_rules( ++ enable, zone, protocol, destination) + zone_transaction.add_rules(backend, rules) + + for (port,proto) in svc.source_ports: +-- +2.18.0 + diff --git a/0001-nftables-fix-rich-rules-ports-protocols-source-ports.patch b/0001-nftables-fix-rich-rules-ports-protocols-source-ports.patch new file mode 100644 index 0000000..1b4a580 --- /dev/null +++ b/0001-nftables-fix-rich-rules-ports-protocols-source-ports.patch @@ -0,0 +1,74 @@ +From 0a5827471610fdbb19a053f7f46c114d4fbdf2a0 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 29 Aug 2018 16:10:20 -0400 +Subject: [PATCH] nftables: fix rich rules ports/protocols/source ports not + considering ct state + +They were accepting the packets, but were not matching on "ct state new" +as they should have been. In most (all?) cases, this should not have had +a noticeable affect because the existing connections were accepted long +before the _allow rules are hit. + +(cherry picked from commit 0dd56eba38a2e0075281fb5a7180ecb9851359e1) +--- + src/firewall/core/nftables.py | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 1ac8b3a8..20296292 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -812,6 +812,7 @@ class nftables(object): + rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination) + rule_fragment += self._rich_rule_source_fragment(rich_rule.source) + rule_fragment += [proto, "dport", "%s" % portStr(port, "-")] ++ rule_fragment += ["ct", "state", "new"] + + rules = [] + if rich_rule: +@@ -821,7 +822,7 @@ class nftables(object): + else: + rules.append([add_del, "rule", "inet", "%s" % TABLE_NAME, + "%s_%s_allow" % (table, target)] + +- rule_fragment + ["ct", "state", "new", "accept"]) ++ rule_fragment + ["accept"]) + + return rules + +@@ -844,6 +845,7 @@ class nftables(object): + rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination) + rule_fragment += self._rich_rule_source_fragment(rich_rule.source) + rule_fragment = ["meta", "l4proto", protocol] ++ rule_fragment += ["ct", "state", "new"] + + rules = [] + if rich_rule: +@@ -853,7 +855,7 @@ class nftables(object): + else: + rules.append([add_del, "rule", "inet", "%s" % TABLE_NAME, + "filter_%s_allow" % (target)] + +- rule_fragment + ["ct", "state", "new", "accept"]) ++ rule_fragment + ["accept"]) + + return rules + +@@ -876,6 +878,7 @@ class nftables(object): + rule_fragment += self._rich_rule_destination_fragment(rich_rule.destination) + rule_fragment += self._rich_rule_source_fragment(rich_rule.source) + rule_fragment += [proto, "sport", "%s" % portStr(port, "-")] ++ rule_fragment += ["ct", "state", "new"] + + rules = [] + if rich_rule: +@@ -885,7 +888,7 @@ class nftables(object): + else: + rules.append([add_del, "rule", "inet", "%s" % TABLE_NAME, + "%s_%s_allow" % (table, target)] + +- rule_fragment + ["ct", "state", "new", "accept"]) ++ rule_fragment + ["accept"]) + + return rules + +-- +2.18.0 + diff --git a/0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch b/0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch new file mode 100644 index 0000000..fb74a51 --- /dev/null +++ b/0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch @@ -0,0 +1,216 @@ +From d9f46f02dd90bc6630f6e5462e67bc5341bdcade Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 29 Aug 2018 10:10:18 -0400 +Subject: [PATCH 2/4] fw_zone: fix services with multiple destination IP + versions + +Only one of the IP versions was being added to the backend. Make sure we +consider both. + +Fixes: #366 +Fixes: 929b1d2ab988 ("fw_zone: push service rule generation into backends") +Fixes: 7c5f5f4d12ee ("fw_zone: push rich rule generation to backend") +(cherry picked from commit 4aa13cc1377143e59a7f89bbbd9c4b01a9b8896a) +--- + src/firewall/core/fw_zone.py | 170 +++++++++++++++++------------------ + 1 file changed, 82 insertions(+), 88 deletions(-) + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index 155b8b7f..75ea6018 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -1572,84 +1572,82 @@ class FirewallZone(object): + if type(rule.element) == Rich_Service: + svc = self._fw.service.get_service(rule.element.name) + +- destination = rule.destination if rule.destination else None ++ destinations = [rule.destination] if rule.destination else [None] ++ + if len(svc.destination) > 0: ++ if rule.destination: ++ # we can not use two destinations at the same time ++ raise FirewallError(errors.INVALID_RULE, ++ "Destination conflict with service.") ++ destinations = [] + for ipv in ipvs: +- if ipv in svc.destination: +- if not backend.is_ipv_supported(ipv): +- # destination is set, only use if it contains ipv +- raise FirewallError(errors.INVALID_RULE, +- "Service %s is not usable with %s" % +- (rule.element.name, backend.name)) +- elif svc.destination[ipv] != "" and rule.destination: +- # we can not use two destinations at the same time +- raise FirewallError(errors.INVALID_RULE, +- "Destination conflict with service.") +- destination = svc.destination[ipv] +- +- if enable: +- zone_transaction.add_chain("filter", "INPUT") +- if self._fw.nf_conntrack_helper_setting == 0: +- zone_transaction.add_chain("raw", "PREROUTING") ++ if ipv in svc.destination and backend.is_ipv_supported(ipv): ++ destinations.append(svc.destination[ipv]) + +- if type(rule.action) == Rich_Accept: +- # only load modules for accept action +- helpers = self.get_helpers_for_service_modules(svc.modules, +- enable) +- +- modules = [ ] +- for helper in helpers: +- module = helper.module ++ for destination in destinations: ++ if enable: ++ zone_transaction.add_chain("filter", "INPUT") + if self._fw.nf_conntrack_helper_setting == 0: +- if helper.name not in \ +- self._fw.nf_conntrack_helpers[module]: +- raise FirewallError( +- errors.INVALID_HELPER, +- "'%s' not available in kernel" % module) +- nat_module = module.replace("conntrack", "nat") +- if nat_module in self._fw.nf_nat_helpers: +- modules.append(nat_module) +- if helper.family != "" and not backend.is_ipv_supported(helper.family): +- # no support for family ipv, continue +- continue +- if len(helper.ports) < 1: +- modules.append(module) +- else: +- for (port,proto) in helper.ports: +- rules = backend.build_zone_helper_ports_rules( +- enable, zone, proto, port, +- destination, helper.name) +- zone_transaction.add_rules(backend, rules) +- else: +- if helper.module not in modules: +- modules.append(helper.module) +- nat_module = helper.module.replace("conntrack", "nat") ++ zone_transaction.add_chain("raw", "PREROUTING") ++ ++ if type(rule.action) == Rich_Accept: ++ # only load modules for accept action ++ helpers = self.get_helpers_for_service_modules(svc.modules, ++ enable) ++ ++ modules = [ ] ++ for helper in helpers: ++ module = helper.module ++ if self._fw.nf_conntrack_helper_setting == 0: ++ if helper.name not in \ ++ self._fw.nf_conntrack_helpers[module]: ++ raise FirewallError( ++ errors.INVALID_HELPER, ++ "'%s' not available in kernel" % module) ++ nat_module = module.replace("conntrack", "nat") + if nat_module in self._fw.nf_nat_helpers: + modules.append(nat_module) +- zone_transaction.add_modules(modules) +- +- # create rules +- for (port,proto) in svc.ports: +- if enable and type(rule.action) == Rich_Mark: +- zone_transaction.add_chain("mangle", "PREROUTING") +- rules = backend.build_zone_ports_rules( +- enable, zone, proto, port, destination, rule) +- zone_transaction.add_rules(backend, rules) +- +- for proto in svc.protocols: +- if enable and type(rule.action) == Rich_Mark: +- zone_transaction.add_chain("mangle", "PREROUTING") +- rules = backend.build_zone_protocol_rules( +- enable, zone, proto, destination, rule) +- zone_transaction.add_rules(backend, rules) +- +- # create rules +- for (port,proto) in svc.source_ports: +- if enable and type(rule.action) == Rich_Mark: +- zone_transaction.add_chain("mangle", "PREROUTING") +- rules = backend.build_zone_source_ports_rules( +- enable, zone, proto, port, destination, rule) +- zone_transaction.add_rules(backend, rules) ++ if helper.family != "" and not backend.is_ipv_supported(helper.family): ++ # no support for family ipv, continue ++ continue ++ if len(helper.ports) < 1: ++ modules.append(module) ++ else: ++ for (port,proto) in helper.ports: ++ rules = backend.build_zone_helper_ports_rules( ++ enable, zone, proto, port, ++ destination, helper.name) ++ zone_transaction.add_rules(backend, rules) ++ else: ++ if helper.module not in modules: ++ modules.append(helper.module) ++ nat_module = helper.module.replace("conntrack", "nat") ++ if nat_module in self._fw.nf_nat_helpers: ++ modules.append(nat_module) ++ zone_transaction.add_modules(modules) ++ ++ # create rules ++ for (port,proto) in svc.ports: ++ if enable and type(rule.action) == Rich_Mark: ++ zone_transaction.add_chain("mangle", "PREROUTING") ++ rules = backend.build_zone_ports_rules( ++ enable, zone, proto, port, destination, rule) ++ zone_transaction.add_rules(backend, rules) ++ ++ for proto in svc.protocols: ++ if enable and type(rule.action) == Rich_Mark: ++ zone_transaction.add_chain("mangle", "PREROUTING") ++ rules = backend.build_zone_protocol_rules( ++ enable, zone, proto, destination, rule) ++ zone_transaction.add_rules(backend, rules) ++ ++ # create rules ++ for (port,proto) in svc.source_ports: ++ if enable and type(rule.action) == Rich_Mark: ++ zone_transaction.add_chain("mangle", "PREROUTING") ++ rules = backend.build_zone_source_ports_rules( ++ enable, zone, proto, port, destination, rule) ++ zone_transaction.add_rules(backend, rules) + + # PORT + elif type(rule.element) == Rich_Port: +@@ -1805,24 +1803,20 @@ class FirewallZone(object): + zone_transaction.add_modules(modules) + zone_transaction.add_chain("filter", "INPUT") + +- for backend in self._fw.enabled_backends(): +- if not backend.zones_supported: +- continue +- skip_backend = False +- +- destination = None ++ # build a list of (backend, destination). The destination may be ipv4, ++ # ipv6 or None ++ # ++ backends_ipv = [] ++ for ipv in ["ipv4", "ipv6"]: ++ backend = self._fw.get_backend_by_ipv(ipv) + if len(svc.destination) > 0: +- for ipv in ["ipv4", "ipv6"]: +- if ipv in svc.destination: +- if not backend.is_ipv_supported(ipv): +- # destination is set, only use if it contains ipv +- skip_backend = True +- break +- destination = svc.destination[ipv] +- +- if skip_backend: +- continue ++ if ipv in svc.destination: ++ backends_ipv.append((backend, svc.destination[ipv])) ++ else: ++ if (backend, None) not in backends_ipv: ++ backends_ipv.append((backend, None)) + ++ for (backend,destination) in backends_ipv: + if self._fw.nf_conntrack_helper_setting == 0: + for helper in helpers: + module = helper.module +-- +2.18.0 + diff --git a/firewalld.changes b/firewalld.changes index 93ed5e1..a92cb72 100644 --- a/firewalld.changes +++ b/firewalld.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Mon Sep 17 14:28:19 UTC 2018 - Markos Chandras + +- Add upstream patch to fix Neighbor Discovery filtering for IPv6 (bsc#1105821) + * 0001-nftables-fx-rich-rules-ports-protocols-source-ports.patch +- Add upstream patch to fix building rules for multiple IP families (bsc#1108651) + * 0001-fw_zone-consider-destination-for-protocols.patch + * 0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch + ------------------------------------------------------------------- Sun Sep 2 03:50:37 UTC 2018 - luc14n0@linuxmail.org diff --git a/firewalld.spec b/firewalld.spec index a053d4b..c97dabf 100644 --- a/firewalld.spec +++ b/firewalld.spec @@ -32,6 +32,12 @@ Source: https://github.com/%{name}/%{name}/archive/v%{version}.tar.gz#/% Patch0: 0001-firewall-backend-Switch-default-backend-to-iptables.patch # PATCH-FIX-UPSTREAM firewalld-fix-firewalld-config-crash.patch luc14n0@linuxmail.org -- fix firewall-config crash when nm_get_zone_of_connection returns "False" Patch1: firewalld-fix-firewalld-config-crash.patch +# PATCH-FIX-UPSTREAM 0001-nftables-fix-rich-rules-ports-protocols-source-ports.patch (bsc#1105821) +Patch2: 0001-nftables-fix-rich-rules-ports-protocols-source-ports.patch +# PATCH-FIX-UPSTRΕΑΜ 0001-fw_zone-consider-destination-for-protocols.patch +Patch3: 0001-fw_zone-consider-destination-for-protocols.patch +# PATCH-FIX-UPSTREAM 0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch (bsc#1108651) +Patch4: 0002-fw_zone-fix-services-with-multiple-destination-IP-ve.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: desktop-file-utils @@ -116,6 +122,9 @@ firewalld. %setup -q %patch0 -p1 %patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 # bsc#1078223 rm config/services/high-availability.xml