|
|
63f414 |
From 3d7ec2dabb164cbc2dce5aa8aa37ae156ebad275 Mon Sep 17 00:00:00 2001
|
|
|
63f414 |
From: Eric Garver <eric@garver.life>
|
|
|
63f414 |
Date: Tue, 23 Feb 2021 09:18:33 -0500
|
|
|
63f414 |
Subject: [PATCH 36/36] fix(ipset): disallow overlapping entries
|
|
|
63f414 |
|
|
|
63f414 |
These are already being blocked by the ipset backend, but we should
|
|
|
63f414 |
catch them higher up to avoid differences in the backends.
|
|
|
63f414 |
|
|
|
63f414 |
(cherry picked from commit 5b4e8918715a1d2e4abf77ed4eb3252486a19109)
|
|
|
63f414 |
---
|
|
|
63f414 |
src/firewall/client.py | 4 +++-
|
|
|
63f414 |
src/firewall/core/fw_ipset.py | 4 +++-
|
|
|
63f414 |
src/firewall/core/ipset.py | 13 +++++++++++++
|
|
|
63f414 |
src/firewall/server/config_ipset.py | 5 ++++-
|
|
|
63f414 |
src/tests/regression/ipset_netmask_allowed.at | 14 ++++++++------
|
|
|
63f414 |
5 files changed, 31 insertions(+), 9 deletions(-)
|
|
|
63f414 |
|
|
|
63f414 |
diff --git a/src/firewall/client.py b/src/firewall/client.py
|
|
|
63f414 |
index aa6bd7cd282b..3715ffd29316 100644
|
|
|
63f414 |
--- a/src/firewall/client.py
|
|
|
63f414 |
+++ b/src/firewall/client.py
|
|
|
63f414 |
@@ -34,7 +34,7 @@ from firewall.core.base import DEFAULT_ZONE_TARGET, DEFAULT_POLICY_TARGET, DEFAU
|
|
|
63f414 |
from firewall.dbus_utils import dbus_to_python
|
|
|
63f414 |
from firewall.functions import b2u
|
|
|
63f414 |
from firewall.core.rich import Rich_Rule
|
|
|
63f414 |
-from firewall.core.ipset import normalize_ipset_entry
|
|
|
63f414 |
+from firewall.core.ipset import normalize_ipset_entry, check_entry_overlaps_existing
|
|
|
63f414 |
from firewall import errors
|
|
|
63f414 |
from firewall.errors import FirewallError
|
|
|
63f414 |
|
|
|
63f414 |
@@ -1619,6 +1619,7 @@ class FirewallClientIPSetSettings(object):
|
|
|
63f414 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
63f414 |
_entries = set()
|
|
|
63f414 |
for _entry in dbus_to_python(entries, list):
|
|
|
63f414 |
+ check_entry_overlaps_existing(_entry, _entries)
|
|
|
63f414 |
_entries.add(normalize_ipset_entry(_entry))
|
|
|
63f414 |
self.settings[5] = list(_entries)
|
|
|
63f414 |
@handle_exceptions
|
|
|
63f414 |
@@ -1628,6 +1629,7 @@ class FirewallClientIPSetSettings(object):
|
|
|
63f414 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
63f414 |
entry = normalize_ipset_entry(entry)
|
|
|
63f414 |
if entry not in self.settings[5]:
|
|
|
63f414 |
+ check_entry_overlaps_existing(entry, self.settings[5])
|
|
|
63f414 |
self.settings[5].append(entry)
|
|
|
63f414 |
else:
|
|
|
63f414 |
raise FirewallError(errors.ALREADY_ENABLED, entry)
|
|
|
63f414 |
diff --git a/src/firewall/core/fw_ipset.py b/src/firewall/core/fw_ipset.py
|
|
|
63f414 |
index e5348949413c..a285fd4a4aab 100644
|
|
|
63f414 |
--- a/src/firewall/core/fw_ipset.py
|
|
|
63f414 |
+++ b/src/firewall/core/fw_ipset.py
|
|
|
63f414 |
@@ -25,7 +25,7 @@ __all__ = [ "FirewallIPSet" ]
|
|
|
63f414 |
|
|
|
63f414 |
from firewall.core.logger import log
|
|
|
63f414 |
from firewall.core.ipset import remove_default_create_options as rm_def_cr_opts, \
|
|
|
63f414 |
- normalize_ipset_entry
|
|
|
63f414 |
+ normalize_ipset_entry, check_entry_overlaps_existing
|
|
|
63f414 |
from firewall.core.io.ipset import IPSet
|
|
|
63f414 |
from firewall import errors
|
|
|
63f414 |
from firewall.errors import FirewallError
|
|
|
63f414 |
@@ -196,6 +196,7 @@ class FirewallIPSet(object):
|
|
|
63f414 |
if entry in obj.entries:
|
|
|
63f414 |
raise FirewallError(errors.ALREADY_ENABLED,
|
|
|
63f414 |
"'%s' already is in '%s'" % (entry, name))
|
|
|
63f414 |
+ check_entry_overlaps_existing(entry, obj.entries)
|
|
|
63f414 |
|
|
|
63f414 |
try:
|
|
|
63f414 |
for backend in self.backends():
|
|
|
63f414 |
@@ -245,6 +246,7 @@ class FirewallIPSet(object):
|
|
|
63f414 |
|
|
|
63f414 |
_entries = set()
|
|
|
63f414 |
for _entry in entries:
|
|
|
63f414 |
+ check_entry_overlaps_existing(_entry, _entries)
|
|
|
63f414 |
_entries.add(normalize_ipset_entry(_entry))
|
|
|
63f414 |
entries = list(_entries)
|
|
|
63f414 |
|
|
|
63f414 |
diff --git a/src/firewall/core/ipset.py b/src/firewall/core/ipset.py
|
|
|
63f414 |
index 5bb21856f648..d6defa395241 100644
|
|
|
63f414 |
--- a/src/firewall/core/ipset.py
|
|
|
63f414 |
+++ b/src/firewall/core/ipset.py
|
|
|
63f414 |
@@ -302,3 +302,16 @@ def normalize_ipset_entry(entry):
|
|
|
63f414 |
_entry.append(_part)
|
|
|
63f414 |
|
|
|
63f414 |
return ",".join(_entry)
|
|
|
63f414 |
+
|
|
|
63f414 |
+def check_entry_overlaps_existing(entry, entries):
|
|
|
63f414 |
+ """ Check if entry overlaps any entry in the list of entries """
|
|
|
63f414 |
+ # Only check simple types
|
|
|
63f414 |
+ if len(entry.split(",")) > 1:
|
|
|
63f414 |
+ return
|
|
|
63f414 |
+
|
|
|
63f414 |
+ for itr in entries:
|
|
|
63f414 |
+ try:
|
|
|
63f414 |
+ if ipaddress.ip_network(itr, strict=False).overlaps(ipaddress.ip_network(entry, strict=False)):
|
|
|
63f414 |
+ raise FirewallError(errors.INVALID_ENTRY, "Entry '{}' overlaps with existing entry '{}'".format(itr, entry))
|
|
|
63f414 |
+ except ValueError:
|
|
|
63f414 |
+ pass
|
|
|
63f414 |
diff --git a/src/firewall/server/config_ipset.py b/src/firewall/server/config_ipset.py
|
|
|
63f414 |
index 18ef5783de62..f33c2a02926f 100644
|
|
|
63f414 |
--- a/src/firewall/server/config_ipset.py
|
|
|
63f414 |
+++ b/src/firewall/server/config_ipset.py
|
|
|
63f414 |
@@ -33,7 +33,8 @@ from firewall.dbus_utils import dbus_to_python, \
|
|
|
63f414 |
dbus_introspection_prepare_properties, \
|
|
|
63f414 |
dbus_introspection_add_properties
|
|
|
63f414 |
from firewall.core.io.ipset import IPSet
|
|
|
63f414 |
-from firewall.core.ipset import IPSET_TYPES, normalize_ipset_entry
|
|
|
63f414 |
+from firewall.core.ipset import IPSET_TYPES, normalize_ipset_entry, \
|
|
|
63f414 |
+ check_entry_overlaps_existing
|
|
|
63f414 |
from firewall.core.logger import log
|
|
|
63f414 |
from firewall.server.decorators import handle_exceptions, \
|
|
|
63f414 |
dbus_handle_exceptions, dbus_service_method
|
|
|
63f414 |
@@ -408,6 +409,7 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
63f414 |
def setEntries(self, entries, sender=None):
|
|
|
63f414 |
_entries = set()
|
|
|
63f414 |
for _entry in dbus_to_python(entries, list):
|
|
|
63f414 |
+ check_entry_overlaps_existing(_entry, _entries)
|
|
|
63f414 |
_entries.add(normalize_ipset_entry(_entry))
|
|
|
63f414 |
entries = list(_entries)
|
|
|
63f414 |
log.debug1("%s.setEntries('[%s]')", self._log_prefix,
|
|
|
63f414 |
@@ -432,6 +434,7 @@ class FirewallDConfigIPSet(slip.dbus.service.Object):
|
|
|
63f414 |
raise FirewallError(errors.IPSET_WITH_TIMEOUT)
|
|
|
63f414 |
if entry in settings[5]:
|
|
|
63f414 |
raise FirewallError(errors.ALREADY_ENABLED, entry)
|
|
|
63f414 |
+ check_entry_overlaps_existing(entry, settings[5])
|
|
|
63f414 |
settings[5].append(entry)
|
|
|
63f414 |
self.update(settings)
|
|
|
63f414 |
|
|
|
63f414 |
diff --git a/src/tests/regression/ipset_netmask_allowed.at b/src/tests/regression/ipset_netmask_allowed.at
|
|
|
63f414 |
index b5165d94b220..fd08afd3b57c 100644
|
|
|
63f414 |
--- a/src/tests/regression/ipset_netmask_allowed.at
|
|
|
63f414 |
+++ b/src/tests/regression/ipset_netmask_allowed.at
|
|
|
63f414 |
@@ -9,15 +9,17 @@ dnl an add for the whole range. i.e. 1.2.3.4/24 --> 1.2.3.[0.255] (256
|
|
|
63f414 |
dnl entries).
|
|
|
63f414 |
dnl
|
|
|
63f414 |
dnl In nftables, we allow this by using actual intervals.
|
|
|
63f414 |
-FWD_CHECK([--permanent --ipset foobar --add-entry 1.2.3.0/24], 0, [ignore])
|
|
|
63f414 |
-FWD_CHECK([ --ipset foobar --add-entry 1.2.3.0/24], 0, [ignore])
|
|
|
63f414 |
+FWD_CHECK([--permanent --ipset foobar --add-entry 1.2.3.4/24], 0, [ignore])
|
|
|
63f414 |
+FWD_CHECK([ --ipset foobar --add-entry 1.2.3.4/24], 0, [ignore])
|
|
|
63f414 |
|
|
|
63f414 |
dnl check the edge case
|
|
|
63f414 |
FWD_CHECK([--permanent --ipset foobar --add-entry 4.3.2.1/32], 0, [ignore])
|
|
|
63f414 |
FWD_CHECK([ --ipset foobar --add-entry 4.3.2.1/32], 0, [ignore])
|
|
|
63f414 |
|
|
|
63f414 |
-dnl overlaps should be denied by ipset
|
|
|
63f414 |
-FWD_CHECK([ --ipset foobar --add-entry 1.2.3.0/22], 13, [ignore], [ignore])
|
|
|
63f414 |
-FWD_CHECK([ --ipset foobar --add-entry 1.2.3.0/30], 13, [ignore], [ignore])
|
|
|
63f414 |
+dnl overlaps should be denied
|
|
|
63f414 |
+FWD_CHECK([--permanent --ipset foobar --add-entry 1.2.3.0/22], 136, [ignore], [ignore])
|
|
|
63f414 |
+FWD_CHECK([ --ipset foobar --add-entry 1.2.3.0/22], 136, [ignore], [ignore])
|
|
|
63f414 |
+FWD_CHECK([--permanent --ipset foobar --add-entry 1.2.3.4/30], 136, [ignore], [ignore])
|
|
|
63f414 |
+FWD_CHECK([ --ipset foobar --add-entry 1.2.3.4/30], 136, [ignore], [ignore])
|
|
|
63f414 |
|
|
|
63f414 |
-FWD_END_TEST([-e '/ERROR: COMMAND_FAILED:/d'])
|
|
|
63f414 |
+FWD_END_TEST([-e '/ERROR: INVALID_ENTRY:/d'])
|
|
|
63f414 |
--
|
|
|
63f414 |
2.27.0
|
|
|
63f414 |
|