2024-02-23 14:23:22 -03:00
from decimal import Decimal , ROUND_DOWN
2024-02-14 16:36:01 -03:00
from django.shortcuts import render , get_object_or_404 , redirect
2024-02-15 12:34:51 -03:00
from user_manager.models import UserAcl
2024-02-14 16:36:01 -03:00
from wireguard.forms import WireGuardInstanceForm
2024-02-23 14:23:22 -03:00
from .models import WireGuardInstance , WebadminSettings
2024-02-14 16:36:01 -03:00
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import models
2024-02-23 14:23:22 -03:00
from django.conf import settings
2024-02-14 16:36:01 -03:00
import os
import subprocess
def generate_instance_defaults ():
max_instance_id = WireGuardInstance . objects . all () . aggregate ( models . Max ( 'instance_id' ))[ 'instance_id__max' ]
new_instance_id = ( max_instance_id + 1 ) if max_instance_id is not None else 0
max_listen_port = WireGuardInstance . objects . all () . aggregate ( models . Max ( 'listen_port' ))[ 'listen_port__max' ]
new_listen_port = ( max_listen_port + 1 ) if max_listen_port is not None else 51820
new_private_key = subprocess . check_output ( 'wg genkey' , shell = True ) . decode ( 'utf-8' ) . strip ()
2024-02-15 12:08:46 -03:00
new_public_key = subprocess . check_output ( f 'echo { new_private_key } | wg pubkey' , shell = True ) . decode ( 'utf-8' ) . strip ()
2024-02-14 16:36:01 -03:00
new_address = f '10.188. { new_instance_id } .1'
address_parts = new_address . split ( '.' )
if len ( address_parts ) == 4 :
network = f "10. { address_parts [ 1 ] } . { address_parts [ 2 ] } .0/24"
port = new_listen_port
instance_id = new_instance_id
interface_name = f "wg { instance_id } "
2024-03-04 12:58:33 -03:00
#post_up_script = (
# f"iptables -t nat -A POSTROUTING -s {network} -o eth0 -j MASQUERADE\n"
# f"iptables -A INPUT -p udp -m udp --dport {port} -j ACCEPT\n"
# f"iptables -A FORWARD -i {interface_name} -o eth0 -d 10.0.0.0/8 -j REJECT\n"
# f"iptables -A FORWARD -i {interface_name} -o eth0 -d 172.16.0.0/12 -j REJECT\n"
# f"iptables -A FORWARD -i {interface_name} -o eth0 -d 192.168.0.0/16 -j REJECT\n"
# f"iptables -A FORWARD -i {interface_name} -j ACCEPT\n"
# f"iptables -A FORWARD -o {interface_name} -j ACCEPT"
#)
2024-02-14 16:36:01 -03:00
2024-03-04 12:58:33 -03:00
#post_down_script = (
# f"iptables -t nat -D POSTROUTING -s {network} -o eth0 -j MASQUERADE\n"
# f"iptables -D INPUT -p udp -m udp --dport {port} -j ACCEPT\n"
# f"iptables -D FORWARD -i {interface_name} -o eth0 -d 10.0.0.0/8 -j REJECT\n"
# f"iptables -D FORWARD -i {interface_name} -o eth0 -d 172.16.0.0/12 -j REJECT\n"
# f"iptables -D FORWARD -i {interface_name} -o eth0 -d 192.168.0.0/16 -j REJECT\n"
# f"iptables -D FORWARD -i {interface_name} -j ACCEPT\n"
# f"iptables -D FORWARD -o {interface_name} -j ACCEPT"
#)
post_up_script = ''
post_down_script = ''
2024-02-14 16:36:01 -03:00
return {
'name' : '' ,
'instance_id' : new_instance_id ,
'listen_port' : new_listen_port ,
'private_key' : new_private_key ,
2024-02-15 12:08:46 -03:00
'public_key' : new_public_key ,
2024-02-14 16:36:01 -03:00
'address' : new_address ,
2024-04-29 15:26:30 -03:00
'dns_primary' : new_address ,
2024-02-14 16:36:01 -03:00
'netmask' : 24 ,
'persistent_keepalive' : 25 ,
'hostname' : 'myserver.example.com' ,
'post_up' : post_up_script ,
'post_down' : post_down_script ,
}
@login_required
2025-02-24 15:18:41 -03:00
def legacy_view_wireguard_status ( request ):
2025-01-21 13:22:18 -03:00
user_acl = get_object_or_404 ( UserAcl , user = request . user )
2024-02-14 16:36:01 -03:00
page_title = 'WireGuard Status'
2024-02-16 17:14:35 -03:00
wireguard_instances = WireGuardInstance . objects . all () . order_by ( 'instance_id' )
if wireguard_instances . filter ( pending_changes = True ) . exists ():
pending_changes_warning = True
else :
pending_changes_warning = False
2025-01-21 13:22:18 -03:00
if user_acl . enable_enhanced_filter :
command_output = 'Enhanced filter is enabled. This command is not available.'
2024-02-15 12:48:40 -03:00
command_success = True
2025-01-21 13:22:18 -03:00
else :
bash_command = [ 'bash' , '-c' , 'wg show' ]
try :
command_output = subprocess . check_output ( bash_command , stderr = subprocess . STDOUT ) . decode ( 'utf-8' )
command_success = True
except subprocess . CalledProcessError as e :
command_output = e . output . decode ( 'utf-8' )
command_success = False
2024-02-15 12:48:40 -03:00
2024-02-16 17:14:35 -03:00
context = { 'page_title' : page_title , 'command_output' : command_output , 'command_success' : command_success , 'pending_changes_warning' : pending_changes_warning , 'wireguard_instances' : wireguard_instances }
2024-02-14 16:36:01 -03:00
return render ( request , 'wireguard/wireguard_status.html' , context )
2025-02-24 15:18:41 -03:00
@login_required
def view_wireguard_status ( request ):
user_acl = get_object_or_404 ( UserAcl , user = request . user )
page_title = 'WireGuard Status'
if user_acl . peer_groups . exists ():
wireguard_instances = []
for peer_group in user_acl . peer_groups . all ():
for instance_temp in peer_group . server_instance . all ():
if instance_temp not in wireguard_instances :
wireguard_instances . append ( instance_temp )
else :
wireguard_instances = WireGuardInstance . objects . all () . order_by ( 'instance_id' )
if WireGuardInstance . objects . filter ( pending_changes = True ) . exists ():
pending_changes_warning = True
else :
pending_changes_warning = False
if user_acl . enable_enhanced_filter :
pass
context = { 'page_title' : page_title , 'pending_changes_warning' : pending_changes_warning , 'wireguard_instances' : wireguard_instances }
return render ( request , 'wireguard/wireguard_status.html' , context )
2024-02-14 16:36:01 -03:00
@login_required
def view_wireguard_manage_instance ( request ):
2024-02-15 12:34:51 -03:00
if not UserAcl . objects . filter ( user = request . user ) . filter ( user_level__gte = 50 ) . exists ():
return render ( request , 'access_denied.html' , { 'page_title' : 'Access Denied' })
2024-02-14 16:36:01 -03:00
wireguard_instances = WireGuardInstance . objects . all () . order_by ( 'instance_id' )
2024-02-16 17:14:35 -03:00
if wireguard_instances . filter ( pending_changes = True ) . exists ():
pending_changes_warning = True
else :
pending_changes_warning = False
2024-02-14 16:36:01 -03:00
if request . GET . get ( 'uuid' ):
current_instance = get_object_or_404 ( WireGuardInstance , uuid = request . GET . get ( 'uuid' ))
else :
if request . GET . get ( 'action' ) == 'create' :
current_instance = None
else :
current_instance = wireguard_instances . first ()
if current_instance :
page_title = f 'wg { current_instance . instance_id } '
message_title = 'Update WireGuard Instance'
if current_instance . name :
page_title += f ' ( { current_instance . name } )'
if request . GET . get ( 'action' ) == 'delete' :
message_title = 'Delete WireGuard Instance'
if request . GET . get ( 'confirmation' ) == 'delete wg' + str ( current_instance . instance_id ):
if current_instance . peer_set . all () . count () > 0 :
messages . warning ( request , 'Error removing wg' + str ( current_instance . instance_id ) + '|Cannot delete WireGuard instance wg' + str ( current_instance . instance_id ) + '. There are still peers associated with this instance.' )
return redirect ( '/server/manage/?uuid=' + str ( current_instance . uuid ))
current_instance . delete ()
messages . success ( request , message_title + '|WireGuard instance wg' + str ( current_instance . instance_id ) + ' deleted successfully.' )
return redirect ( '/server/manage/' )
else :
messages . warning ( request , 'Invalid confirmation' + '|Please confirm deletion of WireGuard instance wg' + str ( current_instance . instance_id ))
return redirect ( '/server/manage/?uuid=' + str ( current_instance . uuid ))
else :
page_title = 'Create a new WireGuard Instance'
message_title = 'New WireGuard Instance'
if request . method == 'POST' :
form = WireGuardInstanceForm ( request . POST , instance = current_instance )
if form . is_valid ():
2024-02-16 17:14:35 -03:00
this_form = form . save ( commit = False )
this_form . pending_changes = True
this_form . save ()
2024-02-14 16:36:01 -03:00
messages . success ( request , message_title + '|WireGuard instance wg' + str ( form . instance . instance_id ) + ' saved successfully.' )
return redirect ( '/server/manage/?uuid=' + str ( form . instance . uuid ))
else :
if not current_instance :
form = WireGuardInstanceForm ( initial = generate_instance_defaults ())
else :
form = WireGuardInstanceForm ( instance = current_instance )
2024-02-16 17:14:35 -03:00
context = { 'page_title' : page_title , 'wireguard_instances' : wireguard_instances , 'current_instance' : current_instance , 'form' : form , 'pending_changes_warning' : pending_changes_warning }
2024-02-14 16:36:01 -03:00
return render ( request , 'wireguard/wireguard_manage_server.html' , context )