summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2022-01-31 19:26:37 +0100
committerGitHub <noreply@github.com>2022-01-31 19:26:37 +0100
commit36e54482a242e785c7a052035549bb45a117ea9a (patch)
tree3d947addcb9ea4c375e2771eed68e393e9295cbe /src
parent3aa1ec3f03a95ad41d3476b92b8b31a68b516b14 (diff)
parentff2cc45f8ba6d7ad1bc75ef384643692a54f31cc (diff)
downloadvyos-1x-36e54482a242e785c7a052035549bb45a117ea9a.tar.gz
vyos-1x-36e54482a242e785c7a052035549bb45a117ea9a.zip
Merge pull request #1199 from sarthurdev/T4218
firewall: T4218: T4216: Add prefix to user defined chains, support negated groups, fixes
Diffstat (limited to 'src')
-rwxr-xr-xsrc/conf_mode/firewall-interface.py11
-rwxr-xr-xsrc/conf_mode/firewall.py34
-rwxr-xr-xsrc/conf_mode/policy-route.py4
-rwxr-xr-xsrc/op_mode/firewall.py3
4 files changed, 36 insertions, 16 deletions
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..9dec2143e 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',
@@ -70,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',
@@ -201,6 +207,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)
@@ -241,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):
@@ -281,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):
+ 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):
+ 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)
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}')
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index b6bb5b802..3146fc357 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -88,7 +88,8 @@ def get_config_firewall(conf, name=None, ipv6=False, interfaces=True):
def get_nftables_details(name, ipv6=False):
suffix = '6' if ipv6 else ''
- command = f'sudo nft list chain ip{suffix} filter {name}'
+ name_prefix = 'NAME6_' if ipv6 else 'NAME_'
+ command = f'sudo nft list chain ip{suffix} filter {name_prefix}{name}'
try:
results = cmd(command)
except: