diff --git a/web/system.py b/web/system.py index ff02964..a5e130c 100644 --- a/web/system.py +++ b/web/system.py @@ -108,7 +108,7 @@ def save_config(): wireguard = db.read('wireguard') for ip, key in wireguard.items(): ip4 = [f'{ip}/32'] - ip6 = [f'{key["ip6"]}/128'] if key.get('ip6') else None + ip6 = [f'{key["ip6"]}'] 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) diff --git a/web/vpn.py b/web/vpn.py index 086463e..8a5b818 100644 --- a/web/vpn.py +++ b/web/vpn.py @@ -29,6 +29,19 @@ def list(): @blueprint.route('/new', methods=('POST',)) @flask_login.login_required def new(): + # Each key is associated with a new IPv4 address from the pool settings['wg_net']. + # Each key gets an IPv6 subnet depending on the amount of surplus addresses available. + # For wg_net 10.10.0.0/18 and wg_net6 1234:5678:90ab:cdef::/64, + # the key for 10.10.0.10/32 would get 1234:5678:90ab:cdef:a::/80. + def ipv4to6(net4, ip4, net6): + # Calculate the address and prefix length for the assigned IPv6 network. + len4 = (net4.max_prefixlen - net4.prefixlen) + len6 = (net6.max_prefixlen - net6.prefixlen) + # Make sure the network address ends at a colon. Wastes some addresses but IPv6. + assigned = (len6 - len4) - (len6 - len4) % 16 + ip6 = (net6.network_address + (index<