import datetime import ipaddress import json import re import subprocess import flask import flask_login from . import db from . import system blueprint = flask.Blueprint('vpn', __name__) wgkey_regex = re.compile(r'^[A-Za-z0-9/+=]{44}$') @blueprint.route('/') @flask_login.login_required def index(): return flask.render_template('vpn/index.html') @blueprint.route('/list') @flask_login.login_required def list(): user = flask_login.current_user.get_id() return flask.jsonify( {k: v | {'active': flask.request.remote_addr in (v.get('ip'), v.get('ip6'))} for k, v in db.load('wireguard').items() if v.get('user') == user}) @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<