From ed67750b94e8bc779ec0e2cf6d568a3f7292de13 Mon Sep 17 00:00:00 2001 From: sarthurdev <965089+sarthurdev@users.noreply.github.com> Date: Sat, 29 Jan 2022 13:18:28 +0100 Subject: firewall: T4218: Adds a prefix to all user defined chains --- src/conf_mode/firewall-interface.py | 11 +++++++---- src/conf_mode/firewall.py | 7 +++++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/firewall-interface.py b/src/conf_mode/firewall-interface.py index a7442ecbd..9a5d278e9 100755 --- a/src/conf_mode/firewall-interface.py +++ b/src/conf_mode/firewall-interface.py @@ -31,6 +31,9 @@ from vyos import ConfigError from vyos import airbag airbag.enable() +NAME_PREFIX = 'NAME_' +NAME6_PREFIX = 'NAME6_' + NFT_CHAINS = { 'in': 'VYOS_FW_FORWARD', 'out': 'VYOS_FW_FORWARD', @@ -127,7 +130,7 @@ def apply(if_firewall): name = dict_search_args(if_firewall, direction, 'name') if name: - rule_exists = cleanup_rule('ip filter', chain, if_prefix, ifname, name) + rule_exists = cleanup_rule('ip filter', chain, if_prefix, ifname, f'{NAME_PREFIX}{name}') if not rule_exists: rule_action = 'insert' @@ -138,13 +141,13 @@ def apply(if_firewall): rule_action = 'add' rule_prefix = f'position {handle}' - run(f'nft {rule_action} rule ip filter {chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {name}') + run(f'nft {rule_action} rule ip filter {chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME_PREFIX}{name}') else: cleanup_rule('ip filter', chain, if_prefix, ifname) ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name') if ipv6_name: - rule_exists = cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname, ipv6_name) + rule_exists = cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname, f'{NAME6_PREFIX}{ipv6_name}') if not rule_exists: rule_action = 'insert' @@ -155,7 +158,7 @@ def apply(if_firewall): rule_action = 'add' rule_prefix = f'position {handle}' - run(f'nft {rule_action} rule ip6 filter {ipv6_chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {ipv6_name}') + run(f'nft {rule_action} rule ip6 filter {ipv6_chain} {rule_prefix} {if_prefix}ifname {ifname} counter jump {NAME6_PREFIX}{ipv6_name}') else: cleanup_rule('ip6 filter', ipv6_chain, if_prefix, ifname) diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 358b938e3..5b6c57d04 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -54,6 +54,9 @@ sysfs_config = { 'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337'} } +NAME_PREFIX = 'NAME_' +NAME6_PREFIX = 'NAME6_' + preserve_chains = [ 'INPUT', 'FORWARD', @@ -281,9 +284,9 @@ def cleanup_commands(firewall): else: commands.append(f'flush chain {table} {chain}') elif chain not in preserve_chains and not chain.startswith("VZONE"): - if table == 'ip filter' and dict_search_args(firewall, 'name', chain): + if table == 'ip filter' and dict_search_args(firewall, 'name', chain.replace(NAME_PREFIX, "", 1)): commands.append(f'flush chain {table} {chain}') - elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain): + elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain.replace(NAME6_PREFIX, "", 1)): commands.append(f'flush chain {table} {chain}') else: commands += cleanup_rule(table, chain) -- cgit v1.2.3 From 985a9e8536cb7f049e82dd1c7333ecced34563fa Mon Sep 17 00:00:00 2001 From: sarthurdev <965089+sarthurdev@users.noreply.github.com> Date: Sat, 29 Jan 2022 23:34:05 +0100 Subject: firewall: T4216: Add support for negated firewall groups --- python/vyos/firewall.py | 25 +++++++++++++++++++++---- src/conf_mode/firewall.py | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src/conf_mode') diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index a2e133217..a74fd922a 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -104,13 +104,25 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): group = side_conf['group'] if 'address_group' in group: group_name = group['address_group'] - output.append(f'{ip_name} {prefix}addr $A{def_suffix}_{group_name}') + operator = '' + if group_name[0] == '!': + operator = '!=' + group_name = group_name[1:] + output.append(f'{ip_name} {prefix}addr {operator} $A{def_suffix}_{group_name}') elif 'network_group' in group: group_name = group['network_group'] - output.append(f'{ip_name} {prefix}addr $N{def_suffix}_{group_name}') + operator = '' + if group_name[0] == '!': + operator = '!=' + group_name = group_name[1:] + output.append(f'{ip_name} {prefix}addr {operator} $N{def_suffix}_{group_name}') if 'mac_group' in group: group_name = group['mac_group'] - output.append(f'ether {prefix}addr $M_{group_name}') + operator = '' + if group_name[0] == '!': + operator = '!=' + group_name = group_name[1:] + output.append(f'ether {prefix}addr {operator} $M_{group_name}') if 'port_group' in group: proto = rule_conf['protocol'] group_name = group['port_group'] @@ -118,7 +130,12 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): if proto == 'tcp_udp': proto = 'th' - output.append(f'{proto} {prefix}port $P_{group_name}') + operator = '' + if group_name[0] == '!': + operator = '!=' + group_name = group_name[1:] + + output.append(f'{proto} {prefix}port {operator} $P_{group_name}') if 'log' in rule_conf and rule_conf['log'] == 'enable': action = rule_conf['action'] if 'action' in rule_conf else 'accept' diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 5b6c57d04..064b2d5a3 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -204,6 +204,10 @@ def verify_rule(firewall, rule_conf, ipv6): for group in valid_groups: if group in side_conf['group']: group_name = side_conf['group'][group] + + if group_name and group_name[0] == '!': + group_name = group_name[1:] + fw_group = f'ipv6_{group}' if ipv6 and group in ['address_group', 'network_group'] else group error_group = fw_group.replace("_", "-") group_obj = dict_search_args(firewall, 'group', fw_group, group_name) -- cgit v1.2.3 From 8532f2c391e895d7cd4c10b6d83d1e26973202a3 Mon Sep 17 00:00:00 2001 From: sarthurdev <965089+sarthurdev@users.noreply.github.com> Date: Sun, 30 Jan 2022 00:07:35 +0100 Subject: policy: T4213: Fix duplicate commands from multiple rules with single table --- src/conf_mode/policy-route.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/conf_mode') diff --git a/src/conf_mode/policy-route.py b/src/conf_mode/policy-route.py index 7dcab4b58..82f668acf 100755 --- a/src/conf_mode/policy-route.py +++ b/src/conf_mode/policy-route.py @@ -206,6 +206,7 @@ def apply_table_marks(policy): for route in ['route', 'route6']: if route in policy: cmd_str = 'ip' if route == 'route' else 'ip -6' + tables = [] for name, pol_conf in policy[route].items(): if 'rule' in pol_conf: for rule_id, rule_conf in pol_conf['rule'].items(): @@ -213,6 +214,9 @@ def apply_table_marks(policy): if set_table: if set_table == 'main': set_table = '254' + if set_table in tables: + continue + tables.append(set_table) table_mark = mark_offset - int(set_table) cmd(f'{cmd_str} rule add pref {set_table} fwmark {table_mark} table {set_table}') -- cgit v1.2.3 From ff2cc45f8ba6d7ad1bc75ef384643692a54f31cc Mon Sep 17 00:00:00 2001 From: sarthurdev <965089+sarthurdev@users.noreply.github.com> Date: Sun, 30 Jan 2022 22:52:49 +0100 Subject: firewall: T2199: Fix errors when referencing an empty chain --- src/conf_mode/firewall.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 064b2d5a3..9dec2143e 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -73,6 +73,9 @@ preserve_chains = [ 'VYOS_FRAG6_MARK' ] +nft_iface_chains = ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'] +nft6_iface_chains = ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL'] + valid_groups = [ 'address_group', 'network_group', @@ -248,27 +251,29 @@ def verify(firewall): name = dict_search_args(if_firewall, direction, 'name') ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name') - if name and not dict_search_args(firewall, 'name', name): + if name and dict_search_args(firewall, 'name', name) == None: raise ConfigError(f'Firewall name "{name}" is still referenced on interface {ifname}') - if ipv6_name and not dict_search_args(firewall, 'ipv6_name', ipv6_name): + if ipv6_name and dict_search_args(firewall, 'ipv6_name', ipv6_name) == None: raise ConfigError(f'Firewall ipv6-name "{ipv6_name}" is still referenced on interface {ifname}') for fw_name, used_names in firewall['zone_policy'].items(): for name in used_names: - if not dict_search_args(firewall, fw_name, name): + if dict_search_args(firewall, fw_name, name) == None: raise ConfigError(f'Firewall {fw_name.replace("_", "-")} "{name}" is still referenced in zone-policy') return None def cleanup_rule(table, jump_chain): commands = [] - results = cmd(f'nft -a list table {table}').split("\n") - for line in results: - if f'jump {jump_chain}' in line: - handle_search = re.search('handle (\d+)', line) - if handle_search: - commands.append(f'delete rule {table} {chain} handle {handle_search[1]}') + chains = nft_iface_chains if table == 'ip filter' else nft6_iface_chains + for chain in chains: + results = cmd(f'nft -a list chain {table} {chain}').split("\n") + for line in results: + if f'jump {jump_chain}' in line: + handle_search = re.search('handle (\d+)', line) + if handle_search: + commands.append(f'delete rule {table} {chain} handle {handle_search[1]}') return commands def cleanup_commands(firewall): @@ -288,9 +293,9 @@ def cleanup_commands(firewall): else: commands.append(f'flush chain {table} {chain}') elif chain not in preserve_chains and not chain.startswith("VZONE"): - if table == 'ip filter' and dict_search_args(firewall, 'name', chain.replace(NAME_PREFIX, "", 1)): + if table == 'ip filter' and dict_search_args(firewall, 'name', chain.replace(NAME_PREFIX, "", 1)) != None: commands.append(f'flush chain {table} {chain}') - elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain.replace(NAME6_PREFIX, "", 1)): + elif table == 'ip6 filter' and dict_search_args(firewall, 'ipv6_name', chain.replace(NAME6_PREFIX, "", 1)) != None: commands.append(f'flush chain {table} {chain}') else: commands += cleanup_rule(table, chain) -- cgit v1.2.3