2020-12-13 10:38:41 +00:00
|
|
|
from django.db import transaction
|
2020-12-13 12:28:43 +00:00
|
|
|
|
2020-12-13 10:38:41 +00:00
|
|
|
from .models import *
|
2020-12-13 12:28:43 +00:00
|
|
|
from .selectors import *
|
2020-12-13 10:38:41 +00:00
|
|
|
|
|
|
|
@transaction.atomic
|
2020-12-13 16:59:35 +00:00
|
|
|
def create_wireguard_vpn(owner, public_key, network_mask):
|
2020-12-13 10:38:41 +00:00
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
pool = get_suitable_pools(network_mask)[0]
|
|
|
|
count = pool.wireguardvpn_set.count()
|
2020-12-13 10:38:41 +00:00
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
# First object
|
|
|
|
if count == 0:
|
|
|
|
return WireGuardVPN.objects.create(owner=owner,
|
|
|
|
vpnpool=pool,
|
|
|
|
pool_index=0,
|
|
|
|
wireguard_public_key=public_key)
|
2020-12-13 10:38:41 +00:00
|
|
|
|
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
else: # Select last network and try +1 it
|
|
|
|
last_net = WireGuardVPN.objects.filter(vpnpool=pool).order_by('pool_index').last()
|
2020-12-13 10:38:41 +00:00
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
next_index = last_net.pool_index + 1
|
2020-12-13 10:38:41 +00:00
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
if next_index <= pool.max_pool_index:
|
|
|
|
return WireGuardVPN.objects.create(owner=owner,
|
|
|
|
vpnpool=pool,
|
|
|
|
pool_index=next_index,
|
|
|
|
wireguard_public_key=public_key)
|
2020-12-13 10:38:41 +00:00
|
|
|
|
2020-12-13 16:59:35 +00:00
|
|
|
|
|
|
|
# Still there? Then we need to lookup previously used networks
|
|
|
|
try:
|
|
|
|
free_lease = WireGuardVPNFreeLeases.objects.get(vpnpool=pool)
|
|
|
|
|
|
|
|
vpn = WireGuardVPN.objects.create(owner=owner,
|
|
|
|
vpnpool=pool,
|
|
|
|
pool_index=free_lease.pool_index,
|
|
|
|
wireguard_public_key=public_key)
|
|
|
|
|
|
|
|
free_lease.delete()
|
|
|
|
|
|
|
|
return vpn
|
|
|
|
|
|
|
|
except WireGuardVPNFreeLeases.DoesNotExist:
|
|
|
|
pass
|
2020-12-13 10:38:41 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def wireguard_config_filename(self):
|
|
|
|
return '/etc/wireguard/{}.conf'.format(self.network)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def wireguard_config(self):
|
|
|
|
wireguard_config = [
|
|
|
|
"""
|
|
|
|
[Interface]
|
|
|
|
ListenPort = 51820
|
|
|
|
PrivateKey = {privatekey}
|
|
|
|
""".format(privatekey=self.wireguard_private_key) ]
|
|
|
|
|
|
|
|
peers = []
|
|
|
|
|
|
|
|
for reservation in self.vpnnetworkreservation_set.filter(status='used'):
|
|
|
|
public_key = reservation.vpnnetwork_set.first().wireguard_public_key
|
|
|
|
peer_network = "{}/{}".format(reservation.address, self.subnetwork_size)
|
|
|
|
owner = reservation.vpnnetwork_set.first().owner
|
|
|
|
|
|
|
|
peers.append("""
|
|
|
|
# Owner: {owner}
|
|
|
|
[Peer]
|
|
|
|
PublicKey = {public_key}
|
|
|
|
AllowedIPs = {peer_network}
|
|
|
|
""".format(
|
|
|
|
owner=owner,
|
|
|
|
public_key=public_key,
|
|
|
|
peer_network=peer_network))
|
|
|
|
|
|
|
|
wireguard_config.extend(peers)
|
|
|
|
|
|
|
|
return "\n".join(wireguard_config)
|
|
|
|
|
|
|
|
|
|
|
|
def configure_wireguard_vpnserver(self):
|
|
|
|
"""
|
|
|
|
This method is designed to run as a celery task and should
|
|
|
|
not be called directly from the web
|
|
|
|
"""
|
|
|
|
|
|
|
|
# subprocess, ssh
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def num_maximum_networks(self):
|
|
|
|
"""
|
|
|
|
sample:
|
|
|
|
network_size = 40
|
|
|
|
subnetwork_size = 48
|
|
|
|
maximum_networks = 2^(48-40)
|
|
|
|
|
|
|
|
2nd sample:
|
|
|
|
network_size = 8
|
|
|
|
subnetwork_size = 24
|
|
|
|
maximum_networks = 2^(24-8)
|
|
|
|
"""
|
|
|
|
|
|
|
|
return 2**(self.subnetwork_mask - self.network_mask)
|