From 6ba1193ff9f5a0767623c3bd2aed073724d0ea11 Mon Sep 17 00:00:00 2001 From: Eric Garver Date: Fri, 3 Nov 2023 12:56:10 -0400 Subject: [PATCH] fix(ipset): fix configuring IP range for ipsets with nftables Resolves: RHEL-13241 --- ...-fix-configuring-IP-range-for-ipsets.patch | 138 ++++++++++++++++++ firewalld.spec | 6 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch diff --git a/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch b/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch new file mode 100644 index 0000000..4de35a1 --- /dev/null +++ b/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch @@ -0,0 +1,138 @@ +From 90412a5fae831dcb1a8c9d9f4a798efabcc46567 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 11 Jul 2023 15:26:56 +0200 +Subject: [PATCH 13/17] v1.2.0: fix(ipset): fix configuring IP range for ipsets + with nftables + +Setting an IP range with nftables did not work: + + firewall-cmd --permanent --delete-ipset=testipset || : + firewall-cmd --permanent --delete-zone=testzone || : + + ENTRY=1.1.1.1-1.1.1.10 + + firewall-cmd --permanent --new-ipset=testipset --type=hash:ip + firewall-cmd --permanent --ipset=testipset --add-entry="$ENTRY" + firewall-cmd --permanent --info-ipset=testipset + firewall-cmd --permanent --new-zone=testzone + firewall-cmd --permanent --zone=testzone --add-rich-rule='rule family="ipv4" source ipset="testipset" service name="ssh" accept' + + firewall-cmd --reload & + +This would generate the following JSON request: + + { + "add": { + "element": { + "family": "inet", + "table": "firewalld", + "name": "testipset", + "elem": [ + "1.1.1.1-1.1.1.10" + ] + } + } + } + +libnftables will try to resolve "1.1.1.1-1.1.1.10" via getaddrinfo(). Calling +getaddrinfo() to resolve names is bound to fail, and it blocks the process for +a very long time. libnftables should not block the calling process ([1]). + +We need to generate the correct JSON request, which is + + { + "add": { + "element": { + "family": "inet", + "table": "firewalld", + "name": "testipset", + "elem": [ + { + "range": [ + "1.1.1.1", + "1.1.1.10" + ] + } + ] + } + } + } + +This is an ugly fix, because the parsing of ipset entries is duplicated +and inconsistent. A better solution for that shall follow. + +[1] https://marc.info/?l=netfilter-devel&m=168901121103612 + +https://bugzilla.redhat.com/show_bug.cgi?id=2028748 + +Fixes: 1582c5dd736a ('feat: nftables: convert to libnftables JSON interface') +(cherry picked from commit 4db89e316f2d60f3cf856a7025a96a61e40b1e5a) +--- + src/firewall/core/nftables.py | 27 +++++++++++++++------------ + src/tests/cli/firewall-cmd.at | 4 ++-- + 2 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 19a649aaaa71..2764bcf93645 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -1850,19 +1850,22 @@ class nftables(object): + fragment.append({"range": [port_str[:index], port_str[index+1:]]}) + + elif type_format[i] in ["ip", "net"]: +- try: +- index = entry_tokens[i].index("/") +- except ValueError: +- addr = entry_tokens[i] +- if "family" in obj.options and obj.options["family"] == "inet6": +- addr = normalizeIP6(addr) +- fragment.append(addr) ++ if '-' in entry_tokens[i]: ++ fragment.append({"range": entry_tokens[i].split('-') }) + else: +- addr = entry_tokens[i][:index] +- if "family" in obj.options and obj.options["family"] == "inet6": +- addr = normalizeIP6(addr) +- fragment.append({"prefix": {"addr": addr, +- "len": int(entry_tokens[i][index+1:])}}) ++ try: ++ index = entry_tokens[i].index("/") ++ except ValueError: ++ addr = entry_tokens[i] ++ if "family" in obj.options and obj.options["family"] == "inet6": ++ addr = normalizeIP6(addr) ++ fragment.append(addr) ++ else: ++ addr = entry_tokens[i][:index] ++ if "family" in obj.options and obj.options["family"] == "inet6": ++ addr = normalizeIP6(addr) ++ fragment.append({"prefix": {"addr": addr, ++ "len": int(entry_tokens[i][index+1:])}}) + else: + fragment.append(entry_tokens[i]) + return [{"concat": fragment}] if len(type_format) > 1 else fragment +diff --git a/src/tests/cli/firewall-cmd.at b/src/tests/cli/firewall-cmd.at +index 47bdd81f5194..c4ab3108d37c 100644 +--- a/src/tests/cli/firewall-cmd.at ++++ b/src/tests/cli/firewall-cmd.at +@@ -908,7 +908,7 @@ FWD_START_TEST([ipset]) + + dnl multi dimensional sets + FWD_CHECK([--permanent --new-ipset=foobar --type=hash:ip,port], 0, ignore) +- FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10,1234], 0, ignore) ++ FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10-10.10.10.12,1234], 0, ignore) + FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10,2000-2100], 0, ignore) + FWD_RELOAD + NFT_LIST_SET([foobar], 0, [dnl +@@ -916,7 +916,7 @@ FWD_START_TEST([ipset]) + set foobar { + type ipv4_addr . inet_proto . inet_service + flags interval +- elements = { 10.10.10.10 . tcp . 1234, ++ elements = { 10.10.10.10-10.10.10.12 . tcp . 1234, + 10.10.10.10 . tcp . 2000-2100 } + } + } +-- +2.39.3 + diff --git a/firewalld.spec b/firewalld.spec index 9f8526f..cb4f0b2 100644 --- a/firewalld.spec +++ b/firewalld.spec @@ -1,7 +1,7 @@ Summary: A firewall daemon with D-Bus interface providing a dynamic firewall Name: firewalld Version: 0.9.11 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.firewalld.org License: GPLv2+ Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.gz @@ -17,6 +17,7 @@ Patch9: 0009-v1.1.0-test-ipset-huge-set-of-entries-benchmark.patch Patch10: 0010-v1.1.0-fix-ipset-further-reduce-cost-of-entry-overla.patch Patch11: 0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch Patch12: 0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch +Patch13: 0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch BuildArch: noarch BuildRequires: autoconf @@ -218,6 +219,9 @@ desktop-file-install --delete-original \ %{_mandir}/man1/firewall-config*.1* %changelog +* Fri Nov 03 2023 Eric Garver - 0.9.11-3 +- fix(ipset): fix configuring IP range for ipsets with nftables + * Fri Nov 03 2023 Eric Garver - 0.9.11-2 - fix(ipset): exception on overlap checking empty set