Blame SOURCES/sos-bz2005195-iptables-based-on-ntf.patch

900e1b
From 2ab8ba3ecbd52e452cc554d515e0782801dcb4b6 Mon Sep 17 00:00:00 2001
900e1b
From: Pavel Moravec <pmoravec@redhat.com>
900e1b
Date: Wed, 8 Sep 2021 15:31:48 +0200
900e1b
Subject: [PATCH] [firewalld] collect nft rules in firewall_tables only
900e1b
900e1b
We collect 'nft list ruleset' in both plugins, while:
900e1b
- nft is not shipped by firewalld package, so we should not collect
900e1b
it in firewalld plugin
900e1b
- running the command requires both nf_tables and nfnetlink kmods, so
900e1b
we should use both kmods in the predicate
900e1b
900e1b
Resolves: #2679
900e1b
900e1b
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
900e1b
---
900e1b
 sos/report/plugins/firewall_tables.py | 9 +++++----
900e1b
 sos/report/plugins/firewalld.py       | 8 +-------
900e1b
 2 files changed, 6 insertions(+), 11 deletions(-)
900e1b
900e1b
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
900e1b
index 56058d3bf9..63a7dddeb5 100644
900e1b
--- a/sos/report/plugins/firewall_tables.py
900e1b
+++ b/sos/report/plugins/firewall_tables.py
900e1b
@@ -40,10 +40,11 @@ def collect_nftables(self):
900e1b
         """ Collects nftables rulesets with 'nft' commands if the modules
900e1b
         are present """
900e1b
 
900e1b
-        self.add_cmd_output(
900e1b
-            "nft list ruleset",
900e1b
-            pred=SoSPredicate(self, kmods=['nf_tables'])
900e1b
-        )
900e1b
+        # collect nftables ruleset
900e1b
+        nft_pred = SoSPredicate(self,
900e1b
+                                kmods=['nf_tables', 'nfnetlink'],
900e1b
+                                required={'kmods': 'all'})
900e1b
+        self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
900e1b
 
900e1b
     def setup(self):
900e1b
         # collect iptables -t for any existing table, if we can't read the
900e1b
diff --git a/sos/report/plugins/firewalld.py b/sos/report/plugins/firewalld.py
900e1b
index ec83527ed7..9401bfd239 100644
900e1b
--- a/sos/report/plugins/firewalld.py
900e1b
+++ b/sos/report/plugins/firewalld.py
900e1b
@@ -9,7 +9,7 @@
900e1b
 #
900e1b
 # See the LICENSE file in the source distribution for further information.
900e1b
 
900e1b
-from sos.report.plugins import Plugin, RedHatPlugin, SoSPredicate
900e1b
+from sos.report.plugins import Plugin, RedHatPlugin
900e1b
 
900e1b
 
900e1b
 class FirewallD(Plugin, RedHatPlugin):
900e1b
@@ -35,12 +35,6 @@ def setup(self):
900e1b
             "/var/log/firewalld",
900e1b
         ])
900e1b
 
900e1b
-        # collect nftables ruleset
900e1b
-        nft_pred = SoSPredicate(self,
900e1b
-                                kmods=['nf_tables', 'nfnetlink'],
900e1b
-                                required={'kmods': 'all'})
900e1b
-        self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
900e1b
-
900e1b
         # use a 10s timeout to workaround dbus problems in
900e1b
         # docker containers.
900e1b
         self.add_cmd_output([
900e1b
-- 
900e1b
2.31.1
900e1b
900e1b
900e1b
From 2a7cf53b61943907dc823cf893530b620a87946c Mon Sep 17 00:00:00 2001
900e1b
From: Pavel Moravec <pmoravec@redhat.com>
900e1b
Date: Fri, 15 Oct 2021 22:31:36 +0200
900e1b
Subject: [PATCH 1/3] [report] Use log_skipped_cmd method inside
900e1b
 collect_cmd_output
900e1b
900e1b
Also, remove obsolete parameters of the log_skipped_cmd method.
900e1b
900e1b
Related: #2724
900e1b
900e1b
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
900e1b
---
900e1b
 sos/report/plugins/__init__.py | 26 ++++++++------------------
900e1b
 1 file changed, 8 insertions(+), 18 deletions(-)
900e1b
900e1b
diff --git a/sos/report/plugins/__init__.py b/sos/report/plugins/__init__.py
900e1b
index ec138f83..b60ab5f6 100644
900e1b
--- a/sos/report/plugins/__init__.py
900e1b
+++ b/sos/report/plugins/__init__.py
900e1b
@@ -876,8 +876,7 @@ class Plugin():
900e1b
             return bool(pred)
900e1b
         return False
900e1b
 
900e1b
-    def log_skipped_cmd(self, pred, cmd, kmods=False, services=False,
900e1b
-                        changes=False):
900e1b
+    def log_skipped_cmd(self, cmd, pred, changes=False):
900e1b
         """Log that a command was skipped due to predicate evaluation.
900e1b
 
900e1b
         Emit a warning message indicating that a command was skipped due
900e1b
@@ -887,21 +886,17 @@ class Plugin():
900e1b
         message indicating that the missing data can be collected by using
900e1b
         the "--allow-system-changes" command line option will be included.
900e1b
 
900e1b
-        :param pred:    The predicate that caused the command to be skipped
900e1b
-        :type pred:     ``SoSPredicate``
900e1b
-
900e1b
         :param cmd:     The command that was skipped
900e1b
         :type cmd:      ``str``
900e1b
 
900e1b
-        :param kmods:   Did kernel modules cause the command to be skipped
900e1b
-        :type kmods:    ``bool``
900e1b
-
900e1b
-        :param services: Did services cause the command to be skipped
900e1b
-        :type services: ``bool``
900e1b
+        :param pred:    The predicate that caused the command to be skipped
900e1b
+        :type pred:     ``SoSPredicate``
900e1b
 
900e1b
         :param changes: Is the `--allow-system-changes` enabled
900e1b
         :type changes:  ``bool``
900e1b
         """
900e1b
+        if pred is None:
900e1b
+            pred = SoSPredicate(self)
900e1b
         msg = "skipped command '%s': %s" % (cmd, pred.report_failure())
900e1b
 
900e1b
         if changes:
900e1b
@@ -1700,9 +1693,7 @@ class Plugin():
900e1b
             self.collect_cmds.append(soscmd)
900e1b
             self._log_info("added cmd output '%s'" % soscmd.cmd)
900e1b
         else:
900e1b
-            self.log_skipped_cmd(pred, soscmd.cmd, kmods=bool(pred.kmods),
900e1b
-                                 services=bool(pred.services),
900e1b
-                                 changes=soscmd.changes)
900e1b
+            self.log_skipped_cmd(soscmd.cmd, pred, changes=soscmd.changes)
900e1b
 
900e1b
     def add_cmd_output(self, cmds, suggest_filename=None,
900e1b
                        root_symlink=None, timeout=None, stderr=True,
900e1b
@@ -2112,7 +2103,7 @@ class Plugin():
900e1b
                            root_symlink=False, timeout=None,
900e1b
                            stderr=True, chroot=True, runat=None, env=None,
900e1b
                            binary=False, sizelimit=None, pred=None,
900e1b
-                           subdir=None, tags=[]):
900e1b
+                           changes=False, subdir=None, tags=[]):
900e1b
         """Execute a command and save the output to a file for inclusion in the
900e1b
         report, then return the results for further use by the plugin
900e1b
 
900e1b
@@ -2163,8 +2154,7 @@ class Plugin():
900e1b
         :rtype: ``dict``
900e1b
         """
900e1b
         if not self.test_predicate(cmd=True, pred=pred):
900e1b
-            self._log_info("skipped cmd output '%s' due to predicate (%s)" %
900e1b
-                           (cmd, self.get_predicate(cmd=True, pred=pred)))
900e1b
+            self.log_skipped_cmd(cmd, pred, changes=changes)
900e1b
             return {
900e1b
                 'status': None,  # don't match on if result['status'] checks
900e1b
                 'output': '',
900e1b
-- 
900e1b
2.31.1
900e1b
900e1b
900e1b
From 6b1bea0ffb1df7f8e5001b06cf25f0741b007ddd Mon Sep 17 00:00:00 2001
900e1b
From: Pavel Moravec <pmoravec@redhat.com>
900e1b
Date: Fri, 15 Oct 2021 22:34:01 +0200
900e1b
Subject: [PATCH 2/3] [firewall_tables] call iptables -t  based on nft
900e1b
 list
900e1b
900e1b
If iptables are not realy in use, calling iptables -t 
900e1b
would load corresponding nft table.
900e1b
900e1b
Therefore, call iptables -t only for the tables from "nft list ruleset"
900e1b
output.
900e1b
900e1b
Example: nft list ruleset contains
900e1b
900e1b
table ip mangle {
900e1b
..
900e1b
}
900e1b
900e1b
so we can collect iptable -t mangle -nvL .
900e1b
900e1b
The same applies to ip6tables as well.
900e1b
900e1b
Resolves: #2724
900e1b
900e1b
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
900e1b
---
900e1b
 sos/report/plugins/firewall_tables.py | 29 ++++++++++++++++++++-------
900e1b
 1 file changed, 22 insertions(+), 7 deletions(-)
900e1b
900e1b
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
900e1b
index 63a7ddde..ef04d939 100644
900e1b
--- a/sos/report/plugins/firewall_tables.py
900e1b
+++ b/sos/report/plugins/firewall_tables.py
900e1b
@@ -44,26 +44,41 @@ class firewall_tables(Plugin, IndependentPlugin):
900e1b
         nft_pred = SoSPredicate(self,
900e1b
                                 kmods=['nf_tables', 'nfnetlink'],
900e1b
                                 required={'kmods': 'all'})
900e1b
-        self.add_cmd_output("nft list ruleset", pred=nft_pred, changes=True)
900e1b
+        return self.collect_cmd_output("nft list ruleset", pred=nft_pred,
900e1b
+                                       changes=True)
900e1b
 
900e1b
     def setup(self):
900e1b
+        # first, collect "nft list ruleset" as collecting commands like
900e1b
+        # ip6tables -t mangle -nvL
900e1b
+        # depends on its output
900e1b
+        # store in nft_ip_tables lists of ip[|6] tables from nft list
900e1b
+        nft_list = self.collect_nftables()
900e1b
+        nft_ip_tables = {'ip': [], 'ip6': []}
900e1b
+        nft_lines = nft_list['output'] if nft_list['status'] == 0 else ''
900e1b
+        for line in nft_lines.splitlines():
900e1b
+            words = line.split()[0:3]
900e1b
+            if len(words) == 3 and words[0] == 'table' and \
900e1b
+                    words[1] in nft_ip_tables.keys():
900e1b
+                nft_ip_tables[words[1]].append(words[2])
900e1b
         # collect iptables -t for any existing table, if we can't read the
900e1b
         # tables, collect 2 default ones (mangle, filter)
900e1b
+        # do collect them only when relevant nft list ruleset exists
900e1b
+        default_ip_tables = "mangle\nfilter\n"
900e1b
         try:
900e1b
             ip_tables_names = open("/proc/net/ip_tables_names").read()
900e1b
         except IOError:
900e1b
-            ip_tables_names = "mangle\nfilter\n"
900e1b
+            ip_tables_names = default_ip_tables
900e1b
         for table in ip_tables_names.splitlines():
900e1b
-            self.collect_iptable(table)
900e1b
+            if nft_list['status'] == 0 and table in nft_ip_tables['ip']:
900e1b
+                self.collect_iptable(table)
900e1b
         # collect the same for ip6tables
900e1b
         try:
900e1b
             ip_tables_names = open("/proc/net/ip6_tables_names").read()
900e1b
         except IOError:
900e1b
-            ip_tables_names = "mangle\nfilter\n"
900e1b
+            ip_tables_names = default_ip_tables
900e1b
         for table in ip_tables_names.splitlines():
900e1b
-            self.collect_ip6table(table)
900e1b
-
900e1b
-        self.collect_nftables()
900e1b
+            if nft_list['status'] == 0 and table in nft_ip_tables['ip6']:
900e1b
+                self.collect_ip6table(table)
900e1b
 
900e1b
         # When iptables is called it will load the modules
900e1b
         # iptables_filter (for kernel <= 3) or
900e1b
-- 
900e1b
2.31.1
900e1b
900e1b
900e1b
From 464bd2d2e83f203e369f2ba7671bbb7da53e06f6 Mon Sep 17 00:00:00 2001
900e1b
From: Pavel Moravec <pmoravec@redhat.com>
900e1b
Date: Sun, 24 Oct 2021 16:00:31 +0200
900e1b
Subject: [PATCH 3/3] [firewall_tables] Call iptables only when nft ip filter
900e1b
 table exists
900e1b
900e1b
iptables -vnxL creates nft 'ip filter' table if it does not exist, hence
900e1b
we must guard iptables execution by presence of the nft table.
900e1b
900e1b
An equivalent logic applies to ip6tables.
900e1b
900e1b
Resolves: #2724
900e1b
900e1b
Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
900e1b
---
900e1b
 sos/report/plugins/firewall_tables.py | 26 ++++++++++++++------------
900e1b
 1 file changed, 14 insertions(+), 12 deletions(-)
900e1b
900e1b
diff --git a/sos/report/plugins/firewall_tables.py b/sos/report/plugins/firewall_tables.py
900e1b
index ef04d939..7eafd60f 100644
900e1b
--- a/sos/report/plugins/firewall_tables.py
900e1b
+++ b/sos/report/plugins/firewall_tables.py
900e1b
@@ -80,19 +80,21 @@ class firewall_tables(Plugin, IndependentPlugin):
900e1b
             if nft_list['status'] == 0 and table in nft_ip_tables['ip6']:
900e1b
                 self.collect_ip6table(table)
900e1b
 
900e1b
-        # When iptables is called it will load the modules
900e1b
-        # iptables_filter (for kernel <= 3) or
900e1b
-        # nf_tables (for kernel >= 4) if they are not loaded.
900e1b
+        # When iptables is called it will load:
900e1b
+        # 1) the modules iptables_filter (for kernel <= 3) or
900e1b
+        #    nf_tables (for kernel >= 4) if they are not loaded.
900e1b
+        # 2) nft 'ip filter' table will be created
900e1b
         # The same goes for ipv6.
900e1b
-        self.add_cmd_output(
900e1b
-            "iptables -vnxL",
900e1b
-            pred=SoSPredicate(self, kmods=['iptable_filter', 'nf_tables'])
900e1b
-        )
900e1b
-
900e1b
-        self.add_cmd_output(
900e1b
-            "ip6tables -vnxL",
900e1b
-            pred=SoSPredicate(self, kmods=['ip6table_filter', 'nf_tables'])
900e1b
-        )
900e1b
+        if nft_list['status'] != 0 or 'filter' in nft_ip_tables['ip']:
900e1b
+            self.add_cmd_output(
900e1b
+                "iptables -vnxL",
900e1b
+                pred=SoSPredicate(self, kmods=['iptable_filter', 'nf_tables'])
900e1b
+            )
900e1b
+        if nft_list['status'] != 0 or 'filter' in nft_ip_tables['ip6']:
900e1b
+            self.add_cmd_output(
900e1b
+                "ip6tables -vnxL",
900e1b
+                pred=SoSPredicate(self, kmods=['ip6table_filter', 'nf_tables'])
900e1b
+            )
900e1b
 
900e1b
         self.add_copy_spec([
900e1b
             "/etc/nftables",
900e1b
-- 
900e1b
2.31.1
900e1b