From 2212a438b234f34f32e08efef2f841ba55a3b6a0 Mon Sep 17 00:00:00 2001 From: sskaje Date: Tue, 31 Dec 2024 10:44:01 +0800 Subject: wireguard: T4930: allow peers via FQDN * set interfaces wireguard wgXX peer YY hostname --- src/conf_mode/interfaces_wireguard.py | 40 ++++++++++++++++++++++++++++++----- src/conf_mode/nat.py | 8 +++---- 2 files changed, 39 insertions(+), 9 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/interfaces_wireguard.py b/src/conf_mode/interfaces_wireguard.py index b6fd6b0b2..1dbaa9d4e 100755 --- a/src/conf_mode/interfaces_wireguard.py +++ b/src/conf_mode/interfaces_wireguard.py @@ -29,11 +29,12 @@ from vyos.ifconfig import WireGuardIf from vyos.utils.kernel import check_kmod from vyos.utils.network import check_port_availability from vyos.utils.network import is_wireguard_key_pair +from vyos.utils.process import call from vyos import ConfigError from vyos import airbag +from pathlib import Path airbag.enable() - def get_config(config=None): """ Retrive CLI config as dictionary. Dictionary can never be empty, as at least the @@ -54,6 +55,12 @@ def get_config(config=None): if is_node_changed(conf, base + [ifname, 'peer']): wireguard.update({'rebuild_required': {}}) + wireguard['peers_need_resolve'] = [] + if 'peer' in wireguard: + for peer, peer_config in wireguard['peer'].items(): + if 'disable' not in peer_config and 'host_name' in peer_config: + wireguard['peers_need_resolve'].append(peer) + return wireguard def verify(wireguard): @@ -82,16 +89,15 @@ def verify(wireguard): for tmp in wireguard['peer']: peer = wireguard['peer'][tmp] + if 'host_name' in peer and 'address' in peer: + raise ConfigError('"host-name" and "address" are mutually exclusive') + if 'allowed_ips' not in peer: raise ConfigError(f'Wireguard allowed-ips required for peer "{tmp}"!') if 'public_key' not in peer: raise ConfigError(f'Wireguard public-key required for peer "{tmp}"!') - if ('address' in peer and 'port' not in peer) or ('port' in peer and 'address' not in peer): - raise ConfigError('Both Wireguard port and address must be defined ' - f'for peer "{tmp}" if either one of them is set!') - if peer['public_key'] in public_keys: raise ConfigError(f'Duplicate public-key defined on peer "{tmp}"') @@ -99,6 +105,13 @@ def verify(wireguard): if is_wireguard_key_pair(wireguard['private_key'], peer['public_key']): raise ConfigError(f'Peer "{tmp}" has the same public key as the interface "{wireguard["ifname"]}"') + if 'port' not in peer: + if 'host_name' in peer or 'address' in peer: + raise ConfigError(f'Missing "host-name" or "address" on peer "{tmp}"') + else: + if 'host_name' not in peer and 'address' not in peer: + raise ConfigError(f'Missing "host-name" and "address" on peer "{tmp}"') + public_keys.append(peer['public_key']) def generate(wireguard): @@ -122,6 +135,23 @@ def apply(wireguard): wg = WireGuardIf(**wireguard) wg.update(wireguard) + domain_resolver_usage = '/run/use-vyos-domain-resolver-interfaces-wireguard-' + wireguard['ifname'] + + ## DOMAIN RESOLVER + domain_action = 'restart' + if 'peers_need_resolve' in wireguard and len(wireguard['peers_need_resolve']) > 0 and 'disable' not in wireguard: + from vyos.utils.file import write_file + + text = f'# Automatically generated by interfaces_wireguard.py\nThis file indicates that vyos-domain-resolver service is used by the interfaces_wireguard.\n' + text += "intefaces:\n" + "".join([f" - {peer}\n" for peer in wireguard['peers_need_resolve']]) + Path(domain_resolver_usage).write_text(text) + write_file(domain_resolver_usage, text) + else: + Path(domain_resolver_usage).unlink(missing_ok=True) + if not Path('/run').glob('use-vyos-domain-resolver*'): + domain_action = 'stop' + call(f'systemctl {domain_action} vyos-domain-resolver.service') + return None if __name__ == '__main__': diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py index 98b2f3f29..504b3e82a 100755 --- a/src/conf_mode/nat.py +++ b/src/conf_mode/nat.py @@ -17,6 +17,7 @@ import os from sys import exit +from pathlib import Path from vyos.base import Warning from vyos.config import Config @@ -43,7 +44,6 @@ k_mod = ['nft_nat', 'nft_chain_nat'] nftables_nat_config = '/run/nftables_nat.conf' nftables_static_nat_conf = '/run/nftables_static-nat-rules.nft' domain_resolver_usage = '/run/use-vyos-domain-resolver-nat' -domain_resolver_usage_firewall = '/run/use-vyos-domain-resolver-firewall' valid_groups = [ 'address_group', @@ -265,9 +265,9 @@ def apply(nat): text = f'# Automatically generated by nat.py\nThis file indicates that vyos-domain-resolver service is used by nat.\n' write_file(domain_resolver_usage, text) elif os.path.exists(domain_resolver_usage): - os.unlink(domain_resolver_usage) - if not os.path.exists(domain_resolver_usage_firewall): - # Firewall not using domain resolver + Path(domain_resolver_usage).unlink(missing_ok=True) + + if not Path('/run').glob('use-vyos-domain-resolver*'): domain_action = 'stop' call(f'systemctl {domain_action} vyos-domain-resolver.service') -- cgit v1.2.3 From c4c35d3b7a9de76802663376b82c7decfc878980 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 18 Jan 2025 22:44:35 +0100 Subject: wireguard: T4930: use common error message pattern --- src/conf_mode/interfaces_wireguard.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/interfaces_wireguard.py b/src/conf_mode/interfaces_wireguard.py index 1dbaa9d4e..877d013cf 100755 --- a/src/conf_mode/interfaces_wireguard.py +++ b/src/conf_mode/interfaces_wireguard.py @@ -89,28 +89,33 @@ def verify(wireguard): for tmp in wireguard['peer']: peer = wireguard['peer'][tmp] + base_error = f'WireGuard peer "{tmp}":' + if 'host_name' in peer and 'address' in peer: - raise ConfigError('"host-name" and "address" are mutually exclusive') + raise ConfigError(f'{base_error} address/host-name are mutually exclusive!') if 'allowed_ips' not in peer: - raise ConfigError(f'Wireguard allowed-ips required for peer "{tmp}"!') + raise ConfigError(f'{base_error} missing mandatory allowed-ips!') if 'public_key' not in peer: - raise ConfigError(f'Wireguard public-key required for peer "{tmp}"!') + raise ConfigError(f'{base_error} missing mandatory public-key!') if peer['public_key'] in public_keys: - raise ConfigError(f'Duplicate public-key defined on peer "{tmp}"') + raise ConfigError(f'{base_error} duplicate public-key!') if 'disable' not in peer: if is_wireguard_key_pair(wireguard['private_key'], peer['public_key']): - raise ConfigError(f'Peer "{tmp}" has the same public key as the interface "{wireguard["ifname"]}"') + tmp = wireguard["ifname"] + raise ConfigError(f'{base_error} identical public key as interface "{tmp}"!') + port_addr_error = f'{base_error} both port and address/host-name must '\ + 'be defined if either one of them is set!' if 'port' not in peer: if 'host_name' in peer or 'address' in peer: - raise ConfigError(f'Missing "host-name" or "address" on peer "{tmp}"') + raise ConfigError(port_addr_error) else: if 'host_name' not in peer and 'address' not in peer: - raise ConfigError(f'Missing "host-name" and "address" on peer "{tmp}"') + raise ConfigError(port_addr_error) public_keys.append(peer['public_key']) -- cgit v1.2.3