From f25b58ee8d5b326b9d347002ef9887b7723ec703 Mon Sep 17 00:00:00 2001 From: networkhell <35071549+networkhell@users.noreply.github.com> Date: Fri, 14 Feb 2020 12:02:51 +0100 Subject: [PATCH 1/3] Update iptables_raw.py --- iptables_raw.py | 71 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/iptables_raw.py b/iptables_raw.py index 890b5dc..68e54e5 100644 --- a/iptables_raw.py +++ b/iptables_raw.py @@ -1,6 +1,5 @@ #!/usr/bin/python # -*- coding: utf-8 -*- - # Make coding more python3-ish from __future__ import (absolute_import, division, print_function) __metaclass__ = type @@ -293,6 +292,8 @@ class Iptables: module = None def __init__(self, module, ipversion): + # test + self._ipversion = ipversion # Create directory for json files. if not os.path.exists(self.STATE_DIR): os.makedirs(self.STATE_DIR) @@ -302,7 +303,6 @@ def __init__(self, module, ipversion): self.system_save_path = self._get_system_save_path(ipversion) self.state_dict = self._read_state_file() self.bins = self._get_bins(ipversion) - self.iptables_names_file = self._get_iptables_names_file(ipversion) # Check if we have a required iptables version. self._check_compatibility() # Save active iptables rules for all tables, so that we don't @@ -320,25 +320,63 @@ def _get_bins(self, ipversion): if ipversion == '4': return {'iptables': Iptables.module.get_bin_path('iptables'), 'iptables-save': Iptables.module.get_bin_path('iptables-save'), - 'iptables-restore': Iptables.module.get_bin_path('iptables-restore')} + 'iptables-restore': Iptables.module.get_bin_path('iptables-restore'), + 'nft': Iptables.module.get_bin_path('nft') } else: return {'iptables': Iptables.module.get_bin_path('ip6tables'), 'iptables-save': Iptables.module.get_bin_path('ip6tables-save'), - 'iptables-restore': Iptables.module.get_bin_path('ip6tables-restore')} - - def _get_iptables_names_file(self, ipversion): - if ipversion == '4': - return '/proc/net/ip_tables_names' - else: - return '/proc/net/ip6_tables_names' - - # Return a list of active iptables tables + 'iptables-restore': Iptables.module.get_bin_path('ip6tables-restore'), + 'nft': Iptables.module.get_bin_path('nft') } + + # return list of active tables + # detect if nftables is installed - support for nftables def _get_list_of_active_tables(self): - if os.path.isfile(self.iptables_names_file): - table_names = open(self.iptables_names_file, 'r').read() - return table_names.splitlines() + if self.bins['nft']: + cmd = [self.bins['nft'], '-v'] + rc, stdout, stderr = Iptables.module.run_command(cmd, check_rc=False) + if rc == 0: + if self._ipversion == '4': + cmd = [self.bins['nft'], 'list', 'tables', 'ip', '-j'] + rc, stdout, stderr = Iptables.module.run_command(cmd, check_rc=False) + jsonout = json.loads(stdout) + if rc == 0: + if len(jsonout['nftables']) > 0: + table_names = [] + for table in jsonout['nftables']: + table_names.append(table['table']['name']) + return table_names + else: + return self.TABLES + else: + cmd = [self.bins['nft'], 'list', 'tables', 'ip6', '-j'] + rc, stdout, stderr = Iptables.module.run_command(cmd, check_rc=False) + jsonout = json.loads(stdout) + if rc == 0: + if len(jsonout['nftables']) > 0: + table_names = [] + for table in jsonout['nftables']: + table_names.append(table['table']['name']) + return table_names + else: + return self.TABLES + # assume that no nftables is used --> netfilter fallback else: - return [] + if self._ipversion == '4': + iptables_names_file = '/proc/net/ip_tables_names' + if os.path.isfile(iptables_names_file): + table_names = open(iptables_names_file, 'r').read() + if table_names: + return table_names.splitlines() + else: + return self.TABLES + else: + iptables_names_file = '/proc/net/ip6_tables_names' + if os.path.isfile(iptables_names_file): + table_names = open(iptables_names_file, 'r').read() + if table_names: + return table_names.splitlines() + else: + return self.TABLES # If /etc/debian_version exist, this means this is a debian based OS (Ubuntu, Mint, etc...) def _is_debian(self): @@ -902,6 +940,7 @@ def _system_save_active(self, backup=False): all_active_rules = self._get_active_rules(table='*', clean=False) # Move iptables-save dump of all tables to the iptables_save_path self._write_rules_to_file(all_active_rules, self.system_save_path) + print('all_active_rules') # Apply table dict rules to the system. def system_apply_table_rules(self, table, test=False): From c1fd9a407c2dde5c7f487d8e8be9ee008028dd6f Mon Sep 17 00:00:00 2001 From: networkhell <35071549+networkhell@users.noreply.github.com> Date: Fri, 14 Feb 2020 12:20:55 +0100 Subject: [PATCH 2/3] Update iptables_raw.py --- iptables_raw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iptables_raw.py b/iptables_raw.py index 68e54e5..f0243ce 100644 --- a/iptables_raw.py +++ b/iptables_raw.py @@ -292,7 +292,7 @@ class Iptables: module = None def __init__(self, module, ipversion): - # test + # make ipversion available to all functions self._ipversion = ipversion # Create directory for json files. if not os.path.exists(self.STATE_DIR): From 445ff12b3c5f1c41154f70f8f87ddf8f8f309874 Mon Sep 17 00:00:00 2001 From: networkhell <35071549+networkhell@users.noreply.github.com> Date: Fri, 14 Feb 2020 12:45:06 +0100 Subject: [PATCH 3/3] Make module compatible with nftables On systems using netfilter, nftables should not be installed, on systems using the new nftables backend, nftables and the nft command have to be installed. --- iptables_raw.py | 1 - 1 file changed, 1 deletion(-) diff --git a/iptables_raw.py b/iptables_raw.py index f0243ce..45db5c6 100644 --- a/iptables_raw.py +++ b/iptables_raw.py @@ -940,7 +940,6 @@ def _system_save_active(self, backup=False): all_active_rules = self._get_active_rules(table='*', clean=False) # Move iptables-save dump of all tables to the iptables_save_path self._write_rules_to_file(all_active_rules, self.system_save_path) - print('all_active_rules') # Apply table dict rules to the system. def system_apply_table_rules(self, table, test=False):