From 85710cee8fe970cab1699f781df876761bd3cd3c Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Thu, 12 Aug 2021 00:56:41 +0200
Subject: firewall: T2199: Migrate firewall op-mode to XML/Python
---
op-mode-definitions/firewall.xml.in | 178 ++++++++++++++++++++++++++++++++++++
1 file changed, 178 insertions(+)
create mode 100644 op-mode-definitions/firewall.xml.in
(limited to 'op-mode-definitions')
diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in
new file mode 100644
index 000000000..84df67b3d
--- /dev/null
+++ b/op-mode-definitions/firewall.xml.in
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+ Show firewall information
+
+
+
+
+ Show firewall group
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show_group --name $4
+
+
+
+ Show IPv6 firewall chains
+
+ firewall ipv6-name
+
+
+
+
+
+ Show summary of IPv6 firewall rules
+
+ firewall ipv6-name ${COMP_WORDS[6]} rule
+
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6 --ipv6
+
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --ipv6
+
+
+
+ Show IPv4 firewall chains
+
+ firewall name
+
+
+
+
+
+ Show summary of IPv4 firewall rules
+
+ firewall name ${COMP_WORDS[6]} rule
+
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6
+
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4
+
+
+
+ Show statistics of firewall application
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show_statistics
+
+
+
+ Show summary of firewall application
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show_summary
+
+
+ sudo ${vyos_op_scripts_dir}/firewall.py --action show_all
+
+
+
+
--
cgit v1.2.3
From 3ebb08893b4bbd016bd0eb04374be5f691ad4abb Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Thu, 12 Aug 2021 01:00:59 +0200
Subject: zone-policy: T2199: Migrate zone-policy op-mode to XML/Python
---
op-mode-definitions/zone-policy.xml.in | 24 ++++++++++
src/op_mode/zone_policy.py | 81 ++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+)
create mode 100644 op-mode-definitions/zone-policy.xml.in
create mode 100755 src/op_mode/zone_policy.py
(limited to 'op-mode-definitions')
diff --git a/op-mode-definitions/zone-policy.xml.in b/op-mode-definitions/zone-policy.xml.in
new file mode 100644
index 000000000..c4b02bcee
--- /dev/null
+++ b/op-mode-definitions/zone-policy.xml.in
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ Show zone policy information
+
+
+
+
+ Show summary of zone policy for a specific zone
+
+ zone-policy zone
+
+
+ sudo ${vyos_op_scripts_dir}/zone_policy.py --action show --name $4
+
+
+ sudo ${vyos_op_scripts_dir}/zone_policy.py --action show
+
+
+
+
diff --git a/src/op_mode/zone_policy.py b/src/op_mode/zone_policy.py
new file mode 100755
index 000000000..7b43018c2
--- /dev/null
+++ b/src/op_mode/zone_policy.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import argparse
+import tabulate
+
+from vyos.config import Config
+from vyos.util import dict_search_args
+
+def get_config_zone(conf, name=None):
+ config_path = ['zone-policy']
+ if name:
+ config_path += ['zone', name]
+
+ zone_policy = conf.get_config_dict(config_path, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ return zone_policy
+
+def output_zone_name(zone, zone_conf):
+ print(f'\n---------------------------------\nZone: "{zone}"\n')
+
+ interfaces = ', '.join(zone_conf['interface']) if 'interface' in zone_conf else ''
+ if 'local_zone' in zone_conf:
+ interfaces = 'LOCAL'
+
+ print(f'Interfaces: {interfaces}\n')
+
+ header = ['From Zone', 'Firewall']
+ rows = []
+
+ if 'from' in zone_conf:
+ for from_name, from_conf in zone_conf['from'].items():
+ row = [from_name]
+ v4_name = dict_search_args(from_conf, 'firewall', 'name')
+ v6_name = dict_search_args(from_conf, 'firewall', 'ipv6_name')
+
+ if v4_name:
+ rows.append(row + [v4_name])
+
+ if v6_name:
+ rows.append(row + [f'{v6_name} [IPv6]'])
+
+ if rows:
+ print('From Zones:\n')
+ print(tabulate.tabulate(rows, header))
+
+def show_zone_policy(zone):
+ conf = Config()
+ zone_policy = get_config_zone(conf, zone)
+
+ if not zone_policy:
+ return
+
+ if 'zone' in zone_policy:
+ for zone, zone_conf in zone_policy['zone'].items():
+ output_zone_name(zone, zone_conf)
+ elif zone:
+ output_zone_name(zone, zone_policy)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Action', required=False)
+ parser.add_argument('--name', help='Zone name', required=False, action='store', nargs='?', default='')
+
+ args = parser.parse_args()
+
+ if args.action == 'show':
+ show_zone_policy(args.name)
--
cgit v1.2.3
From dcd202aeeb890edf289c57305cb0bf07c87df341 Mon Sep 17 00:00:00 2001
From: sarthurdev <965089+sarthurdev@users.noreply.github.com>
Date: Thu, 12 Aug 2021 00:57:00 +0200
Subject: policy: T2199: Migrate policy route op-mode to XML/Python
---
op-mode-definitions/policy-route.xml.in | 143 ++++++++++++++++++++++++
src/op_mode/policy_route.py | 189 ++++++++++++++++++++++++++++++++
2 files changed, 332 insertions(+)
create mode 100644 op-mode-definitions/policy-route.xml.in
create mode 100755 src/op_mode/policy_route.py
(limited to 'op-mode-definitions')
diff --git a/op-mode-definitions/policy-route.xml.in b/op-mode-definitions/policy-route.xml.in
new file mode 100644
index 000000000..c998e5487
--- /dev/null
+++ b/op-mode-definitions/policy-route.xml.in
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+ Show policy information
+
+
+
+
+ Show IPv6 policy chain
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all --ipv6
+
+
+
+ Show IPv6 policy chains
+
+ policy ipv6-route
+
+
+
+
+
+ Show summary of IPv6 policy rules
+
+ policy ipv6-route ${COMP_WORDS[4]} rule
+
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6 --ipv6
+
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --ipv6
+
+
+
+ Show IPv4 policy chain
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show_all
+
+
+
+ Show IPv4 policy chains
+
+ policy route
+
+
+
+
+
+ Show summary of IPv4 policy rules
+
+ policy route ${COMP_WORDS[4]} rule
+
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4 --rule $6
+
+
+ sudo ${vyos_op_scripts_dir}/policy_route.py --action show --name $4
+
+
+
+
+
+
diff --git a/src/op_mode/policy_route.py b/src/op_mode/policy_route.py
new file mode 100755
index 000000000..e0b4ac514
--- /dev/null
+++ b/src/op_mode/policy_route.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import argparse
+import re
+import tabulate
+
+from vyos.config import Config
+from vyos.util import cmd
+from vyos.util import dict_search_args
+
+def get_policy_interfaces(conf, policy, name=None, ipv6=False):
+ interfaces = conf.get_config_dict(['interfaces'], key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+
+ routes = ['route', 'ipv6_route']
+
+ def parse_if(ifname, if_conf):
+ if 'policy' in if_conf:
+ for route in routes:
+ if route in if_conf['policy']:
+ route_name = if_conf['policy'][route]
+ name_str = f'({ifname},{route})'
+
+ if not name:
+ policy[route][route_name]['interface'].append(name_str)
+ elif not ipv6 and name == route_name:
+ policy['interface'].append(name_str)
+
+ for iftype in ['vif', 'vif_s', 'vif_c']:
+ if iftype in if_conf:
+ for vifname, vif_conf in if_conf[iftype].items():
+ parse_if(f'{ifname}.{vifname}', vif_conf)
+
+ for iftype, iftype_conf in interfaces.items():
+ for ifname, if_conf in iftype_conf.items():
+ parse_if(ifname, if_conf)
+
+def get_config_policy(conf, name=None, ipv6=False, interfaces=True):
+ config_path = ['policy']
+ if name:
+ config_path += ['ipv6-route' if ipv6 else 'route', name]
+
+ policy = conf.get_config_dict(config_path, key_mangling=('-', '_'),
+ get_first_key=True, no_tag_node_value_mangle=True)
+ if policy and interfaces:
+ if name:
+ policy['interface'] = []
+ else:
+ if 'route' in policy:
+ for route_name, route_conf in policy['route'].items():
+ route_conf['interface'] = []
+
+ if 'ipv6_route' in policy:
+ for route_name, route_conf in policy['ipv6_route'].items():
+ route_conf['interface'] = []
+
+ get_policy_interfaces(conf, policy, name, ipv6)
+
+ return policy
+
+def get_nftables_details(name, ipv6=False):
+ suffix = '6' if ipv6 else ''
+ command = f'sudo nft list chain ip{suffix} mangle VYOS_PBR{suffix}_{name}'
+ try:
+ results = cmd(command)
+ except:
+ return {}
+
+ out = {}
+ for line in results.split('\n'):
+ comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line)
+ if not comment_search:
+ continue
+
+ rule = {}
+ rule_id = comment_search[1]
+ counter_search = re.search(r'counter packets (\d+) bytes (\d+)', line)
+ if counter_search:
+ rule['packets'] = counter_search[1]
+ rule['bytes'] = counter_search[2]
+
+ rule['conditions'] = re.sub(r'(\b(counter packets \d+ bytes \d+|drop|reject|return|log)\b|comment "[\w\-]+")', '', line).strip()
+ out[rule_id] = rule
+ return out
+
+def output_policy_route(name, route_conf, ipv6=False, single_rule_id=None):
+ ip_str = 'IPv6' if ipv6 else 'IPv4'
+ print(f'\n---------------------------------\n{ip_str} Policy Route "{name}"\n')
+
+ if route_conf['interface']:
+ print('Active on: {0}\n'.format(" ".join(route_conf['interface'])))
+
+ details = get_nftables_details(name, ipv6)
+ rows = []
+
+ if 'rule' in route_conf:
+ for rule_id, rule_conf in route_conf['rule'].items():
+ if single_rule_id and rule_id != single_rule_id:
+ continue
+
+ if 'disable' in rule_conf:
+ continue
+
+ action = rule_conf['action'] if 'action' in rule_conf else 'set'
+ protocol = rule_conf['protocol'] if 'protocol' in rule_conf else 'all'
+
+ row = [rule_id, action, protocol]
+ if rule_id in details:
+ rule_details = details[rule_id]
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ row.append(rule_details['conditions'])
+ rows.append(row)
+
+ if 'default_action' in route_conf and not single_rule_id:
+ row = ['default', route_conf['default_action'], 'all']
+ if 'default-action' in details:
+ rule_details = details['default-action']
+ row.append(rule_details.get('packets', 0))
+ row.append(rule_details.get('bytes', 0))
+ rows.append(row)
+
+ if rows:
+ header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions']
+ print(tabulate.tabulate(rows, header) + '\n')
+
+def show_policy(ipv6=False):
+ print('Ruleset Information')
+
+ conf = Config()
+ policy = get_config_policy(conf)
+
+ if not policy:
+ return
+
+ if not ipv6 and 'route' in policy:
+ for route, route_conf in policy['route'].items():
+ output_policy_route(route, route_conf, ipv6=False)
+
+ if ipv6 and 'ipv6_route' in policy:
+ for route, route_conf in policy['ipv6_route'].items():
+ output_policy_route(route, route_conf, ipv6=True)
+
+def show_policy_name(name, ipv6=False):
+ print('Ruleset Information')
+
+ conf = Config()
+ policy = get_config_policy(conf, name, ipv6)
+ if policy:
+ output_policy_route(name, policy, ipv6)
+
+def show_policy_rule(name, rule_id, ipv6=False):
+ print('Rule Information')
+
+ conf = Config()
+ policy = get_config_policy(conf, name, ipv6)
+ if policy:
+ output_policy_route(name, policy, ipv6, rule_id)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--action', help='Action', required=False)
+ parser.add_argument('--name', help='Policy name', required=False, action='store', nargs='?', default='')
+ parser.add_argument('--rule', help='Policy Rule ID', required=False)
+ parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true')
+
+ args = parser.parse_args()
+
+ if args.action == 'show':
+ if not args.rule:
+ show_policy_name(args.name, args.ipv6)
+ else:
+ show_policy_rule(args.name, args.rule, args.ipv6)
+ elif args.action == 'show_all':
+ show_policy(args.ipv6)
--
cgit v1.2.3