summaryrefslogtreecommitdiff
path: root/src/conf_mode/firewall.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/firewall.py')
-rwxr-xr-xsrc/conf_mode/firewall.py85
1 files changed, 34 insertions, 51 deletions
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index dcdbf8fab..20cf1ead1 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -26,13 +26,10 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import node_changed
from vyos.configdiff import get_config_diff, Diff
+from vyos.configdep import set_dependents, call_dependents
# from vyos.configverify import verify_interface_exists
+from vyos.firewall import fqdn_config_parse
from vyos.firewall import geoip_update
-from vyos.firewall import get_ips_domains_dict
-from vyos.firewall import nft_add_set_elements
-from vyos.firewall import nft_flush_set
-from vyos.firewall import nft_init_set
-from vyos.firewall import nft_update_set_elements
from vyos.template import render
from vyos.util import call
from vyos.util import cmd
@@ -45,7 +42,8 @@ from vyos import ConfigError
from vyos import airbag
airbag.enable()
-policy_route_conf_script = '/usr/libexec/vyos/conf_mode/policy-route.py'
+nat_conf_script = 'nat.py'
+policy_route_conf_script = 'policy-route.py'
nftables_conf = '/run/nftables.conf'
@@ -163,7 +161,10 @@ def get_config(config=None):
for zone in firewall['zone']:
firewall['zone'][zone] = dict_merge(default_values, firewall['zone'][zone])
- firewall['policy_resync'] = bool('group' in firewall or node_changed(conf, base + ['group']))
+ firewall['group_resync'] = bool('group' in firewall or node_changed(conf, base + ['group']))
+ if firewall['group_resync']:
+ # Update nat and policy-route as firewall groups were updated
+ set_dependents('group_resync', conf)
if 'config_trap' in firewall and firewall['config_trap'] == 'enable':
diff = get_config_diff(conf)
@@ -174,6 +175,8 @@ def get_config(config=None):
firewall['geoip_updated'] = geoip_updated(conf, firewall)
+ fqdn_config_parse(firewall)
+
return firewall
def verify_rule(firewall, rule_conf, ipv6):
@@ -233,29 +236,28 @@ def verify_rule(firewall, rule_conf, ipv6):
if side in rule_conf:
side_conf = rule_conf[side]
- if dict_search_args(side_conf, 'geoip', 'country_code'):
- if 'address' in side_conf:
- raise ConfigError('Address and GeoIP cannot both be defined')
-
- if dict_search_args(side_conf, 'group', 'address_group'):
- raise ConfigError('Address-group and GeoIP cannot both be defined')
-
- if dict_search_args(side_conf, 'group', 'network_group'):
- raise ConfigError('Network-group and GeoIP cannot both be defined')
+ if len({'address', 'fqdn', 'geoip'} & set(side_conf)) > 1:
+ raise ConfigError('Only one of address, fqdn or geoip can be specified')
if 'group' in side_conf:
- if {'address_group', 'network_group'} <= set(side_conf['group']):
- raise ConfigError('Only one address-group or network-group can be specified')
+ 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')
for group in valid_groups:
if group in side_conf['group']:
group_name = side_conf['group'][group]
+ fw_group = f'ipv6_{group}' if ipv6 and group in ['address_group', 'network_group'] else group
+ error_group = fw_group.replace("_", "-")
+
+ if group in ['address_group', 'network_group', 'domain_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')
+
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)
if group_obj is None:
@@ -275,6 +277,8 @@ def verify_nested_group(group_name, group, groups, seen):
if 'include' not in group:
return
+ seen.append(group_name)
+
for g in group['include']:
if g not in groups:
raise ConfigError(f'Nested group "{g}" does not exist')
@@ -282,8 +286,6 @@ def verify_nested_group(group_name, group, groups, seen):
if g in seen:
raise ConfigError(f'Group "{group_name}" has a circular reference')
- seen.append(g)
-
if 'include' in groups[g]:
verify_nested_group(g, groups[g], groups, seen)
@@ -467,42 +469,23 @@ def post_apply_trap(firewall):
cmd(base_cmd + ' '.join(objects))
-def resync_policy_route():
- # Update policy route as firewall groups were updated
- tmp, out = rc_cmd(policy_route_conf_script)
- if tmp > 0:
- Warning(f'Failed to re-apply policy route configuration! {out}')
-
def apply(firewall):
install_result, output = rc_cmd(f'nft -f {nftables_conf}')
if install_result == 1:
raise ConfigError(f'Failed to apply firewall: {output}')
- # set firewall group domain-group xxx
- if 'group' in firewall:
- if 'domain_group' in firewall['group']:
- # T970 Enable a resolver (systemd daemon) that checks
- # domain-group addresses and update entries for domains by timeout
- # If router loaded without internet connection or for synchronization
- call('systemctl restart vyos-domain-group-resolve.service')
- for group, group_config in firewall['group']['domain_group'].items():
- domains = []
- if group_config.get('address') is not None:
- for address in group_config.get('address'):
- domains.append(address)
- # Add elements to domain-group, try to resolve domain => ip
- # and add elements to nft set
- ip_dict = get_ips_domains_dict(domains)
- elements = sum(ip_dict.values(), [])
- nft_init_set(f'D_{group}')
- nft_add_set_elements(f'D_{group}', elements)
- else:
- call('systemctl stop vyos-domain-group-resolve.service')
-
apply_sysfs(firewall)
- if firewall['policy_resync']:
- resync_policy_route()
+ if firewall['group_resync']:
+ call_dependents()
+
+ # T970 Enable a resolver (systemd daemon) that checks
+ # domain-group/fqdn addresses and update entries for domains by timeout
+ # If router loaded without internet connection or for synchronization
+ domain_action = 'stop'
+ if dict_search_args(firewall, 'group', 'domain_group') or firewall['ip_fqdn'] or firewall['ip6_fqdn']:
+ domain_action = 'restart'
+ call(f'systemctl {domain_action} vyos-domain-resolver.service')
if firewall['geoip_updated']:
# Call helper script to Update set contents