1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-06 16:00:28 +01:00

Merge branch 'main' into hmm-what-about-socket

This commit is contained in:
Donald Cheng Hong Zou 2022-02-28 13:31:06 -05:00
commit 3623104e3b
11 changed files with 92 additions and 33 deletions

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
.vscode/sftp.json .vscode
src/.vscode/sftp.json
.DS_Store .DS_Store
.idea .idea
src/db src/db

View File

@ -10,6 +10,7 @@
<p align="center"> <p align="center">
<a href="https://github.com/donaldzou/wireguard-dashboard/releases/latest"><img src="https://img.shields.io/github/v/release/donaldzou/wireguard-dashboard"></a> <a href="https://github.com/donaldzou/wireguard-dashboard/releases/latest"><img src="https://img.shields.io/github/v/release/donaldzou/wireguard-dashboard"></a>
<a href="https://wakatime.com/badge/user/45f53c7c-9da9-4cb0-85d6-17bd38cc748b/project/5334ae20-e9a6-4c55-9fea-52d4eb9dfba6"><img src="https://wakatime.com/badge/user/45f53c7c-9da9-4cb0-85d6-17bd38cc748b/project/5334ae20-e9a6-4c55-9fea-52d4eb9dfba6.svg" alt="wakatime"></a> <a href="https://wakatime.com/badge/user/45f53c7c-9da9-4cb0-85d6-17bd38cc748b/project/5334ae20-e9a6-4c55-9fea-52d4eb9dfba6"><img src="https://wakatime.com/badge/user/45f53c7c-9da9-4cb0-85d6-17bd38cc748b/project/5334ae20-e9a6-4c55-9fea-52d4eb9dfba6.svg" alt="wakatime"></a>
<a href="https://hits.seeyoufarm.com"><img src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fdonaldzou%2FWGDashboard&count_bg=%2379C83D&title_bg=%23555555&icon=github.svg&icon_color=%23E7E7E7&title=Visitor&edge_flat=false"/></a>
</p> </p>
<p align="center">Monitoring WireGuard is not convinient, need to login into server and type <code>wg show</code>. That's why this platform is being created, to view all configurations and manage them in a easier way.</p> <p align="center">Monitoring WireGuard is not convinient, need to login into server and type <code>wg show</code>. That's why this platform is being created, to view all configurations and manage them in a easier way.</p>
<p align="center"><small>Note: This project is not affiliate to the official WireGuard Project ;)</small></p> <p align="center"><small>Note: This project is not affiliate to the official WireGuard Project ;)</small></p>
@ -115,7 +116,7 @@
1. Download WGDashboard 1. Download WGDashboard
```shell ```shell
git clone -b v3.0 https://github.com/donaldzou/WGDashboard.git wgdashboard git clone -b v3.0.5 https://github.com/donaldzou/WGDashboard.git wgdashboard
2. Open the WGDashboard folder 2. Open the WGDashboard folder
@ -301,7 +302,7 @@ Since version 2.0, WGDashboard will be using a configuration file called `wg-das
| `app_ip` | IP address the dashboard will run with | `0.0.0.0` | Yes | | `app_ip` | IP address the dashboard will run with | `0.0.0.0` | Yes |
| `app_port` | Port the the dashboard will run with | `10086` | Yes | | `app_port` | Port the the dashboard will run with | `10086` | Yes |
| `auth_req` | Does the dashboard need authentication to access, if `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **User can only edit the file directly in system**. | `true` | **No** | | `auth_req` | Does the dashboard need authentication to access, if `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **User can only edit the file directly in system**. | `true` | **No** |
| `version` | Dashboard Version | `v3.0` | **No** | | `version` | Dashboard Version | `v3.0.5` | **No** |
| `dashboard_refresh_interval` | How frequent the dashboard will refresh on the configuration page | `60000ms` | Yes | | `dashboard_refresh_interval` | How frequent the dashboard will refresh on the configuration page | `60000ms` | Yes |
| `dashboard_sort` | How configuration is sorting | `status` | Yes | | `dashboard_sort` | How configuration is sorting | `status` | Yes |
| | | | | | | | | |
@ -348,15 +349,34 @@ Endpoint = 0.0.0.0:51820
<hr> <hr>
#### Update Method 1 (For `v3.0` or above)
1. Change your directory to `wgdashboard/src`
```bash
cd wgdashboard/src
```
2. Update the dashboard with the following
```bash
./wgd.sh update
```
> If this doesn't work, please use the method below. Sorry about that :(
#### Update Method 2
1. Change your directory to `wgdashboard` 1. Change your directory to `wgdashboard`
```shell ```shell
cd wgdashboard cd wgdashboard/src
``` ```
2. Update the dashboard 2. Update the dashboard
```shell ```shell
git pull https://github.com/donaldzou/WGDashboard.git v3.0 --force git pull https://github.com/donaldzou/WGDashboard.git v3.0.5 --force
``` ```
3. Install 3. Install
@ -365,6 +385,8 @@ Endpoint = 0.0.0.0:51820
./wgd.sh install ./wgd.sh install
``` ```
Starting with `v3.0`, you can simply do `./wgd.sh update` !! (I hope, lol) Starting with `v3.0`, you can simply do `./wgd.sh update` !! (I hope, lol)
## 🥘 Experimental Functions ## 🥘 Experimental Functions

View File

@ -4,7 +4,6 @@ Under Apache-2.0 License
""" """
import sqlite3 import sqlite3
from flask import g
import configparser import configparser
import hashlib import hashlib
import ipaddress import ipaddress
@ -22,7 +21,7 @@ from datetime import datetime, timedelta
from operator import itemgetter 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 import Flask, request, render_template, redirect, url_for, session, jsonify, g
from flask_qrcode import QRcode from flask_qrcode import QRcode
from icmplib import ping, traceroute from icmplib import ping, traceroute
# TESTING # TESTING
@ -33,22 +32,27 @@ from util import regex_match, check_DNS, check_Allowed_IPs, check_remote_endpoin
check_IP_with_range, clean_IP_with_range check_IP_with_range, clean_IP_with_range
# Dashboard Version # Dashboard Version
DASHBOARD_VERSION = 'v3.0' DASHBOARD_VERSION = 'v3.0.5'
# WireGuard's configuration path # WireGuard's configuration path
WG_CONF_PATH = None WG_CONF_PATH = None
# Dashboard Config Name # Dashboard Config Name
configuration_path = os.getenv('CONFIGURATION_PATH', '.') configuration_path = os.getenv('CONFIGURATION_PATH', '.')
DB_PATH = os.path.join(configuration_path, 'db') DB_PATH = os.path.join(configuration_path, 'db')
if not os.path.isdir(DB_PATH): if not os.path.isdir(DB_PATH):
os.mkdir(DB_PATH) os.mkdir(DB_PATH)
DASHBOARD_CONF = os.path.join(configuration_path, 'wg-dashboard.ini') DASHBOARD_CONF = os.path.join(configuration_path, 'wg-dashboard.ini')
# Upgrade Required # Upgrade Required
UPDATE = None UPDATE = None
# Flask App Configuration # Flask App Configuration
app = Flask("WGDashboard") app = Flask("WGDashboard")
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928 app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928
app.secret_key = secrets.token_urlsafe(16) app.secret_key = secrets.token_urlsafe(16)
app.config['TEMPLATES_AUTO_RELOAD'] = True app.config['TEMPLATES_AUTO_RELOAD'] = True
# Enable QR Code Generator # Enable QR Code Generator
QRcode(app) QRcode(app)
socketio = SocketIO(app) socketio = SocketIO(app)
@ -101,7 +105,6 @@ def get_conf_peer_key(config_name):
return config_name + " is not running." return config_name + " is not running."
# Get numbers of connected peer of a configuration
def get_conf_running_peer_number(config_name): def get_conf_running_peer_number(config_name):
""" """
Get number of running peers on wireguard interface. Get number of running peers on wireguard interface.
@ -130,7 +133,6 @@ def get_conf_running_peer_number(config_name):
return running return running
# Read [Interface] section from configuration file
def read_conf_file_interface(config_name): def read_conf_file_interface(config_name):
""" """
Get interface settings. Get interface settings.
@ -163,7 +165,6 @@ def read_conf_file(config_name):
@rtype: dict @rtype: dict
""" """
# Read Configuration File Start
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")
@ -296,6 +297,7 @@ def get_endpoint(config_name):
count += 2 count += 2
def get_allowed_ip(conf_peer_data, config_name): def get_allowed_ip(conf_peer_data, config_name):
""" """
Get allowed ips from all peers of a configuration Get allowed ips from all peers of a configuration
@ -628,7 +630,6 @@ def close_DB(exception):
g.db.close() g.db.close()
# Before request
@app.before_request @app.before_request
def auth_req(): def auth_req():
""" """
@ -680,7 +681,7 @@ def signin():
if "message" in session: if "message" in session:
message = session['message'] message = session['message']
session.pop("message") session.pop("message")
return render_template('signin.html', message=message) return render_template('signin.html', message=message, version=DASHBOARD_VERSION)
# Sign Out # Sign Out
@ -1712,11 +1713,11 @@ def get_host_bind():
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 = config.get("Server", "app_port")
return app_ip, app_port return app_ip, app_port
if __name__ == "__main__": if __name__ == "__main__":
init_dashboard()
UPDATE = check_update() UPDATE = check_update()
config = configparser.ConfigParser(strict=False) config = configparser.ConfigParser(strict=False)
config.read('wg-dashboard.ini') config.read('wg-dashboard.ini')

BIN
src/static/.DS_Store vendored

Binary file not shown.

View File

@ -1,5 +1,6 @@
body { body {
font-size: .875rem; font-size: .875rem;
/*font-family: 'Poppins', sans-serif;*/
} }
.feather { .feather {
@ -407,8 +408,26 @@ main{
.btn{ .btn{
border-radius: 8px; border-radius: 8px;
/*padding: 0.6rem 0.9em;*/
} }
#username, #password{
padding: 0.6rem calc( 0.9rem + 32px );
height: inherit;
}
label[for="username"], label[for="password"]{
font-size: 1rem;
margin: 0 !important;
transform: translateY(30px) translateX(16px);
padding: 0;
}
/*label[for="password"]{*/
/* transform: translateY(32px) translateX(16px);*/
/*}*/
.modal-content{ .modal-content{
border-radius: 10px; border-radius: 10px;
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -171,6 +171,17 @@
return String.fromCharCode.apply(null, base64); return String.fromCharCode.apply(null, base64);
} }
function base64ToKey(base64) {
let binary_string = window.atob(base64);
let len = binary_string.length;
let bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
let uint8 = new Uint8Array(bytes.buffer);
return uint8;
}
function putU32(b, n) function putU32(b, n)
{ {
b.push(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff); b.push(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff);
@ -282,7 +293,8 @@
}; };
}, },
generatePublicKey: function (privateKey){ generatePublicKey: function (privateKey){
return keyToBase64(generatePublicKey(privateKey)) privateKey = base64ToKey(privateKey);
return keyToBase64(generatePublicKey(privateKey));
}, },
generateZipFiles: function(res){ generateZipFiles: function(res){

File diff suppressed because one or more lines are too long

View File

@ -14,41 +14,46 @@
<div class="container-fluid login-container-fluid"> <div class="container-fluid login-container-fluid">
<main role="main" class="container login-container"> <main role="main" class="container login-container">
<div class="login-box" style="margin: auto !important;"> <div class="login-box" style="margin: auto !important;">
<h1 class="text-center">Sign In</h1> <h1 class="text-center">Sign in</h1>
<h5 class="text-center">to WGDashboard</h5>
<form style="margin-left: auto !important; margin-right: auto !important; max-width: 500px;" action="/auth" method="post"> <form style="margin-left: auto !important; margin-right: auto !important; max-width: 500px;" action="/auth" method="post">
{% if message != "" %} {% if message != "" %}
<div class="alert alert-warning" role="alert">You need to sign in first</div> <div class="alert alert-warning" role="alert">You need to sign in first</div>
{% endif %} {% endif %}
<div class="alert alert-danger d-none" role="alert"></div> <div class="alert alert-danger d-none" role="alert" style="margin-top: 1rem; margin-bottom: 0rem;"></div>
<div class="form-group"> <div class="form-group">
<label for="username" class="text-left" style="font-size: 1rem"><i class="bi bi-person-circle"></i> Username</label> <label for="username" class="text-left" style="font-size: 1rem"><i class="bi bi-person-circle"></i></label>
<input type="text" class="form-control" id="username" name="username" required> <input type="text" class="form-control" id="username" name="username" placeholder="Your username" required>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password" class="text-left" style="font-size: 1rem"><i class="bi bi-key-fill"></i> Password</label> <label for="password" class="text-left" style="font-size: 1rem"><i class="bi bi-key-fill"></i></label>
<input type="password" class="form-control" id="password" name="password" required> <input type="password" class="form-control" id="password" name="password" placeholder="Your password" required>
</div> </div>
<button type="submit" class="btn btn-dark" style="width: 100%;">Sign In</button> <button type="submit" class="btn btn-dark" style="width: 100%">Sign In</button>
</form> </form>
</div> </div>
</main> </main>
</div> </div>
<small class="text-muted" style="position: fixed; bottom: 0; width: 100%; text-align: center; margin-bottom: 2rem">Version: {{ version }}</small>
</body> </body>
{% include "footer.html" %} {% include "footer.html" %}
<script> <script>
$("button").on("click", function(e){ let loginButton = $('button[type="submit"]');
let req = $("input[required]"); loginButton.on("click", function(e){
e.preventDefault();
let $password = $("#password");
let $username = $("#username");
let req = [$password, $username];
let check = true let check = true
for (let i = 0; i < req.length; i++){ for (let i = 0; i < req.length; i++){
if ($(req[i]).val().length === 0){ if ($(req[i]).val().length === 0){
$("button").html("Sign In"); loginButton.html("Sign In");
check = false; check = false;
$("input[required]").addClass("is-invalid"); $(req[i]).addClass("is-invalid");
break; break;
} }
} }
if (check){ if (check){
e.preventDefault();
$(this).html("Signing In...").attr("disabled", "disabled"); $(this).html("Signing In...").attr("disabled", "disabled");
$.ajax({ $.ajax({
url: "/auth", url: "/auth",
@ -67,8 +72,8 @@
window.location.replace("/"); window.location.replace("/");
} }
}else{ }else{
$(".alert").html(res.msg).removeClass("d-none"); $(".alert").html(res.msg).removeClass("d-none").fadeIn();
$("button").html("Sign In").removeAttr("disabled"); loginButton.html("Sign In").removeAttr("disabled");
$("input[required]").addClass("is-invalid"); $("input[required]").addClass("is-invalid");
} }
}); });

1
src/wgd.sh Executable file → Normal file
View File

@ -33,6 +33,7 @@ help () {
} }
_check_and_set_venv(){ _check_and_set_venv(){
# This function will not be using in v3.0
# deb/ubuntu users: might need a 'apt install python3.8-venv' # deb/ubuntu users: might need a 'apt install python3.8-venv'
# set up the local environment # set up the local environment
APP_ROOT=`pwd` APP_ROOT=`pwd`