From ff2246df8c42cb9a9c17d84d1b9f68543ea7dbd0 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Mon, 4 Dec 2023 10:23:41 +0100 Subject: [PATCH] vpn: configure IPv6 addresses for WG clients --- web/__init__.py | 1 + web/system.py | 4 +++- web/templates/vpn/wg-fri.conf | 2 +- web/vpn.py | 7 ++++++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/web/__init__.py b/web/__init__.py index 5d66611..afc1256 100644 --- a/web/__init__.py +++ b/web/__init__.py @@ -28,6 +28,7 @@ def create_app(test_config=None): 'wg_dns': False, 'wg_key': '', 'wg_net': '', + 'wg_net6': '', 'version': 0, } diff --git a/web/system.py b/web/system.py index 62469e7..720c357 100644 --- a/web/system.py +++ b/web/system.py @@ -102,7 +102,7 @@ def save_config(): wireguard = db.read('wireguard') for ip, key in wireguard.items(): ip4 = [f'{ip}/32'] - ip6 = [f'{key["ip6"]}/128'] if 'ip6' in key else None + ip6 = [f'{key["ip6"]}/128'] if key.get('ip6') else None for network in user_networks.get(key.get('user', ''), ()): if group := network_group(network): ipset_add(ipsets, group, ip4, ip6) @@ -174,6 +174,8 @@ PrivateKey = {settings.get('wg_key')} PublicKey = {data.get('key')} AllowedIPs = {ip} ''', file=f) + if 'ip6' in data: + print(f'AllowedIPs = {data["ip6"]}', file=f) # Make a config archive in a temporary place, so we don’t send # incomplete tars. diff --git a/web/templates/vpn/wg-fri.conf b/web/templates/vpn/wg-fri.conf index 811883d..09bbf9c 100644 --- a/web/templates/vpn/wg-fri.conf +++ b/web/templates/vpn/wg-fri.conf @@ -2,7 +2,7 @@ # {{ timestamp }} {{ current_user['username'] }} {{ name }} # PublicKey = {{ pubkey }} PrivateKey = # paste private key here -Address = {{ ip }} +Address = {{ ip }}{% if ip6 %}, {{ ip6 }}{% endif %} {%- if dns %} DNS = {{ dns }} {%- endif %} diff --git a/web/vpn.py b/web/vpn.py index 964bfae..a1c46f3 100644 --- a/web/vpn.py +++ b/web/vpn.py @@ -39,8 +39,11 @@ def new(): with db.locked(): # Find a free address for the new key. keys = db.read('wireguard') - for ip in host.network.hosts(): + ip6 = None + for index, ip in enumerate(host.network.hosts(), start=1): if ip != host.ip and str(ip) not in keys: + if wg_net6 := settings.get('wg_net6'): + ip6 = (ipaddress.ip_interface(wg_net6) + index).ip break else: return flask.Response('no more available IP addresses', status=500, mimetype='text/plain') @@ -49,6 +52,7 @@ def new(): keys[str(ip)] = { 'key': pubkey, + 'ip6': str(ip6) if ip6 else None, 'time': now.timestamp(), 'user': flask_login.current_user.get_id(), 'name': name, @@ -65,6 +69,7 @@ def new(): 'server_key': server_pubkey, 'pubkey': pubkey, 'ip': str(ip), + 'ip6': str(ip6) if ip6 else None, 'timestamp': now, 'name': name, 'dns': settings.get('wg_dns') if flask.request.json.get('use_dns', True) else False,