mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2024-11-22 23:27:45 +01:00
general refactoring
This commit is contained in:
parent
710d631ffe
commit
f5ad7a49ce
319
src/dashboard.py
319
src/dashboard.py
@ -3,30 +3,32 @@
|
|||||||
Under Apache-2.0 License
|
Under Apache-2.0 License
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Import other python files
|
|
||||||
from util import *
|
|
||||||
# Python Built-in Library
|
|
||||||
import os
|
|
||||||
from flask import Flask, request, render_template, redirect, url_for, session, abort, jsonify
|
|
||||||
import subprocess
|
|
||||||
from datetime import datetime, date, time, timedelta
|
|
||||||
import time
|
|
||||||
from operator import itemgetter
|
|
||||||
import secrets
|
|
||||||
import hashlib
|
|
||||||
import json, urllib.request
|
|
||||||
import configparser
|
import configparser
|
||||||
import re
|
import hashlib
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import sqlite3
|
import json
|
||||||
|
# Python Built-in Library
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import secrets
|
||||||
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
from datetime import datetime, time, timedelta
|
||||||
|
from operator import itemgetter
|
||||||
|
|
||||||
# PIP installed library
|
# PIP installed library
|
||||||
import ifcfg
|
import ifcfg
|
||||||
|
from flask import Flask, request, render_template, redirect, url_for, session, jsonify
|
||||||
from flask_qrcode import QRcode
|
from flask_qrcode import QRcode
|
||||||
|
from icmplib import ping, traceroute
|
||||||
from tinydb import TinyDB, Query
|
from tinydb import TinyDB, Query
|
||||||
from tinydb.storages import JSONStorage
|
|
||||||
from tinydb.middlewares import CachingMiddleware
|
# Import other python files
|
||||||
from icmplib import ping, multiping, traceroute, resolve, Host, Hop
|
from util import *
|
||||||
|
|
||||||
# Dashboard Version
|
# Dashboard Version
|
||||||
dashboard_version = 'v3.0'
|
dashboard_version = 'v3.0'
|
||||||
# Dashboard Config Name
|
# Dashboard Config Name
|
||||||
@ -45,36 +47,44 @@ QRcode(app)
|
|||||||
sem = threading.RLock()
|
sem = threading.RLock()
|
||||||
|
|
||||||
|
|
||||||
|
# Read / Write Dashboard Config File
|
||||||
|
def get_dashboard_conf():
|
||||||
"""
|
"""
|
||||||
Dashboard Configuration Related
|
Dashboard Configuration Related
|
||||||
"""
|
"""
|
||||||
# Read / Write Dashboard Config File
|
|
||||||
def get_dashboard_conf():
|
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def set_dashboard_conf(config):
|
def set_dashboard_conf(config):
|
||||||
config.write(open(dashboard_conf, "w"))
|
config.write(open(dashboard_conf, "w"))
|
||||||
|
|
||||||
|
|
||||||
|
# Get all keys from a configuration
|
||||||
|
def get_conf_peer_key(config_name):
|
||||||
"""
|
"""
|
||||||
Configuration Related
|
Configuration Related
|
||||||
"""
|
"""
|
||||||
# Get all keys from a configuration
|
|
||||||
def get_conf_peer_key(config_name):
|
|
||||||
try:
|
try:
|
||||||
peer_key = subprocess.check_output("wg show " + config_name + " peers", shell=True)
|
peer_key = subprocess.run(f"wg show {config_name} peers",
|
||||||
|
check=True, shell=True, capture_output=True).stdout
|
||||||
peer_key = peer_key.decode("UTF-8").split()
|
peer_key = peer_key.decode("UTF-8").split()
|
||||||
return peer_key
|
return peer_key
|
||||||
except Exception:
|
except subprocess.CalledProcessError:
|
||||||
return config_name + " is not running."
|
return config_name + " is not running."
|
||||||
|
|
||||||
|
|
||||||
# Get numbers of connected peer of a configuration
|
# Get numbers of connected peer of a configuration
|
||||||
def get_conf_running_peer_number(config_name):
|
def get_conf_running_peer_number(config_name):
|
||||||
running = 0
|
running = 0
|
||||||
# Get latest handshakes
|
# Get latest handshakes
|
||||||
try:
|
try:
|
||||||
data_usage = subprocess.check_output("wg show " + config_name + " latest-handshakes", shell=True)
|
data_usage = subprocess.run(f"wg show {config_name} latest-handshakes",
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return "stopped"
|
return "stopped"
|
||||||
data_usage = data_usage.decode("UTF-8").split()
|
data_usage = data_usage.decode("UTF-8").split()
|
||||||
count = 0
|
count = 0
|
||||||
@ -87,13 +97,13 @@ def get_conf_running_peer_number(config_name):
|
|||||||
count += 2
|
count += 2
|
||||||
return running
|
return running
|
||||||
|
|
||||||
|
|
||||||
# Read [Interface] section from configuration file
|
# Read [Interface] section from configuration file
|
||||||
def read_conf_file_interface(config_name):
|
def read_conf_file_interface(config_name):
|
||||||
conf_location = wg_conf_path + "/" + config_name + ".conf"
|
conf_location = wg_conf_path + "/" + config_name + ".conf"
|
||||||
f = open(conf_location, 'r')
|
f = open(conf_location, 'r')
|
||||||
file = f.read().split("\n")
|
file = f.read().split("\n")
|
||||||
data = {}
|
data = {}
|
||||||
peers_start = 0
|
|
||||||
for i in range(len(file)):
|
for i in range(len(file)):
|
||||||
if not regex_match("#(.*)", file[i]):
|
if not regex_match("#(.*)", file[i]):
|
||||||
if len(file[i]) > 0:
|
if len(file[i]) > 0:
|
||||||
@ -104,6 +114,7 @@ def read_conf_file_interface(config_name):
|
|||||||
f.close()
|
f.close()
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
# Read the whole configuration file
|
# Read the whole configuration file
|
||||||
def read_conf_file(config_name):
|
def read_conf_file(config_name):
|
||||||
# Read Configuration File Start
|
# Read Configuration File Start
|
||||||
@ -143,12 +154,14 @@ def read_conf_file(config_name):
|
|||||||
# Read Configuration File End
|
# Read Configuration File End
|
||||||
return conf_peer_data
|
return conf_peer_data
|
||||||
|
|
||||||
|
|
||||||
# Get latest handshake from all peers of a configuration
|
# Get latest handshake from all peers of a configuration
|
||||||
def get_latest_handshake(config_name, db, peers):
|
def get_latest_handshake(config_name, db, peers):
|
||||||
# Get latest handshakes
|
# Get latest handshakes
|
||||||
try:
|
try:
|
||||||
data_usage = subprocess.check_output("wg show " + config_name + " latest-handshakes", shell=True)
|
data_usage = subprocess.run(f"wg show {config_name} latest-handshakes",
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return "stopped"
|
return "stopped"
|
||||||
data_usage = data_usage.decode("UTF-8").split()
|
data_usage = data_usage.decode("UTF-8").split()
|
||||||
count = 0
|
count = 0
|
||||||
@ -167,12 +180,14 @@ def get_latest_handshake(config_name, db, peers):
|
|||||||
db.update({"latest_handshake": "(None)", "status": status}, peers.id == data_usage[count])
|
db.update({"latest_handshake": "(None)", "status": status}, peers.id == data_usage[count])
|
||||||
count += 2
|
count += 2
|
||||||
|
|
||||||
|
|
||||||
# Get transfer from all peers of a configuration
|
# Get transfer from all peers of a configuration
|
||||||
def get_transfer(config_name, db, peers):
|
def get_transfer(config_name, db, peers):
|
||||||
# Get transfer
|
# Get transfer
|
||||||
try:
|
try:
|
||||||
data_usage = subprocess.check_output("wg show " + config_name + " transfer", shell=True)
|
data_usage = subprocess.run(f"wg show {config_name} transfer",
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return "stopped"
|
return "stopped"
|
||||||
data_usage = data_usage.decode("UTF-8").split()
|
data_usage = data_usage.decode("UTF-8").split()
|
||||||
count = 0
|
count = 0
|
||||||
@ -202,12 +217,14 @@ def get_transfer(config_name, db, peers):
|
|||||||
|
|
||||||
count += 3
|
count += 3
|
||||||
|
|
||||||
|
|
||||||
# Get endpoint from all peers of a configuration
|
# Get endpoint from all peers of a configuration
|
||||||
def get_endpoint(config_name, db, peers):
|
def get_endpoint(config_name, db, peers):
|
||||||
# Get endpoint
|
# Get endpoint
|
||||||
try:
|
try:
|
||||||
data_usage = subprocess.check_output("wg show " + config_name + " endpoints", shell=True)
|
data_usage = subprocess.run(f"wg show {config_name} endpoints",
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return "stopped"
|
return "stopped"
|
||||||
data_usage = data_usage.decode("UTF-8").split()
|
data_usage = data_usage.decode("UTF-8").split()
|
||||||
count = 0
|
count = 0
|
||||||
@ -215,12 +232,14 @@ def get_endpoint(config_name, db, peers):
|
|||||||
db.update({"endpoint": data_usage[count + 1]}, peers.id == data_usage[count])
|
db.update({"endpoint": data_usage[count + 1]}, peers.id == data_usage[count])
|
||||||
count += 2
|
count += 2
|
||||||
|
|
||||||
|
|
||||||
# Get allowed ips from all peers of a configuration
|
# Get allowed ips from all peers of a configuration
|
||||||
def get_allowed_ip(config_name, db, peers, conf_peer_data):
|
def get_allowed_ip(db, peers, conf_peer_data):
|
||||||
# Get allowed ip
|
# Get allowed ip
|
||||||
for i in conf_peer_data["Peers"]:
|
for i in conf_peer_data["Peers"]:
|
||||||
db.update({"allowed_ip": i.get('AllowedIPs', '(None)')}, peers.id == i["PublicKey"])
|
db.update({"allowed_ip": i.get('AllowedIPs', '(None)')}, peers.id == i["PublicKey"])
|
||||||
|
|
||||||
|
|
||||||
# Look for new peers from WireGuard
|
# Look for new peers from WireGuard
|
||||||
def get_all_peers_data(config_name):
|
def get_all_peers_data(config_name):
|
||||||
sem.acquire()
|
sem.acquire()
|
||||||
@ -279,17 +298,19 @@ def get_all_peers_data(config_name):
|
|||||||
get_latest_handshake(config_name, db, peers)
|
get_latest_handshake(config_name, db, peers)
|
||||||
get_transfer(config_name, db, peers)
|
get_transfer(config_name, db, peers)
|
||||||
get_endpoint(config_name, db, peers)
|
get_endpoint(config_name, db, peers)
|
||||||
get_allowed_ip(config_name, db, peers, conf_peer_data)
|
get_allowed_ip(db, peers, conf_peer_data)
|
||||||
toc = time.perf_counter()
|
toc = time.perf_counter()
|
||||||
print(f"Finish fetching data in {toc - tic:0.4f} seconds")
|
print(f"Finish fetching data in {toc - tic:0.4f} seconds")
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
|
|
||||||
|
|
||||||
|
# Search for peers
|
||||||
|
def get_peers(config_name, search, sort_t):
|
||||||
"""
|
"""
|
||||||
Frontend Related Functions
|
Frontend Related Functions
|
||||||
"""
|
"""
|
||||||
# Search for peers
|
|
||||||
def get_peers(config_name, search, sort_t):
|
|
||||||
get_all_peers_data(config_name)
|
get_all_peers_data(config_name)
|
||||||
sem.acquire()
|
sem.acquire()
|
||||||
|
|
||||||
@ -308,17 +329,16 @@ def get_peers(config_name, search, sort_t):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Get configuration public key
|
# Get configuration public key
|
||||||
def get_conf_pub_key(config_name):
|
def get_conf_pub_key(config_name):
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
conf.read(wg_conf_path + "/" + config_name + ".conf")
|
conf.read(wg_conf_path + "/" + config_name + ".conf")
|
||||||
pri = conf.get("Interface", "PrivateKey")
|
pri = conf.get("Interface", "PrivateKey")
|
||||||
pub = subprocess.check_output("echo '" + pri + "' | wg pubkey", shell=True)
|
pub = subprocess.run(f"echo '{pri}' | wg pubkey", check=True, shell=True, capture_output=True).stdout
|
||||||
conf.clear()
|
conf.clear()
|
||||||
return pub.decode().strip("\n")
|
return pub.decode().strip("\n")
|
||||||
|
|
||||||
|
|
||||||
# Get configuration listen port
|
# Get configuration listen port
|
||||||
def get_conf_listen_port(config_name):
|
def get_conf_listen_port(config_name):
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
@ -326,13 +346,15 @@ def get_conf_listen_port(config_name):
|
|||||||
port = ""
|
port = ""
|
||||||
try:
|
try:
|
||||||
port = conf.get("Interface", "ListenPort")
|
port = conf.get("Interface", "ListenPort")
|
||||||
except:
|
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||||
if get_conf_status(config_name) == "running":
|
if get_conf_status(config_name) == "running":
|
||||||
port = subprocess.check_output("wg show "+config_name+" listen-port", shell=True)
|
port = subprocess.run(f"wg show {config_name} listen-port",
|
||||||
|
check=True, shell=True, capture_output=True).stdout
|
||||||
port = port.decode("UTF-8")
|
port = port.decode("UTF-8")
|
||||||
conf.clear()
|
conf.clear()
|
||||||
return port
|
return port
|
||||||
|
|
||||||
|
|
||||||
# Get configuration total data
|
# Get configuration total data
|
||||||
def get_conf_total_data(config_name):
|
def get_conf_total_data(config_name):
|
||||||
sem.acquire()
|
sem.acquire()
|
||||||
@ -353,6 +375,7 @@ def get_conf_total_data(config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return [total, upload_total, download_total]
|
return [total, upload_total, download_total]
|
||||||
|
|
||||||
|
|
||||||
# Get configuration status
|
# Get configuration status
|
||||||
def get_conf_status(config_name):
|
def get_conf_status(config_name):
|
||||||
ifconfig = dict(ifcfg.interfaces().items())
|
ifconfig = dict(ifcfg.interfaces().items())
|
||||||
@ -361,6 +384,7 @@ def get_conf_status(config_name):
|
|||||||
else:
|
else:
|
||||||
return "stopped"
|
return "stopped"
|
||||||
|
|
||||||
|
|
||||||
# Get all configuration as a list
|
# Get all configuration as a list
|
||||||
def get_conf_list():
|
def get_conf_list():
|
||||||
conf = []
|
conf = []
|
||||||
@ -377,10 +401,9 @@ def get_conf_list():
|
|||||||
conf = sorted(conf, key=itemgetter('conf'))
|
conf = sorted(conf, key=itemgetter('conf'))
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
|
||||||
# Generate private key
|
# Generate private key
|
||||||
def gen_private_key():
|
def gen_private_key():
|
||||||
gen = subprocess.check_output('wg genkey > private_key.txt && wg pubkey < private_key.txt > public_key.txt',
|
|
||||||
shell=True)
|
|
||||||
private = open('private_key.txt')
|
private = open('private_key.txt')
|
||||||
private_key = private.readline().strip()
|
private_key = private.readline().strip()
|
||||||
public = open('public_key.txt')
|
public = open('public_key.txt')
|
||||||
@ -392,22 +415,23 @@ def gen_private_key():
|
|||||||
os.remove('public_key.txt')
|
os.remove('public_key.txt')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
# Generate public key
|
# Generate public key
|
||||||
def gen_public_key(private_key):
|
def gen_public_key(private_key):
|
||||||
pri_key_file = open('private_key.txt', 'w')
|
pri_key_file = open('private_key.txt', 'w')
|
||||||
pri_key_file.write(private_key)
|
pri_key_file.write(private_key)
|
||||||
pri_key_file.close()
|
pri_key_file.close()
|
||||||
try:
|
try:
|
||||||
check = subprocess.check_output("wg pubkey < private_key.txt > public_key.txt", shell=True)
|
|
||||||
public = open('public_key.txt')
|
public = open('public_key.txt')
|
||||||
public_key = public.readline().strip()
|
public_key = public.readline().strip()
|
||||||
os.remove('private_key.txt')
|
os.remove('private_key.txt')
|
||||||
os.remove('public_key.txt')
|
os.remove('public_key.txt')
|
||||||
return {"status": 'success', "msg": "", "data": public_key}
|
return {"status": 'success', "msg": "", "data": public_key}
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError:
|
||||||
os.remove('private_key.txt')
|
os.remove('private_key.txt')
|
||||||
return {"status": 'failed', "msg": "Key is not the correct length or format", "data": ""}
|
return {"status": 'failed', "msg": "Key is not the correct length or format", "data": ""}
|
||||||
|
|
||||||
|
|
||||||
# Check if private key and public key match
|
# Check if private key and public key match
|
||||||
def checkKeyMatch(private_key, public_key, config_name):
|
def checkKeyMatch(private_key, public_key, config_name):
|
||||||
result = gen_public_key(private_key)
|
result = gen_public_key(private_key)
|
||||||
@ -428,9 +452,9 @@ def checkKeyMatch(private_key, public_key, config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return {'status': 'success'}
|
return {'status': 'success'}
|
||||||
|
|
||||||
|
|
||||||
# Check if there is repeated allowed IP
|
# Check if there is repeated allowed IP
|
||||||
def check_repeat_allowed_IP(public_key, ip, config_name):
|
def check_repeat_allowed_IP(public_key, ip, config_name):
|
||||||
|
|
||||||
sem.acquire()
|
sem.acquire()
|
||||||
|
|
||||||
db = TinyDB('db/' + config_name + '.json')
|
db = TinyDB('db/' + config_name + '.json')
|
||||||
@ -454,10 +478,10 @@ def check_repeat_allowed_IP(public_key, ip, config_name):
|
|||||||
Flask Functions
|
Flask Functions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Before request
|
# Before request
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def auth_req():
|
def auth_req():
|
||||||
|
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
conf.read(dashboard_conf)
|
conf.read(dashboard_conf)
|
||||||
req = conf.get("Server", "auth_req")
|
req = conf.get("Server", "auth_req")
|
||||||
@ -480,9 +504,12 @@ def auth_req():
|
|||||||
'update_app_ip_port', 'update_wg_conf_path']:
|
'update_app_ip_port', 'update_wg_conf_path']:
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Sign In / Sign Out
|
Sign In / Sign Out
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Sign In
|
# Sign In
|
||||||
@app.route('/signin', methods=['GET'])
|
@app.route('/signin', methods=['GET'])
|
||||||
def signin():
|
def signin():
|
||||||
@ -492,6 +519,7 @@ def signin():
|
|||||||
session.pop("message")
|
session.pop("message")
|
||||||
return render_template('signin.html', message=message)
|
return render_template('signin.html', message=message)
|
||||||
|
|
||||||
|
|
||||||
# Sign Out
|
# Sign Out
|
||||||
@app.route('/signout', methods=['GET'])
|
@app.route('/signout', methods=['GET'])
|
||||||
def signout():
|
def signout():
|
||||||
@ -500,14 +528,15 @@ def signout():
|
|||||||
message = "Sign out successfully!"
|
message = "Sign out successfully!"
|
||||||
return render_template('signin.html', message=message)
|
return render_template('signin.html', message=message)
|
||||||
|
|
||||||
|
|
||||||
# Authentication
|
# Authentication
|
||||||
@app.route('/auth', methods=['POST'])
|
@app.route('/auth', methods=['POST'])
|
||||||
def auth():
|
def auth():
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
password = hashlib.sha256(request.form['password'].encode())
|
password = hashlib.sha256(request.form['password'].encode())
|
||||||
if password.hexdigest() == config["Account"]["password"] and request.form['username'] == config["Account"][
|
if password.hexdigest() == config["Account"]["password"] \
|
||||||
"username"]:
|
and request.form['username'] == config["Account"]["username"]:
|
||||||
session['username'] = request.form['username']
|
session['username'] = request.form['username']
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
@ -516,20 +545,23 @@ def auth():
|
|||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("signin"))
|
return redirect(url_for("signin"))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/', methods=['GET'])
|
||||||
|
def index():
|
||||||
"""
|
"""
|
||||||
Index Page Related
|
Index Page Related
|
||||||
"""
|
"""
|
||||||
@app.route('/', methods=['GET'])
|
|
||||||
def index():
|
|
||||||
update = check_update()
|
|
||||||
return render_template('index.html', conf=get_conf_list())
|
return render_template('index.html', conf=get_conf_list())
|
||||||
|
|
||||||
"""
|
|
||||||
Setting Page Related
|
|
||||||
"""
|
|
||||||
# Setting Page
|
# Setting Page
|
||||||
@app.route('/settings', methods=['GET'])
|
@app.route('/settings', methods=['GET'])
|
||||||
def settings():
|
def settings():
|
||||||
|
"""
|
||||||
|
Setting Page Related
|
||||||
|
"""
|
||||||
|
|
||||||
message = ""
|
message = ""
|
||||||
status = ""
|
status = ""
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
@ -549,6 +581,7 @@ def settings():
|
|||||||
peer_keepalive=config.get("Peers", "peer_keep_alive"),
|
peer_keepalive=config.get("Peers", "peer_keep_alive"),
|
||||||
peer_remote_endpoint=config.get("Peers", "remote_endpoint"))
|
peer_remote_endpoint=config.get("Peers", "remote_endpoint"))
|
||||||
|
|
||||||
|
|
||||||
# Update account username
|
# Update account username
|
||||||
@app.route('/update_acct', methods=['POST'])
|
@app.route('/update_acct', methods=['POST'])
|
||||||
def update_acct():
|
def update_acct():
|
||||||
@ -566,12 +599,14 @@ def update_acct():
|
|||||||
session['username'] = request.form['username']
|
session['username'] = request.form['username']
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
session['message'] = "Username update failed."
|
session['message'] = "Username update failed."
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
|
|
||||||
# Update peer default settting
|
# Update peer default settting
|
||||||
@app.route('/update_peer_default_config', methods=['POST'])
|
@app.route('/update_peer_default_config', methods=['POST'])
|
||||||
def update_peer_default_config():
|
def update_peer_default_config():
|
||||||
@ -584,40 +619,45 @@ def update_peer_default_config():
|
|||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
# Check DNS Format
|
# Check DNS Format
|
||||||
DNS = request.form['peer_global_DNS']
|
dns_addresses = request.form['peer_global_DNS']
|
||||||
if not check_DNS(DNS):
|
if not check_DNS(dns_addresses):
|
||||||
session['message'] = "Peer DNS Format Incorrect."
|
session['message'] = "Peer DNS Format Incorrect."
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
DNS = DNS.replace(" ","").split(',')
|
dns_addresses = dns_addresses.replace(" ", "").split(',')
|
||||||
DNS = ",".join(DNS)
|
dns_addresses = ",".join(dns_addresses)
|
||||||
|
|
||||||
# Check Endpoint Allowed IPs
|
# Check Endpoint Allowed IPs
|
||||||
ip = request.form['peer_endpoint_allowed_ip']
|
ip = request.form['peer_endpoint_allowed_ip']
|
||||||
if not check_Allowed_IPs(ip):
|
if not check_Allowed_IPs(ip):
|
||||||
session['message'] = "Peer Endpoint Allowed IPs Format Incorrect. Example: 192.168.1.1/32 or 192.168.1.1/32,192.168.1.2/32"
|
session['message'] = "Peer Endpoint Allowed IPs Format Incorrect. " \
|
||||||
|
"Example: 192.168.1.1/32 or 192.168.1.1/32,192.168.1.2/32"
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
# Check MTU Format
|
# Check MTU Format
|
||||||
if len(request.form['peer_mtu']) > 0:
|
if len(request.form['peer_mtu']) > 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to using
|
||||||
mtu = int(request.form['peer_mtu'])
|
mtu = int(request.form['peer_mtu'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.info(exc)
|
||||||
session['message'] = "MTU format is incorrect."
|
session['message'] = "MTU format is incorrect."
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
# Check keepalive Format
|
# Check keepalive Format
|
||||||
if len(request.form['peer_keep_alive']) > 0:
|
if len(request.form['peer_keep_alive']) > 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to using
|
||||||
mtu = int(request.form['peer_keep_alive'])
|
mtu = int(request.form['peer_keep_alive'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
session['message'] = "Persistent keepalive format is incorrect."
|
session['message'] = "Persistent keepalive format is incorrect."
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
# Check peer remote endpoint
|
# Check peer remote endpoint
|
||||||
if not check_remote_endpoint(request.form['peer_remote_endpoint']):
|
if not check_remote_endpoint(request.form['peer_remote_endpoint']):
|
||||||
session[
|
session['message'] = "Peer Remote Endpoint format is incorrect. It can only be a valid " \
|
||||||
'message'] = "Peer Remote Endpoint format is incorrect. It can only be a valid IP address or valid domain (without http:// or https://). "
|
"IP address or valid domain (without http:// or https://). "
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
@ -625,8 +665,7 @@ def update_peer_default_config():
|
|||||||
config.set("Peers", "peer_keep_alive", request.form['peer_keep_alive'])
|
config.set("Peers", "peer_keep_alive", request.form['peer_keep_alive'])
|
||||||
config.set("Peers", "peer_mtu", request.form['peer_mtu'])
|
config.set("Peers", "peer_mtu", request.form['peer_mtu'])
|
||||||
config.set("Peers", "peer_endpoint_allowed_ip", ','.join(clean_IP_with_range(ip)))
|
config.set("Peers", "peer_endpoint_allowed_ip", ','.join(clean_IP_with_range(ip)))
|
||||||
config.set("Peers", "peer_global_DNS", DNS)
|
config.set("Peers", "peer_global_DNS", dns_addresses)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config.write(open(dashboard_conf, "w"))
|
config.write(open(dashboard_conf, "w"))
|
||||||
@ -634,12 +673,14 @@ def update_peer_default_config():
|
|||||||
session['message_status'] = "success"
|
session['message_status'] = "success"
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
session['message'] = "Peer Default Settings update failed."
|
session['message'] = "Peer Default Settings update failed."
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
|
|
||||||
# Update dashboard password
|
# Update dashboard password
|
||||||
@app.route('/update_pwd', methods=['POST'])
|
@app.route('/update_pwd', methods=['POST'])
|
||||||
def update_pwd():
|
def update_pwd():
|
||||||
@ -655,7 +696,8 @@ def update_pwd():
|
|||||||
session['message_status'] = "success"
|
session['message_status'] = "success"
|
||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
session['message'] = "Password update failed"
|
session['message'] = "Password update failed"
|
||||||
session['message_status'] = "danger"
|
session['message_status'] = "danger"
|
||||||
config.clear()
|
config.clear()
|
||||||
@ -671,6 +713,7 @@ def update_pwd():
|
|||||||
config.clear()
|
config.clear()
|
||||||
return redirect(url_for("settings"))
|
return redirect(url_for("settings"))
|
||||||
|
|
||||||
|
|
||||||
# Update dashboard IP and port
|
# Update dashboard IP and port
|
||||||
@app.route('/update_app_ip_port', methods=['POST'])
|
@app.route('/update_app_ip_port', methods=['POST'])
|
||||||
def update_app_ip_port():
|
def update_app_ip_port():
|
||||||
@ -682,6 +725,7 @@ def update_app_ip_port():
|
|||||||
config.clear()
|
config.clear()
|
||||||
os.system('bash wgd.sh restart')
|
os.system('bash wgd.sh restart')
|
||||||
|
|
||||||
|
|
||||||
# Update WireGuard configuration file path
|
# Update WireGuard configuration file path
|
||||||
@app.route('/update_wg_conf_path', methods=['POST'])
|
@app.route('/update_wg_conf_path', methods=['POST'])
|
||||||
def update_wg_conf_path():
|
def update_wg_conf_path():
|
||||||
@ -694,12 +738,14 @@ def update_wg_conf_path():
|
|||||||
config.clear()
|
config.clear()
|
||||||
os.system('bash wgd.sh restart')
|
os.system('bash wgd.sh restart')
|
||||||
|
|
||||||
"""
|
|
||||||
Configuration Page Related
|
|
||||||
"""
|
|
||||||
# Update configuration sorting
|
# Update configuration sorting
|
||||||
@app.route('/update_dashboard_sort', methods=['POST'])
|
@app.route('/update_dashboard_sort', methods=['POST'])
|
||||||
def update_dashbaord_sort():
|
def update_dashbaord_sort():
|
||||||
|
"""
|
||||||
|
Configuration Page Related
|
||||||
|
"""
|
||||||
|
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
@ -712,6 +758,7 @@ def update_dashbaord_sort():
|
|||||||
config.clear()
|
config.clear()
|
||||||
return "true"
|
return "true"
|
||||||
|
|
||||||
|
|
||||||
# Update configuration refresh interval
|
# Update configuration refresh interval
|
||||||
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
|
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
|
||||||
def update_dashboard_refresh_interval():
|
def update_dashboard_refresh_interval():
|
||||||
@ -722,6 +769,7 @@ def update_dashboard_refresh_interval():
|
|||||||
config.clear()
|
config.clear()
|
||||||
return "true"
|
return "true"
|
||||||
|
|
||||||
|
|
||||||
# Configuration Page
|
# Configuration Page
|
||||||
@app.route('/configuration/<config_name>', methods=['GET'])
|
@app.route('/configuration/<config_name>', methods=['GET'])
|
||||||
def conf(config_name):
|
def conf(config_name):
|
||||||
@ -749,12 +797,14 @@ def conf(config_name):
|
|||||||
mtu=config.get("Peers", "peer_MTU"),
|
mtu=config.get("Peers", "peer_MTU"),
|
||||||
keep_alive=config.get("Peers", "peer_keep_alive"))
|
keep_alive=config.get("Peers", "peer_keep_alive"))
|
||||||
|
|
||||||
|
|
||||||
# Get configuration details
|
# Get configuration details
|
||||||
@app.route('/get_config/<config_name>', methods=['GET'])
|
@app.route('/get_config/<config_name>', methods=['GET'])
|
||||||
def get_conf(config_name):
|
def get_conf(config_name):
|
||||||
config_interface = read_conf_file_interface(config_name)
|
config_interface = read_conf_file_interface(config_name)
|
||||||
search = request.args.get('search')
|
search = request.args.get('search')
|
||||||
if len(search) == 0: search = ""
|
if search == 0:
|
||||||
|
search = ""
|
||||||
search = urllib.parse.unquote(search)
|
search = urllib.parse.unquote(search)
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
@ -779,8 +829,11 @@ def get_conf(config_name):
|
|||||||
else:
|
else:
|
||||||
conf_data['checked'] = "checked"
|
conf_data['checked'] = "checked"
|
||||||
print(config.get("Peers", "remote_endpoint"))
|
print(config.get("Peers", "remote_endpoint"))
|
||||||
return render_template('get_conf.html', conf_data=conf_data, wg_ip=config.get("Peers","remote_endpoint"), sort_tag=sort,
|
return render_template('get_conf.html', conf_data=conf_data, wg_ip=config.get("Peers", "remote_endpoint"),
|
||||||
dashboard_refresh_interval=int(config.get("Server", "dashboard_refresh_interval")), peer_display_mode=peer_display_mode)
|
sort_tag=sort,
|
||||||
|
dashboard_refresh_interval=int(config.get("Server", "dashboard_refresh_interval")),
|
||||||
|
peer_display_mode=peer_display_mode)
|
||||||
|
|
||||||
|
|
||||||
# Turn on / off a configuration
|
# Turn on / off a configuration
|
||||||
@app.route('/switch/<config_name>', methods=['GET'])
|
@app.route('/switch/<config_name>', methods=['GET'])
|
||||||
@ -791,17 +844,20 @@ def switch(config_name):
|
|||||||
status = get_conf_status(config_name)
|
status = get_conf_status(config_name)
|
||||||
if status == "running":
|
if status == "running":
|
||||||
try:
|
try:
|
||||||
status = subprocess.check_output("wg-quick down " + config_name, shell=True)
|
subprocess.run("wg-quick down " + config_name,
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
elif status == "stopped":
|
elif status == "stopped":
|
||||||
try:
|
try:
|
||||||
status = subprocess.check_output("wg-quick up " + config_name, shell=True)
|
subprocess.run("wg-quick up " + config_name,
|
||||||
except Exception:
|
check=True, shell=True, capture_output=True).stdout
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
|
|
||||||
# Add peer
|
# Add peer
|
||||||
@app.route('/add_peer/<config_name>', methods=['POST'])
|
@app.route('/add_peer/<config_name>', methods=['POST'])
|
||||||
def add_peer(config_name):
|
def add_peer(config_name):
|
||||||
@ -813,9 +869,9 @@ def add_peer(config_name):
|
|||||||
public_key = data['public_key']
|
public_key = data['public_key']
|
||||||
allowed_ips = data['allowed_ips']
|
allowed_ips = data['allowed_ips']
|
||||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||||
DNS = data['DNS']
|
dns_addresses = data['DNS']
|
||||||
keys = get_conf_peer_key(config_name)
|
keys = get_conf_peer_key(config_name)
|
||||||
if len(public_key) == 0 or len(DNS) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
|
if len(public_key) == 0 or len(dns_addresses) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return "Please fill in all required box."
|
return "Please fill in all required box."
|
||||||
@ -831,7 +887,7 @@ def add_peer(config_name):
|
|||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return "Allowed IP already taken by another peer."
|
return "Allowed IP already taken by another peer."
|
||||||
if not check_DNS(DNS):
|
if not check_DNS(dns_addresses):
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return "DNS formate is incorrect. Example: 1.1.1.1"
|
return "DNS formate is incorrect. Example: 1.1.1.1"
|
||||||
@ -841,23 +897,27 @@ def add_peer(config_name):
|
|||||||
return "Endpoint Allowed IPs format is incorrect."
|
return "Endpoint Allowed IPs format is incorrect."
|
||||||
if len(data['MTU']) != 0:
|
if len(data['MTU']) != 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to using
|
||||||
mtu = int(data['MTU'])
|
mtu = int(data['MTU'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return "MTU format is not correct."
|
return "MTU format is not correct."
|
||||||
if len(data['keep_alive']) != 0:
|
if len(data['keep_alive']) != 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to using
|
||||||
keep_alive = int(data['keep_alive'])
|
keep_alive = int(data['keep_alive'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return "Persistent Keepalive format is not correct."
|
return "Persistent Keepalive format is not correct."
|
||||||
try:
|
try:
|
||||||
status = subprocess.check_output(
|
subprocess.run(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips}",
|
||||||
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips, shell=True,
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||||
stderr=subprocess.STDOUT)
|
subprocess.run("wg-quick save " + config_name,
|
||||||
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||||
get_all_peers_data(config_name)
|
get_all_peers_data(config_name)
|
||||||
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'],
|
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'],
|
||||||
"endpoint_allowed_ip": endpoint_allowed_ip},
|
"endpoint_allowed_ip": endpoint_allowed_ip},
|
||||||
@ -870,6 +930,7 @@ def add_peer(config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return exc.output.strip()
|
return exc.output.strip()
|
||||||
|
|
||||||
|
|
||||||
# Remove peer
|
# Remove peer
|
||||||
@app.route('/remove_peer/<config_name>', methods=['POST'])
|
@app.route('/remove_peer/<config_name>', methods=['POST'])
|
||||||
def remove_peer(config_name):
|
def remove_peer(config_name):
|
||||||
@ -889,9 +950,10 @@ def remove_peer(config_name):
|
|||||||
return "This key does not exist"
|
return "This key does not exist"
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
status = subprocess.check_output("wg set " + config_name + " peer " + delete_key + " remove", shell=True,
|
subprocess.run(f"wg set {config_name} peer {delete_key} remove",
|
||||||
stderr=subprocess.STDOUT)
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||||
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
|
subprocess.run("wg-quick save " + config_name,
|
||||||
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||||
db.remove(peers.id == delete_key)
|
db.remove(peers.id == delete_key)
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
@ -901,6 +963,7 @@ def remove_peer(config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return exc.output.strip()
|
return exc.output.strip()
|
||||||
|
|
||||||
|
|
||||||
# Save peer settings
|
# Save peer settings
|
||||||
@app.route('/save_peer_setting/<config_name>', methods=['POST'])
|
@app.route('/save_peer_setting/<config_name>', methods=['POST'])
|
||||||
def save_peer_setting(config_name):
|
def save_peer_setting(config_name):
|
||||||
@ -908,7 +971,7 @@ def save_peer_setting(config_name):
|
|||||||
id = data['id']
|
id = data['id']
|
||||||
name = data['name']
|
name = data['name']
|
||||||
private_key = data['private_key']
|
private_key = data['private_key']
|
||||||
DNS = data['DNS']
|
dns_addresses = data['DNS']
|
||||||
allowed_ip = data['allowed_ip']
|
allowed_ip = data['allowed_ip']
|
||||||
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
endpoint_allowed_ip = data['endpoint_allowed_ip']
|
||||||
sem.acquire()
|
sem.acquire()
|
||||||
@ -921,21 +984,25 @@ def save_peer_setting(config_name):
|
|||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
|
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
|
||||||
if not check_DNS(DNS):
|
if not check_DNS(dns_addresses):
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
|
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
|
||||||
if len(data['MTU']) != 0:
|
if len(data['MTU']) != 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to use
|
||||||
mtu = int(data['MTU'])
|
mtu = int(data['MTU'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
|
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
|
||||||
if len(data['keep_alive']) != 0:
|
if len(data['keep_alive']) != 0:
|
||||||
try:
|
try:
|
||||||
|
# TODO need to using
|
||||||
keep_alive = int(data['keep_alive'])
|
keep_alive = int(data['keep_alive'])
|
||||||
except:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
|
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
|
||||||
@ -953,17 +1020,17 @@ def save_peer_setting(config_name):
|
|||||||
if allowed_ip == "":
|
if allowed_ip == "":
|
||||||
allowed_ip = '""'
|
allowed_ip = '""'
|
||||||
allowed_ip = allowed_ip.replace(" ", "")
|
allowed_ip = allowed_ip.replace(" ", "")
|
||||||
change_ip = subprocess.check_output('wg set ' + config_name + " peer " + id + " allowed-ips " + allowed_ip,
|
change_ip = subprocess.run('wg set ' + config_name + " peer " + id + " allowed-ips " + allowed_ip,
|
||||||
shell=True, stderr=subprocess.STDOUT)
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT).stdout
|
||||||
save_change_ip = subprocess.check_output('wg-quick save ' + config_name, shell=True,
|
subprocess.run('wg-quick save ' + config_name,
|
||||||
stderr=subprocess.STDOUT)
|
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
|
||||||
if change_ip.decode("UTF-8") != "":
|
if change_ip.decode("UTF-8") != "":
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
|
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
|
||||||
db.update(
|
db.update(
|
||||||
{"name": name, "private_key": private_key,
|
{"name": name, "private_key": private_key,
|
||||||
"DNS": DNS, "endpoint_allowed_ip": endpoint_allowed_ip,
|
"DNS": dns_addresses, "endpoint_allowed_ip": endpoint_allowed_ip,
|
||||||
"mtu": data['MTU'],
|
"mtu": data['MTU'],
|
||||||
"keepalive": data['keep_alive']},
|
"keepalive": data['keep_alive']},
|
||||||
peers.id == id)
|
peers.id == id)
|
||||||
@ -979,6 +1046,7 @@ def save_peer_setting(config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
return jsonify({"status": "failed", "msg": "This peer does not exist."})
|
||||||
|
|
||||||
|
|
||||||
# Get peer settings
|
# Get peer settings
|
||||||
@app.route('/get_peer_data/<config_name>', methods=['POST'])
|
@app.route('/get_peer_data/<config_name>', methods=['POST'])
|
||||||
def get_peer_name(config_name):
|
def get_peer_name(config_name):
|
||||||
@ -996,11 +1064,13 @@ def get_peer_name(config_name):
|
|||||||
sem.release()
|
sem.release()
|
||||||
return jsonify(data)
|
return jsonify(data)
|
||||||
|
|
||||||
|
|
||||||
# Generate a private key
|
# Generate a private key
|
||||||
@app.route('/generate_peer', methods=['GET'])
|
@app.route('/generate_peer', methods=['GET'])
|
||||||
def generate_peer():
|
def generate_peer():
|
||||||
return jsonify(gen_private_key())
|
return jsonify(gen_private_key())
|
||||||
|
|
||||||
|
|
||||||
# Generate a public key from a private key
|
# Generate a public key from a private key
|
||||||
@app.route('/generate_public_key', methods=['POST'])
|
@app.route('/generate_public_key', methods=['POST'])
|
||||||
def generate_public_key():
|
def generate_public_key():
|
||||||
@ -1008,6 +1078,7 @@ def generate_public_key():
|
|||||||
private_key = data['private_key']
|
private_key = data['private_key']
|
||||||
return jsonify(gen_public_key(private_key))
|
return jsonify(gen_public_key(private_key))
|
||||||
|
|
||||||
|
|
||||||
# Check if both key match
|
# Check if both key match
|
||||||
@app.route('/check_key_match/<config_name>', methods=['POST'])
|
@app.route('/check_key_match/<config_name>', methods=['POST'])
|
||||||
def check_key_match(config_name):
|
def check_key_match(config_name):
|
||||||
@ -1033,8 +1104,8 @@ def generate_qrcode(config_name):
|
|||||||
endpoint = config.get("Peers", "remote_endpoint") + ":" + listen_port
|
endpoint = config.get("Peers", "remote_endpoint") + ":" + listen_port
|
||||||
private_key = peer['private_key']
|
private_key = peer['private_key']
|
||||||
allowed_ip = peer['allowed_ip']
|
allowed_ip = peer['allowed_ip']
|
||||||
DNS = peer['DNS']
|
dns_addresses = peer['DNS']
|
||||||
MTU = peer['mtu']
|
mtu_value = peer['mtu']
|
||||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||||
keepalive = peer['keepalive']
|
keepalive = peer['keepalive']
|
||||||
conf = {
|
conf = {
|
||||||
@ -1043,8 +1114,8 @@ def generate_qrcode(config_name):
|
|||||||
"endpoint": endpoint,
|
"endpoint": endpoint,
|
||||||
"private_key": private_key,
|
"private_key": private_key,
|
||||||
"allowed_ip": allowed_ip,
|
"allowed_ip": allowed_ip,
|
||||||
"DNS": DNS,
|
"DNS": dns_addresses,
|
||||||
"mtu": MTU,
|
"mtu": mtu_value,
|
||||||
"endpoint_allowed_ip": endpoint_allowed_ip,
|
"endpoint_allowed_ip": endpoint_allowed_ip,
|
||||||
"keepalive": keepalive,
|
"keepalive": keepalive,
|
||||||
}
|
}
|
||||||
@ -1055,6 +1126,8 @@ def generate_qrcode(config_name):
|
|||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return redirect("/configuration/" + config_name)
|
return redirect("/configuration/" + config_name)
|
||||||
|
|
||||||
|
|
||||||
# Download configuration file
|
# Download configuration file
|
||||||
@app.route('/<config_name>', methods=['GET'])
|
@app.route('/<config_name>', methods=['GET'])
|
||||||
def download(config_name):
|
def download(config_name):
|
||||||
@ -1073,8 +1146,8 @@ def download(config_name):
|
|||||||
endpoint = config.get("Peers", "remote_endpoint") + ":" + listen_port
|
endpoint = config.get("Peers", "remote_endpoint") + ":" + listen_port
|
||||||
private_key = peer['private_key']
|
private_key = peer['private_key']
|
||||||
allowed_ip = peer['allowed_ip']
|
allowed_ip = peer['allowed_ip']
|
||||||
DNS = peer['DNS']
|
dns_addresses = peer['DNS']
|
||||||
MTU = peer['mtu']
|
mtu_value = peer['mtu']
|
||||||
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
endpoint_allowed_ip = peer['endpoint_allowed_ip']
|
||||||
keepalive = peer['keepalive']
|
keepalive = peer['keepalive']
|
||||||
filename = peer['name']
|
filename = peer['name']
|
||||||
@ -1093,17 +1166,21 @@ def download(config_name):
|
|||||||
filename = "".join(filename.split(' '))
|
filename = "".join(filename.split(' '))
|
||||||
filename = filename + "_" + config_name
|
filename = filename + "_" + config_name
|
||||||
|
|
||||||
def generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive):
|
|
||||||
yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\nMTU = " + MTU + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + endpoint+ "\nPersistentKeepalive = " + keepalive
|
|
||||||
db.close()
|
db.close()
|
||||||
sem.release()
|
sem.release()
|
||||||
return app.response_class(generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive),
|
result = "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + \
|
||||||
|
dns_addresses + "\nMTU = " + mtu_value + "\n\n[Peer]\nPublicKey = " + \
|
||||||
|
public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + \
|
||||||
|
endpoint + "\nPersistentKeepalive = " + keepalive
|
||||||
|
|
||||||
|
return app.response_class((yield result),
|
||||||
mimetype='text/conf',
|
mimetype='text/conf',
|
||||||
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
|
||||||
else:
|
else:
|
||||||
db.close()
|
db.close()
|
||||||
return redirect("/configuration/" + config_name)
|
return redirect("/configuration/" + config_name)
|
||||||
|
|
||||||
|
|
||||||
# Switch peer displate mode
|
# Switch peer displate mode
|
||||||
@app.route('/switch_display_mode/<mode>', methods=['GET'])
|
@app.route('/switch_display_mode/<mode>', methods=['GET'])
|
||||||
def switch_display_mode(mode):
|
def switch_display_mode(mode):
|
||||||
@ -1119,6 +1196,8 @@ def switch_display_mode(mode):
|
|||||||
"""
|
"""
|
||||||
Dashboard Tools Related
|
Dashboard Tools Related
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# Get all IP for ping
|
# Get all IP for ping
|
||||||
@app.route('/get_ping_ip', methods=['POST'])
|
@app.route('/get_ping_ip', methods=['POST'])
|
||||||
def get_ping_ip():
|
def get_ping_ip():
|
||||||
@ -1141,6 +1220,7 @@ def get_ping_ip():
|
|||||||
sem.release()
|
sem.release()
|
||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
# Ping IP
|
# Ping IP
|
||||||
@app.route('/ping_ip', methods=['POST'])
|
@app.route('/ping_ip', methods=['POST'])
|
||||||
def ping_ip():
|
def ping_ip():
|
||||||
@ -1159,9 +1239,11 @@ def ping_ip():
|
|||||||
if returnjson['package_loss'] == 1.0:
|
if returnjson['package_loss'] == 1.0:
|
||||||
returnjson['package_loss'] = returnjson['package_sent']
|
returnjson['package_loss'] = returnjson['package_sent']
|
||||||
return jsonify(returnjson)
|
return jsonify(returnjson)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
return "Error"
|
return "Error"
|
||||||
|
|
||||||
|
|
||||||
# Traceroute IP
|
# Traceroute IP
|
||||||
@app.route('/traceroute_ip', methods=['POST'])
|
@app.route('/traceroute_ip', methods=['POST'])
|
||||||
def traceroute_ip():
|
def traceroute_ip():
|
||||||
@ -1176,16 +1258,20 @@ def traceroute_ip():
|
|||||||
"max_rtt": hop.max_rtt})
|
"max_rtt": hop.max_rtt})
|
||||||
last_distance = hop.distance
|
last_distance = hop.distance
|
||||||
return jsonify(returnjson)
|
return jsonify(returnjson)
|
||||||
except Exception:
|
except Exception as exc:
|
||||||
|
logging.error(exc)
|
||||||
return "Error"
|
return "Error"
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dashboard Initialization
|
Dashboard Initialization
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def init_dashboard():
|
def init_dashboard():
|
||||||
# Set Default INI File
|
# Set Default INI File
|
||||||
if not os.path.isfile("wg-dashboard.ini"):
|
if not os.path.isfile("wg-dashboard.ini"):
|
||||||
conf_file = open("wg-dashboard.ini", "w+")
|
open("wg-dashboard.ini", "w")
|
||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(dashboard_conf)
|
config.read(dashboard_conf)
|
||||||
# Defualt dashboard account setting
|
# Defualt dashboard account setting
|
||||||
@ -1231,17 +1317,20 @@ def init_dashboard():
|
|||||||
config.write(open(dashboard_conf, "w"))
|
config.write(open(dashboard_conf, "w"))
|
||||||
config.clear()
|
config.clear()
|
||||||
|
|
||||||
|
|
||||||
|
def check_update():
|
||||||
"""
|
"""
|
||||||
Dashboard check update
|
Dashboard check update
|
||||||
"""
|
"""
|
||||||
def check_update():
|
|
||||||
conf = configparser.ConfigParser(strict=False)
|
conf = configparser.ConfigParser(strict=False)
|
||||||
conf.read(dashboard_conf)
|
conf.read(dashboard_conf)
|
||||||
data = urllib.request.urlopen("https://api.github.com/repos/donaldzou/WGDashboard/releases").read()
|
data = urllib.request.urlopen("https://api.github.com/repos/donaldzou/WGDashboard/releases").read()
|
||||||
output = json.loads(data)
|
output = json.loads(data)
|
||||||
release = []
|
release = []
|
||||||
for i in output:
|
for i in output:
|
||||||
if i["prerelease"] == False: release.append(i)
|
if not i["prerelease"]:
|
||||||
|
release.append(i)
|
||||||
if conf.get("Server", "version") == release[0]["tag_name"]:
|
if conf.get("Server", "version") == release[0]["tag_name"]:
|
||||||
return "false"
|
return "false"
|
||||||
else:
|
else:
|
||||||
@ -1254,7 +1343,7 @@ if __name__ == "__main__":
|
|||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read('wg-dashboard.ini')
|
config.read('wg-dashboard.ini')
|
||||||
app_ip = config.get("Server", "app_ip")
|
app_ip = config.get("Server", "app_ip")
|
||||||
app_port = config.get("Server", "app_port")
|
app_port = int(config.get("Server", "app_port"))
|
||||||
wg_conf_path = config.get("Server", "wg_conf_path")
|
wg_conf_path = config.get("Server", "wg_conf_path")
|
||||||
config.clear()
|
config.clear()
|
||||||
app.run(host=app_ip, debug=False, port=app_port)
|
app.run(host=app_ip, debug=False, port=app_port)
|
||||||
|
Loading…
Reference in New Issue
Block a user