summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
authorAlex W <embezzle.dev@proton.me>2025-01-30 20:22:41 +0000
committerAlex W <embezzle.dev@proton.me>2025-03-21 21:08:50 +0100
commit9e2bdc96ea63e7ee1adb002df17e0d9ecc1cd410 (patch)
tree29af39c615a3b3cbcf327af4839f578f29af00d9 /src/conf_mode
parent7eec4583bf7feb900fad02e009b9ded11b52fd5d (diff)
downloadvyos-1x-9e2bdc96ea63e7ee1adb002df17e0d9ecc1cd410.tar.gz
vyos-1x-9e2bdc96ea63e7ee1adb002df17e0d9ecc1cd410.zip
firewall: T5493: Implement remote-group
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/firewall.py26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 768bb127d..cebe57092 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -44,6 +44,7 @@ airbag.enable()
nftables_conf = '/run/nftables.conf'
domain_resolver_usage = '/run/use-vyos-domain-resolver-firewall'
+firewall_config_dir = "/config/firewall"
sysctl_file = r'/run/sysctl/10-vyos-firewall.conf'
@@ -53,7 +54,8 @@ valid_groups = [
'network_group',
'port_group',
'interface_group',
- ## Added for group ussage in bridge firewall
+ 'remote_group',
+ ## Added for group usage in bridge firewall
'ipv4_address_group',
'ipv6_address_group',
'ipv4_network_group',
@@ -311,8 +313,8 @@ def verify_rule(firewall, family, hook, priority, rule_id, rule_conf):
raise ConfigError('Only one of address, fqdn or geoip can be specified')
if 'group' in side_conf:
- if len({'address_group', 'network_group', 'domain_group'} & set(side_conf['group'])) > 1:
- raise ConfigError('Only one address-group, network-group or domain-group can be specified')
+ if len({'address_group', 'network_group', 'domain_group', 'remote_group'} & set(side_conf['group'])) > 1:
+ raise ConfigError('Only one address-group, network-group, remote-group or domain-group can be specified')
for group in valid_groups:
if group in side_conf['group']:
@@ -332,7 +334,7 @@ def verify_rule(firewall, family, hook, priority, rule_id, rule_conf):
error_group = fw_group.replace("_", "-")
- if group in ['address_group', 'network_group', 'domain_group']:
+ if group in ['address_group', 'network_group', 'domain_group', 'remote_group']:
types = [t for t in ['address', 'fqdn', 'geoip'] if t in side_conf]
if types:
raise ConfigError(f'{error_group} and {types[0]} cannot both be defined')
@@ -442,6 +444,11 @@ def verify(firewall):
for group_name, group in groups.items():
verify_nested_group(group_name, group, groups, [])
+ if 'remote_group' in firewall['group']:
+ for group_name, group in firewall['group']['remote_group'].items():
+ if 'url' not in group:
+ raise ConfigError(f'remote-group {group_name} must have a url configured')
+
for family in ['ipv4', 'ipv6', 'bridge']:
if family in firewall:
for chain in ['name','forward','input','output', 'prerouting']:
@@ -539,6 +546,15 @@ def verify(firewall):
def generate(firewall):
render(nftables_conf, 'firewall/nftables.j2', firewall)
render(sysctl_file, 'firewall/sysctl-firewall.conf.j2', firewall)
+
+ # Cleanup remote-group cache files
+ if os.path.exists(firewall_config_dir):
+ for fw_file in os.listdir(firewall_config_dir):
+ # Delete matching files in 'config/firewall' that no longer exist as a remote-group in config
+ if fw_file.startswith("R_") and fw_file.endswith(".txt"):
+ if 'group' not in firewall or 'remote_group' not in firewall['group'] or fw_file[2:-4] not in firewall['group']['remote_group'].keys():
+ os.unlink(os.path.join(firewall_config_dir, fw_file))
+
return None
def parse_firewall_error(output):
@@ -598,7 +614,7 @@ def apply(firewall):
## DOMAIN RESOLVER
domain_action = 'restart'
- if dict_search_args(firewall, 'group', 'domain_group') or firewall['ip_fqdn'].items() or firewall['ip6_fqdn'].items():
+ if dict_search_args(firewall, 'group', 'remote_group') or dict_search_args(firewall, 'group', 'domain_group') or firewall['ip_fqdn'].items() or firewall['ip6_fqdn'].items():
text = f'# Automatically generated by firewall.py\nThis file indicates that vyos-domain-resolver service is used by the firewall.\n'
Path(domain_resolver_usage).write_text(text)
else: