1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-22 15:20:09 +01:00

Commit June 2

This commit is contained in:
Donald Cheng Hong Zou 2021-07-02 13:23:04 -04:00
parent 0a92269456
commit 3aa9eab2bd
9 changed files with 186 additions and 121 deletions

3
.gitignore vendored
View File

@ -8,5 +8,6 @@ src/test.py
tmp
__pycache__
src/wg-dashboard.ini
src/wg-dashboard.ini
src/static/pic.xd
*.conf

View File

@ -17,20 +17,18 @@
## 📣 What's New: Version 2.0.1
## 📣 What's New: Version 2.1
- Added **Ping** and **Traceroute** tool
- Added **Ping** and **Traceroute** tools!
- Adjusted the calculation of data usage on each peers
- Added refresh interval of the dashboard
- Bug fixed when no configuration on fresh install ([Bug report](https://github.com/donaldzou/wireguard-dashboard/issues/23#issuecomment-869189672))
- Fixed crash when too many peers ([Bug report](https://github.com/donaldzou/wireguard-dashboard/issues/22#issuecomment-868840564))
<hr>
### ⚠️ **Update from v1.x.x**
1. Stop the dashboard if it is running.
2. You can use `git pull https://github.com/donaldzou/Wireguard-Dashboard.git v2.0.1` to get the new update inside `Wireguard-Dashboard` directory.
3. Proceed **Step 2 & 3** in the [Install](#-install) step down below.
@ -129,17 +127,31 @@ Since version 2.0, Wireguard Dashboard will be using a configuration file called
All these settings will be able to configure within the dashboard in **Settings** on the sidebar, without changing the actual file. **Except `version` and `auth_req` due to security consideration.**
## ❓ How to update the dashboard?
```shell
cd wireguard-dashboard
sudo sh wgd.sh update # Perform update
sudo sh wgd.sh start # Start dashboard
1. Change your directory to `wireguard-dashboard`
```
$ cd wireguard-dashboard
```
2. Get the newest version
```
$ sudo git pull https://github.com/donaldzou/wireguard-dashboard.git v2.1 --force
```
3. Update and install all python dependencies
```
$ python3 -m pip install -r requirements.txt
```
4. Start the dashboard
```
$ ./wgd.sh start
```
### ⚠️ **Update from v1.x.x**
1. Stop the dashboard if it is running.
2. You can use `git pull https://github.com/donaldzou/Wireguard-Dashboard.git v2.1` to get the new update inside `Wireguard-Dashboard` directory.
3. Proceed **Step 2 & 3** in the [Install](#-install) step down below.
## 🔍 Screenshot

View File

@ -1,9 +1,10 @@
# Python Built-in Library
import os
from flask import Flask, request, render_template, redirect, url_for, session, abort, jsonify
from icmplib import ping, multiping, traceroute, resolve, Host, Hop
import subprocess
from datetime import datetime, date, time, timedelta
import time
from operator import itemgetter
import secrets
import hashlib
@ -13,9 +14,10 @@ import re
# PIP installed library
import ifcfg
from tinydb import TinyDB, Query
from icmplib import ping, multiping, traceroute, resolve, Host, Hop
# Dashboard Version
dashboard_version = 'v2.0'
dashboard_version = 'v2.1'
# Dashboard Config Name
dashboard_conf = 'wg-dashboard.ini'
# Upgrade Required
@ -85,35 +87,18 @@ def read_conf_file(config_name):
if i == "[Peer]":
peer += 1
conf_peer_data["Peers"].append({})
else:
elif peer > -1:
if len(i) > 0:
tmp = re.split('\s*=\s*', i, 1)
if len(tmp) == 2:
conf_peer_data["Peers"][peer][tmp[0]] = tmp[1]
f.close()
# Read Configuration File End
return conf_peer_data
def get_conf_peers_data(config_name):
db = TinyDB('db/' + config_name + '.json')
peers = Query()
conf_peer_data = read_conf_file(config_name)
for i in conf_peer_data['Peers']:
if not db.search(peers.id == i['PublicKey']):
db.insert({
"id": i['PublicKey'],
"name": "",
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
"endpoint": 0,
"status": 0,
"latest_handshake": 0,
"allowed_ip": 0,
"traffic": []
})
def get_latest_handshake(config_name, db, peers):
# Get latest handshakes
try:
data_usage = subprocess.check_output("wg show " + config_name + " latest-handshakes", shell=True)
@ -136,6 +121,7 @@ def get_conf_peers_data(config_name):
db.update({"latest_handshake": "(None)", "status": status}, peers.id == data_usage[count])
count += 2
def get_transfer(config_name, db, peers):
# Get transfer
try:
data_usage = subprocess.check_output("wg show " + config_name + " transfer", shell=True)
@ -157,7 +143,8 @@ def get_conf_peers_data(config_name):
else:
now = datetime.now()
ctime = now.strftime("%d/%m/%Y %H:%M:%S")
traffic.append({"time": ctime, "total_receive": round(total_receive, 4),"total_sent": round(total_sent, 4),
traffic.append(
{"time": ctime, "total_receive": round(total_receive, 4), "total_sent": round(total_sent, 4),
"total_data": round(total_receive + total_sent, 4)})
total_sent = 0
total_receive = 0
@ -168,6 +155,7 @@ def get_conf_peers_data(config_name):
count += 3
def get_endpoint(config_name, db, peers):
# Get endpoint
try:
data_usage = subprocess.check_output("wg show " + config_name + " endpoints", shell=True)
@ -179,12 +167,47 @@ def get_conf_peers_data(config_name):
db.update({"endpoint": data_usage[count + 1]}, peers.id == data_usage[count])
count += 2
def get_allowed_ip(config_name, db, peers, conf_peer_data):
# Get allowed ip
for i in conf_peer_data["Peers"]:
db.update({"allowed_ip": i.get('AllowedIPs', '(None)')}, peers.id == i["PublicKey"])
def get_conf_peers_data(config_name):
db = TinyDB('db/' + config_name + '.json')
peers = Query()
conf_peer_data = read_conf_file(config_name)
for i in conf_peer_data['Peers']:
if not db.search(peers.id == i['PublicKey']):
db.insert({
"id": i['PublicKey'],
"name": "",
"total_receive": 0,
"total_sent": 0,
"total_data": 0,
"endpoint": 0,
"status": 0,
"latest_handshake": 0,
"allowed_ip": 0,
"traffic": []
})
tic = time.perf_counter()
get_latest_handshake(config_name, db, peers)
get_transfer(config_name, db, peers)
get_endpoint(config_name, db, peers)
get_allowed_ip(config_name, db, peers, conf_peer_data)
toc = time.perf_counter()
print(f"Finish fetching data in {toc - tic:0.4f} seconds")
db.close()
def get_peers(config_name):
get_conf_peers_data(config_name)
db = TinyDB('db/' + config_name + '.json')
@ -243,12 +266,12 @@ def get_conf_list():
if ".conf" in i:
i = i.replace('.conf', '')
temp = {"conf": i, "status": get_conf_status(i), "public_key": get_conf_pub_key(i)}
# get_conf_peers_data(i)
if temp['status'] == "running":
temp['checked'] = 'checked'
else:
temp['checked'] = ""
conf.append(temp)
if len(conf) > 0:
conf = sorted(conf, key=itemgetter('conf'))
return conf
@ -266,7 +289,7 @@ def auth_req():
request.endpoint != "signout" and \
request.endpoint != "auth" and \
"username" not in session:
print("not loggedin")
print("User not loggedin - Attemped access: "+str(request.endpoint))
session['message'] = "You need to sign in first!"
return redirect(url_for("signin"))
else:
@ -475,6 +498,9 @@ def conf(config_name):
conf_data['checked'] = "checked"
config = configparser.ConfigParser(strict=False)
config.read(dashboard_conf)
config_list = get_conf_list()
if config_name not in [conf['conf'] for conf in config_list]:
return render_template('index.html', conf=get_conf_list())
return render_template('configuration.html', conf=get_conf_list(), conf_data=conf_data, dashboard_refresh_interval=int(config.get("Server","dashboard_refresh_interval")))
@ -523,7 +549,7 @@ def add_peer(config_name):
public_key = data['public_key']
allowed_ips = data['allowed_ips']
keys = get_conf_peer_key(config_name)
if public_key is not list:
if type(keys) != list:
return config_name+" is not running."
if public_key in keys:
return "Key already exist."
@ -531,8 +557,7 @@ def add_peer(config_name):
status = ""
try:
status = subprocess.check_output(
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips, shell=True,
stderr=subprocess.STDOUT)
"wg set " + config_name + " peer " + public_key + " allowed-ips " + allowed_ips, shell=True, stderr=subprocess.STDOUT)
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
get_conf_peers_data(config_name)
db = TinyDB("db/" + config_name + ".json")
@ -548,13 +573,12 @@ def add_peer(config_name):
def remove_peer(config_name):
if get_conf_status(config_name) == "stopped":
return "Your need to turn on " + config_name + " first."
db = TinyDB("db/" + config_name + ".json")
peers = Query()
data = request.get_json()
delete_key = data['peer_id']
keys = get_conf_peer_key(config_name)
if keys is not list:
if type(keys) != list:
return config_name+" is not running."
if delete_key not in keys:
db.close()

View File

@ -186,3 +186,13 @@ body {
main{
margin-bottom: 3rem;
}
/*.add_btn{*/
/* position: fixed;*/
/* bottom: 1.75rem;*/
/* right: 1.75rem;*/
/* z-index: 1000;*/
/* padding: 0.75rem 1.5rem;*/
/* border-radius: 3rem;*/
/* font-size: 1rem;*/
/*}*/

View File

@ -22,13 +22,13 @@
<span aria-hidden="true">&times;</span>
</button>
</div>
<form>
<form id="add_peer_form">
<div class="form-group">
<label for="public_key">Public Key</label>
<label for="public_key">Public Key<code>*</code></label>
<input type="text" class="form-control" id="public_key" aria-describedby="public_key">
</div>
<div class="form-group">
<label for="allowed_ips">Allowed IPs</label>
<label for="allowed_ips">Allowed IPs<code>*</code></label>
<input type="text" class="form-control" id="allowed_ips">
</div>
<div class="form-group">
@ -163,7 +163,9 @@
headers:{
"Content-Type": "application/json"
},
data: JSON.stringify({"public_key":$("#public_key").val(), "allowed_ips": $("#allowed_ips").val(), "name":$("#new_add_name").val()}),
data: JSON.stringify({"public_key":$("#public_key").val(),
"allowed_ips": $("#allowed_ips").val(),
"name":$("#new_add_name").val()}),
success: function (response){
if(response != "true"){
$("#add_peer_alert").html(response+$("#add_peer_alert").html());
@ -177,12 +179,18 @@
}
})
var deleteModal = new bootstrap.Modal(document.getElementById('delete_modal'), {
keyboard: false
});
$("body").on("click", ".btn-delete-peer", function(){
var peer_id = $(this).attr("id");
$("#delete_peer").attr("peer_id", peer_id);
deleteModal.toggle();
})
$("#delete_peer").click(function(){
var peer_id = $(this).attr("peer_id");
var config = $(this).attr("conf_id");
@ -199,19 +207,22 @@
$("#remove_peer_alert").removeClass("d-none");
}
else{
location.reload();
deleteModal.toggle();
load_data();
$('#alertToast').toast('show');
$('#alertToast .toast-body').html("Peer deleted!");
}
}
})
});
var myModal = new bootstrap.Modal(document.getElementById('setting_modal'), {
var settingModal = new bootstrap.Modal(document.getElementById('setting_modal'), {
keyboard: false
})
$("body").on("click", ".btn-setting-peer", function(){
myModal.toggle();
settingModal.toggle();
var peer_id = $(this).attr("id");
$("#save_peer_name").attr("peer_id", peer_id);
$.ajax({
@ -233,6 +244,7 @@
})
});
$("#save_peer_name").click(function (){
var peer_id = $(this).attr("peer_id");
$.ajax({
@ -243,7 +255,7 @@
},
data: JSON.stringify({id: peer_id, name: $("#peer_name_textbox").val()}),
success: function (response){
myModal.toggle();
settingModal.toggle();
load_data();
$('#alertToast').toast('show');
$('#alertToast .toast-body').html("Name Saved!");

View File

@ -56,10 +56,9 @@
<button type="button" class="btn btn-outline-primary btn-sm update_interval" refresh-interval="30000">30s</button>
<button type="button" class="btn btn-outline-primary btn-sm update_interval" refresh-interval="60000">1m</button>
</div>
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#add_modal">
<i class="bi bi-plus-circle-fill"></i> Peer
<button type="button" class="btn btn-primary add_btn btn-sm" data-toggle="modal" data-target="#add_modal">
<i class="bi bi-plus-circle-fill"></i> PEER
</button>
</div>
</div>
@ -111,7 +110,7 @@
<div class="button-group">
<hr>
<button type="button" class="btn btn-outline-primary btn-setting-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-gear-fill"></i></button>
<button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="{{i['id']}}" data-toggle="modal" data-target="#delete_modal"><i class="bi bi-x-circle-fill"></i></button>
<button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-x-circle-fill"></i></button>
</div>
</div>
</div>

View File

@ -6,6 +6,9 @@
{% include "sidebar.html" %}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4 mb-4">
<h1 class="pb-4 mt-4">Home</h1>
{% if conf == [] %}
<p class="text-muted">You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".</p>
{% endif %}
{% for i in conf%}
<div class="card mt-3">
<div class="card-body">

View File

@ -9,7 +9,7 @@
{% endif %}
{% if session['update'] == "true" %}
<li class="nav-item sb-update-li">
<a class="nav-link sb-update-url" data-toggle="modal" data-target="#update_modal" href="#">New Update Available!<span class="dot dot-running"></span></a>
<a class="nav-link sb-update-url" href="https://github.com/donaldzou/wireguard-dashboard#-how-to-update-the-dashboard">New Update Available!<span class="dot dot-running"></span></a>
</li>
{% endif %}
</ul>

View File

@ -50,17 +50,21 @@ update_wgd() {
printf "Are you sure you want to update to the %s? (Y/N): " "$new_ver"
read up
if [ "$up" = "Y" ]; then
printf "%s\n" "$dashes"
printf "| Shutting down Wireguard Dashboard... |\n"
printf "%s\n" "$dashes"
printf "| Downloading %s from GitHub... |\n" "$new_ver"
printf "%s\n" "$dashes"
git pull https://github.com/donaldzou/wireguard-dashboard.git $new_ver --force > /dev/null 2>&1
printf "| Installing all required python package |\n"
python3 -m pip install -r requirements.txt
printf "| Update Successfully! |\n"
printf "| Dashboard is running... |\n"
exec "wgd.sh" "start"
printf "%s\n" "$dashes"
printf "| Now you can start the dashboard with >> sh wgd.sh start |\n"
printf "%s\n" "$dashes"
exit 1
else
printf "Cancel update. \n"
printf "%s\n" "$dashes"
printf "CANCEL update. \n"
printf "%s\n" "$dashes"
fi
}