From 040f6a8393d552ee43582af6c9e05a11db5ff269 Mon Sep 17 00:00:00 2001 From: Donald Cheng Hong Zou Date: Tue, 4 May 2021 21:26:40 -0400 Subject: [PATCH 1/7] Commit --- .gitignore | 1 + README.md | 144 ++++++++++++++++++++++--------- src/dashboard.py | 70 ++++++++++----- src/templates/configuration.html | 26 ++---- src/templates/footer.html | 14 +-- src/templates/get_conf.html | 13 +-- src/templates/index.html | 8 +- src/templates/settings.html | 26 +++++- src/templates/sidebar.html | 7 +- src/wgd.sh | 14 ++- 10 files changed, 215 insertions(+), 108 deletions(-) diff --git a/.gitignore b/.gitignore index 3758fd9..49f7872 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ tmp __pycache__ src/wg-dashboard.ini src/wg-dashboard.ini +src/static/pic.xd diff --git a/README.md b/README.md index efc99d2..70299f3 100644 --- a/README.md +++ b/README.md @@ -7,42 +7,39 @@

-

-

Monitoring Wireguard is not convinient, need to login into server and type wg show. That's why this platform is being created, to view all configurations in a more straight forward way.

+

Monitoring Wireguard is not convinient, need to login into server and type wg show. That's why this platform is being created, to view all configurations and manage them in a easier way.

+ + + +## 📣 What's New: Version 2.0 + +- Added login function to dashboard + - ***I'm not using the most ideal way to store the username and password, feel free to provide a better way to do this if you any good idea!*** +- Added a config file to the dashboard +- Dashboard config can be change within the **Setting** tab on the side bar +- Adjusted UI +- And much more! ## 💡 Features -- Add peers in configuration -- Manage peer names +- Add peers for each WireGuard configuration +- Manage peer - Delete peers - And many more coming up! Welcome to contribute to this project! ## 📝 Requirement -- Ubuntu 18.04.1 LTS, other OS might work, but haven't test yet. -- ‼️ Make sure you have **Wireguard** installed.‼️ How to install? +- Ubuntu or Debian based OS, other might work, but haven't test yet. Tested on the following OS: + - [x] Ubuntu 18.04.1 LTS + - [ ] If you have tested on other OS and it works perfectly please provide it to me! + +- ‼️ Make sure you have **Wireguard** and **Wireguard-Tools (`wg-quick`)** installed.‼️ How to install? - Configuration files under **/etc/wireguard** - ***Example `.conf` file*** - ``` - [Interface] - Address = 192.168.0.1/24 - SaveConfig = true - PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE - PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE - ListenPort = 12345 - PrivateKey = ABCDEFGHIJKLMNOPQRSTUVWXYZ1234 - - [Peer] - PublicKey = HABCDEFGHIJKLMNOPQRSTUVWXYZ123123123123 - AllowedIPs = 192.168.0.2/32 - - ... - ``` - **Note: For peers, `PublicKey` & `AllowedIPs` is required.** + - **Note: For peers, `PublicKey` & `AllowedIPs` is required.** - Python 3.7+ & Pip3 ``` $ sudo apt-get install python3 python3-pip @@ -50,36 +47,98 @@ ## 🛠 Install -**1. Install Python Dependencies** +1. Download Wireguard Dashboard ``` -$ python3 -m pip install flask tinydb +$ git clone https://github.com/donaldzou/Wireguard-Dashboard.git ``` -**2. Install Wireguard Dashboard** - -``` -$ git clone -b v1.1.2 https://github.com/donaldzou/Wireguard-Dashboard.git -$ cd Wireguard-Dashboard/src -$ python3 dashboard.py -``` - -Access your server with port `10086` ! e.g (http://your_server_ip:10086) - -**3. Install with Production Mode (Optional), not tested yet. ‼️ Proceed with caution. ‼️** +**2. Install Python Dependencies** ``` $ cd Wireguard-Dashboard/src -$ export FLASK_APP=dashboard.py -$ export FLASK_RUN_HOST=0.0.0.0 -$ export FLASK_ENV=development -$ export FLASK_DEBUG=0 -$ flask run +$ python3 -m pip install -r requirements.txt ``` +**3. Install & run Wireguard Dashboard** + +``` +$ sudo sh wgd.sh start +``` + +Access your server with port `10086` ! e.g (http://your_server_ip:10086), continue to read to on how to change port and ip that dashboard is running with. + +## 🪜 Usage + +**1. Start/Stop/Restart Wireguard Dashboard** + +``` +$ cd Wireguard-Dashboard/src +$ sudo sh wgd.sh start # Start the dashboard in background +$ sudo sh wgd.sh debug # Start the dashboard in foreground (debug mode) +$ sudo sh wgd.sh stop # Stop the dashboard +$ sudo sh wgd.sh restart # Restart the dasboard +$ sudo sh wgd.sh update # Update the dashboard +``` + +⚠️ **For first time user please also read the next section.** + +## ✂️ Dashboard Configuration + +Since version 2.0, Wireguard Dashboard will be using a configuration file called `wg-dashboard.ini`, (It will generate automatically after first time running the dashboard). More options will include in future versions, and for now it included the following config: + +- `[Account]` + - `username` - Username (Default: `admin`) + - `password` - Password, will be hash with SHA256 (Default: `admin`). +- `[Server]` + - `app_ip` - IP address the flask will run with (Default: `0.0.0.0`) + - `app_port` - Port the flask will run with (Default: `10086`) + - `auth_req` - Does the dashboard need authentication (Default: `true`) + - If `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **Can only changing the file directly in system**. + - `version` - Dashboard Version + +All these settings***** will be able to configure within the dashboard in **Settings** on the sidebar, without changing the actual file. + +- Example + +``` +[Account] +username = admin +password = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 + +[Server] +app_ip = 0.0.0.0 +app_port = 10086 +auth_req = true +version = v2.0 +``` + +**: Except `version` and `auth_req` due to security consideration.* + +## ❓ How to update the dashboard? + +``` +$ cd wireguard-dashboard +$ sudo sh wgd.sh update # Perform update +$ sudo sh wgd.sh start # Start dashboard + ## 🔍 Example + ![Index Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/index.png) -![Conf Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/configuration.png) + +

Index Page

+ +![Signin Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/signin.png) + +

Signin Page

+ +![Configuration Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/configuration.png) + +

Configuration Page

+ +![Settings Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/settings.png) + +

Settings Page

## Contributors ✨ @@ -105,3 +164,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! + diff --git a/src/dashboard.py b/src/dashboard.py index be237a8..69033c6 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -11,17 +11,17 @@ import configparser # PIP installed library import ifcfg from tinydb import TinyDB, Query - - dashboard_version = 'v2.0' dashboard_conf = 'wg-dashboard.ini' -conf_location = "/etc/wireguard" +update = "" + app = Flask("Wireguard Dashboard") app.secret_key = secrets.token_urlsafe(16) app.config['TEMPLATES_AUTO_RELOAD'] = True conf_data = {} + def get_conf_peer_key(config_name): keys = [] try: @@ -53,7 +53,7 @@ def get_conf_running_peer_number(config_name): def read_conf_file(config_name): # Read Configuration File Start - conf_location = "/etc/wireguard/" + config_name + ".conf" + conf_location = wg_conf_path+"/" + config_name + ".conf" f = open(conf_location, 'r') file = f.read().split("\n") conf_peer_data = { @@ -188,7 +188,7 @@ def get_peers(config_name): def get_conf_pub_key(config_name): conf = configparser.ConfigParser(strict=False) - conf.read(conf_location+"/"+config_name+".conf") + conf.read(wg_conf_path + "/" + config_name + ".conf") pri = conf.get("Interface", "PrivateKey") pub = subprocess.check_output("echo '" + pri + "' | wg pubkey", shell=True) conf.clear() @@ -197,7 +197,7 @@ def get_conf_pub_key(config_name): def get_conf_listen_port(config_name): conf = configparser.ConfigParser(strict=False) - conf.read(conf_location + "/" + config_name + ".conf") + conf.read(wg_conf_path + "/" + config_name + ".conf") port = conf.get("Interface", "ListenPort") conf.clear() return port @@ -224,7 +224,7 @@ def get_conf_status(config_name): def get_conf_list(): conf = [] - for i in os.listdir(conf_location): + for i in os.listdir(wg_conf_path): if not i.startswith('.'): if ".conf" in i: i = i.replace('.conf', '') @@ -246,6 +246,8 @@ def auth_req(): conf = configparser.ConfigParser(strict=False) conf.read(dashboard_conf) req = conf.get("Server", "auth_req") + session['update'] = update + session['dashboard_version'] = dashboard_version if req == "true": if '/static/' not in request.path and \ request.endpoint != "signin" and \ @@ -256,7 +258,7 @@ def auth_req(): print("not loggedin") return redirect(url_for("signin")) else: - if request.endpoint in ['signin', 'signout', 'auth', 'settings', 'update_acct', 'update_pwd', 'update_app_ip_port']: + if request.endpoint in ['signin', 'signout', 'auth', 'settings', 'update_acct', 'update_pwd', 'update_app_ip_port', 'update_wg_conf_path']: return redirect(url_for("index")) @app.route('/signin', methods=['GET']) @@ -289,7 +291,7 @@ def settings(): session.pop("message") session.pop("message_status") required_auth = config.get("Server", "auth_req") - return render_template('settings.html',conf=get_conf_list(),message=message, status=status, app_ip = config.get("Server", "app_ip"), app_port = config.get("Server", "app_port"), required_auth=required_auth) + return render_template('settings.html',conf=get_conf_list(),message=message, status=status, app_ip=config.get("Server", "app_ip"), app_port=config.get("Server", "app_port"), required_auth=required_auth, wg_conf_path=config.get("Server", "wg_conf_path")) @app.route('/auth', methods=['POST']) def auth(): @@ -362,19 +364,24 @@ def update_app_ip_port(): config.clear() os.system('bash wgd.sh restart') -@app.route('/check_update_dashboard', methods=['GET']) -def check_update_dashboard(): - conf = configparser.ConfigParser(strict=False) - conf.read(dashboard_conf) - data = urllib.request.urlopen("https://api.github.com/repos/donaldzou/wireguard-dashboard/releases").read() - output = json.loads(data) - if conf.get("Server", "version") == output[0]["tag_name"]: - return "false" - else: - return "true" +@app.route('/update_wg_conf_path', methods=['POST']) +def update_wg_conf_path(): + config = configparser.ConfigParser(strict=False) + config.read(dashboard_conf) + config.set("Server", "wg_conf_path", request.form['wg_conf_path']) + config.write(open(dashboard_conf, "w")) + session['message'] = "WireGuard Configuration Path Update Successfully!" + session['message_status'] = "success" + config.clear() + os.system('bash wgd.sh restart') + +# @app.route('/check_update_dashboard', methods=['GET']) +# def check_update_dashboard(): +# return have_update @app.route('/', methods=['GET']) def index(): + print(request.referrer) return render_template('index.html', conf=get_conf_list()) @app.route('/configuration/', methods=['GET']) @@ -427,7 +434,8 @@ def switch(config_name): status = subprocess.check_output("wg-quick up " + config_name, shell=True) except Exception: return redirect('/') - return redirect('/') + + return redirect(request.referrer) @app.route('/add_peer/', methods=['POST']) @@ -453,6 +461,9 @@ def add_peer(config_name): @app.route('/remove_peer/', methods=['POST']) 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() @@ -494,8 +505,7 @@ def get_peer_name(config_name): def init_dashboard(): # Set Default INI File - conf = configparser.ConfigParser(strict=False) - if os.path.isfile("wg-dashboard.ini") == False: + if not os.path.isfile("wg-dashboard.ini"): conf_file = open("wg-dashboard.ini", "w+") config = configparser.ConfigParser(strict=False) config.read(dashboard_conf) @@ -509,6 +519,8 @@ def init_dashboard(): if "Server" not in config: config['Server'] = {} + if 'wg_conf_path' not in config['Server']: + config['Server']['wg_conf_path'] = '/etc/wireguard' if 'app_ip' not in config['Server']: config['Server']['app_ip'] = '0.0.0.0' if 'app_port' not in config['Server']: @@ -518,13 +530,27 @@ def init_dashboard(): if 'version' not in config['Server'] or config['Server']['version'] != dashboard_version: config['Server']['version'] = dashboard_version config.write(open(dashboard_conf, "w")) + config.clear() + +def check_update(): + conf = configparser.ConfigParser(strict=False) + conf.read(dashboard_conf) + data = urllib.request.urlopen("https://api.github.com/repos/donaldzou/wireguard-dashboard/releases").read() + output = json.loads(data) + if conf.get("Server", "version") == output[0]["tag_name"]: + return "false" + else: + return "true" + if __name__ == "__main__": init_dashboard() + update = check_update() config = configparser.ConfigParser(strict=False) config.read('wg-dashboard.ini') app_ip = config.get("Server", "app_ip") app_port = config.get("Server", "app_port") + wg_conf_path = config.get("Server", "wg_conf_path") config.clear() app.run(host=app_ip, debug=False, port=app_port) diff --git a/src/templates/configuration.html b/src/templates/configuration.html index 73c771f..007b2fc 100644 --- a/src/templates/configuration.html +++ b/src/templates/configuration.html @@ -108,13 +108,7 @@ - - - +{% include "footer.html" %} - - \ No newline at end of file + crossorigin="anonymous"> \ No newline at end of file diff --git a/src/templates/get_conf.html b/src/templates/get_conf.html index cbff4f3..9b2040f 100644 --- a/src/templates/get_conf.html +++ b/src/templates/get_conf.html @@ -1,26 +1,27 @@
-
+
CONFIGURATION

{{conf_data['name']}}

-
+
ACTION
-{# #} - {% if conf_data['checked'] == "checked" %} ON {% else %} OFF {% endif %} +
-
+
STATUS
{{conf_data['status']}}
-
+
CONNECTED PEERS
{{conf_data['running_peer']}}
diff --git a/src/templates/index.html b/src/templates/index.html index 8c21d04..f04be7f 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -5,6 +5,7 @@
{% include "sidebar.html" %}
+

Home

{% for i in conf%}
@@ -25,10 +26,13 @@
{% if i['checked'] == "checked" %} - + {% else %} {% endif %} +
@@ -40,6 +44,8 @@ {% include "footer.html" %} \ No newline at end of file diff --git a/src/templates/sidebar.html b/src/templates/sidebar.html index 00fd86d..751a640 100644 --- a/src/templates/sidebar.html +++ b/src/templates/sidebar.html @@ -7,7 +7,9 @@ {% if "username" in session %} {% endif %} - + {% if session['update'] == "true" %} + + {% endif %}
diff --git a/src/wgd.sh b/src/wgd.sh index ec90bb9..7c4a426 100644 --- a/src/wgd.sh +++ b/src/wgd.sh @@ -43,6 +43,18 @@ start_wgd_debug() { python3 "$app_name" } +update_wgd() { + git pull + if check_wgd_status; then + stop_wgd + sleep 2 + printf "Wireguard Dashboard is stopped. \n" + start_wgd_debug + else + start_wgd_debug + fi +} + if [ "$#" != 1 ]; @@ -63,7 +75,7 @@ if [ "$#" != 1 ]; printf "Wireguard Dashboard is not running. \n" fi elif [ "$1" = "update" ]; then - echo "update"; + update_wgd elif [ "$1" = "restart" ]; then if check_wgd_status; then stop_wgd From fe7b9730d34673f519c61fcb4eabf0039cf9e66d Mon Sep 17 00:00:00 2001 From: Donald Cheng Hong Zou Date: Tue, 4 May 2021 21:41:13 -0400 Subject: [PATCH 2/7] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 70299f3..6fb059f 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,9 @@ version = v2.0 $ cd wireguard-dashboard $ sudo sh wgd.sh update # Perform update $ sudo sh wgd.sh start # Start dashboard +``` + + ## 🔍 Example From 0fa4759c3aa2785b0b926e81b8dcb935d6eb3cdc Mon Sep 17 00:00:00 2001 From: Donald Cheng Hong Zou Date: Wed, 5 May 2021 14:38:10 -0400 Subject: [PATCH 3/7] Update --- README.md | 72 +++++++++++++++++++++++++------------- src/dashboard.py | 7 ++-- src/templates/sidebar.html | 2 +- src/wgd.sh | 36 ++++++++++++++----- 4 files changed, 80 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 6fb059f..c85c8d9 100644 --- a/README.md +++ b/README.md @@ -16,20 +16,40 @@ ## 📣 What's New: Version 2.0 +### ⚠️ **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` to get the new update inside `Wireguard-Dashboard` directory. +3. Proceed **Step 2 & 3** in the Install step down below. + +
+ - Added login function to dashboard + - ***I'm not using the most ideal way to store the username and password, feel free to provide a better way to do this if you any good idea!*** + - Added a config file to the dashboard + - Dashboard config can be change within the **Setting** tab on the side bar + - Adjusted UI + - And much more! + + ## 💡 Features - Add peers for each WireGuard configuration + - Manage peer + - Delete peers + - And many more coming up! Welcome to contribute to this project! + + ## 📝 Requirement - Ubuntu or Debian based OS, other might work, but haven't test yet. Tested on the following OS: @@ -45,12 +65,14 @@ $ sudo apt-get install python3 python3-pip ``` + + ## 🛠 Install 1. Download Wireguard Dashboard ``` -$ git clone https://github.com/donaldzou/Wireguard-Dashboard.git +$ git clone -b v2.0 https://github.com/donaldzou/Wireguard-Dashboard.git ``` **2. Install Python Dependencies** @@ -68,6 +90,8 @@ $ sudo sh wgd.sh start Access your server with port `10086` ! e.g (http://your_server_ip:10086), continue to read to on how to change port and ip that dashboard is running with. + + ## 🪜 Usage **1. Start/Stop/Restart Wireguard Dashboard** @@ -81,39 +105,37 @@ $ sudo sh wgd.sh restart # Restart the dasboard $ sudo sh wgd.sh update # Update the dashboard ``` -⚠️ **For first time user please also read the next section.** +⚠️ **For first time user please also read the next section.** + + ## ✂️ Dashboard Configuration Since version 2.0, Wireguard Dashboard will be using a configuration file called `wg-dashboard.ini`, (It will generate automatically after first time running the dashboard). More options will include in future versions, and for now it included the following config: -- `[Account]` - - `username` - Username (Default: `admin`) - - `password` - Password, will be hash with SHA256 (Default: `admin`). -- `[Server]` - - `app_ip` - IP address the flask will run with (Default: `0.0.0.0`) - - `app_port` - Port the flask will run with (Default: `10086`) - - `auth_req` - Does the dashboard need authentication (Default: `true`) - - If `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **Can only changing the file directly in system**. - - `version` - Dashboard Version +### `[Account]` -All these settings***** will be able to configure within the dashboard in **Settings** on the sidebar, without changing the actual file. +`username` - Username (Default: `admin`) -- Example +`password` - Password, will be hash with SHA256 (Default: `admin`). -``` -[Account] -username = admin -password = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 +### `[Server]` + +`wg_conf_path` - The path of all the Wireguard configurations (Default: `/etc/wireguard`) + +`app_ip` - IP address the flask will run with (Default: `0.0.0.0`) + +`app_port` - Port the flask will run with (Default: `10086`) + +`auth_req` - Does the dashboard need authentication (Default: `true`) + +- If `auth_req = false` , user will not be access the **Setting** tab due to security consideration. **User can only change the file directly in system**. + +`version` - Dashboard Version + +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.** -[Server] -app_ip = 0.0.0.0 -app_port = 10086 -auth_req = true -version = v2.0 -``` -**: Except `version` and `auth_req` due to security consideration.* ## ❓ How to update the dashboard? @@ -125,7 +147,7 @@ $ sudo sh wgd.sh start # Start dashboard -## 🔍 Example +## 🔍 Screenshot ![Index Image](https://github.com/donaldzou/Wireguard-Dashboard/raw/main/src/static/index.png) diff --git a/src/dashboard.py b/src/dashboard.py index 69033c6..153d463 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -1,3 +1,6 @@ +dashboard_version = 'v2.0' + + # Python Built-in Library import os from flask import Flask, request, render_template, redirect, url_for, session, abort @@ -11,10 +14,8 @@ import configparser # PIP installed library import ifcfg from tinydb import TinyDB, Query -dashboard_version = 'v2.0' dashboard_conf = 'wg-dashboard.ini' update = "" - app = Flask("Wireguard Dashboard") app.secret_key = secrets.token_urlsafe(16) app.config['TEMPLATES_AUTO_RELOAD'] = True @@ -254,8 +255,8 @@ def auth_req(): request.endpoint != "signout" and \ request.endpoint != "auth" and \ "username" not in session: - print(request.path) print("not loggedin") + session['message'] = "You need to sign in first!" return redirect(url_for("signin")) else: if request.endpoint in ['signin', 'signout', 'auth', 'settings', 'update_acct', 'update_pwd', 'update_app_ip_port', 'update_wg_conf_path']: diff --git a/src/templates/sidebar.html b/src/templates/sidebar.html index 751a640..5995ad2 100644 --- a/src/templates/sidebar.html +++ b/src/templates/sidebar.html @@ -8,7 +8,7 @@ {% endif %} {% if session['update'] == "true" %} - + {% endif %}
diff --git a/src/wgd.sh b/src/wgd.sh index 7c4a426..f07253f 100644 --- a/src/wgd.sh +++ b/src/wgd.sh @@ -1,7 +1,7 @@ #!/bin/bash app_name="dashboard.py" - +dashes='------------------------------------------------------------' help () { printf " by Donald Zou - https://github.com/donaldzou \n" printf "Usage: sh wg-dashboard.sh