diff --git a/README.md b/README.md index 4404d5a4..4a0b01ae 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,14 @@

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.1 +## 📣 What's New: Version v2.2 -- 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)) +- 🎉 **New Features** + - **QR Code**: You can add the private key of your existed peer to create a QR code, or just create a new one, dashboard will now be able to auto generate a private key and public key ;) Don't worry, all keys will be generated on your machine, and **will delete all key files after they got generated**. + - **Autostart on boot**: Added a tutorial on how to start the dashboard to on boot! Please read the [tutorial below](https://github.com/donaldzou/wireguard-dashboard/tree/v2.2-beta#autostart-wireguard-dashboard-on-boot). +- 🪚 **Bug Fixed** + - When there are comments in the wireguard config file, will cause the dashboard to crash. + - Used regex to search for config files.
@@ -34,10 +35,14 @@ - [🛠 Install](https://github.com/donaldzou/wireguard-dashboard#-install) - [🪜 Usage](https://github.com/donaldzou/wireguard-dashboard#-usage) - [✂️ Dashboard Configuration](https://github.com/donaldzou/wireguard-dashboard#%EF%B8%8F-dashboard-configuration) + - [Start/Stop/Restart Wireguard Dashboard](https://github.com/donaldzou/wireguard-dashboard/tree/v2.2-beta#startstoprestart-wireguard-dashboard) + - [Autostart Wireguard Dashboard on boot](https://github.com/donaldzou/wireguard-dashboard/tree/v2.2-beta#autostart-wireguard-dashboard-on-boot) - [❓ How to update the dashboard?](https://github.com/donaldzou/wireguard-dashboard#-how-to-update-the-dashboard) - [⚠️ Update from v1.x.x](https://github.com/donaldzou/wireguard-dashboard#%EF%B8%8F--update-from-v1xx) - [🔍 Screenshot](https://github.com/donaldzou/wireguard-dashboard#-screenshot) + + ## 💡 Features - Add peers for each WireGuard configuration @@ -71,7 +76,7 @@ 1. **Download Wireguard Dashboard** ```shell - $ git clone -b v2.1 https://github.com/donaldzou/Wireguard-Dashboard.git + $ git clone -b vv2.2 https://github.com/donaldzou/Wireguard-Dashboard.git 2. **Install Python Dependencies** ```shell @@ -262,7 +267,7 @@ All these settings will be able to configure within the dashboard in **Settings* ``` 2. Get the newest version ``` - $ sudo git pull https://github.com/donaldzou/wireguard-dashboard.git v2.1 --force + $ sudo git pull https://github.com/donaldzou/wireguard-dashboard.git vv2.2 --force ``` 3. Update and install all python dependencies ``` @@ -275,7 +280,7 @@ All these settings will be able to configure within the dashboard in **Settings* ### ⚠️ **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. +2. You can use `git pull https://github.com/donaldzou/Wireguard-Dashboard.git vv2.2` to get the new update inside `Wireguard-Dashboard` directory. 3. Proceed **Step 2 & 3** in the [Install](#-install) step down below. ## 🔍 Screenshot diff --git a/src/dashboard.py b/src/dashboard.py index c59e33d5..2019e201 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -13,6 +13,7 @@ import configparser import re # PIP installed library import ifcfg +from flask_qrcode import QRcode from tinydb import TinyDB, Query from icmplib import ping, multiping, traceroute, resolve, Host, Hop @@ -20,12 +21,16 @@ from icmplib import ping, multiping, traceroute, resolve, Host, Hop dashboard_version = 'v2.1' # Dashboard Config Name dashboard_conf = 'wg-dashboard.ini' +# Default Wireguard IP +wg_ip = ifcfg.default_interface()['inet'] + # Upgrade Required update = "" # Flask App Configuration app = Flask("Wireguard Dashboard") app.secret_key = secrets.token_urlsafe(16) app.config['TEMPLATES_AUTO_RELOAD'] = True +QRcode(app) def get_conf_peer_key(config_name): @@ -54,7 +59,6 @@ def get_conf_running_peer_number(config_name): count += 2 return running - def is_match(regex, text): pattern = re.compile(regex) return pattern.search(text) is not None @@ -97,7 +101,6 @@ def read_conf_file(config_name): # Read Configuration File End return conf_peer_data - def get_latest_handshake(config_name, db, peers): # Get latest handshakes try: @@ -172,17 +175,17 @@ def get_allowed_ip(config_name, db, peers, conf_peer_data): 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']): + search = db.search(peers.id == i['PublicKey']) + if not search: db.insert({ "id": i['PublicKey'], + "private_key": "", "name": "", "total_receive": 0, "total_sent": 0, @@ -193,6 +196,10 @@ def get_conf_peers_data(config_name): "allowed_ip": 0, "traffic": [] }) + else: + # Update database since V2.2 + if "private_key" not in search[0]: + db.update({'private_key':''}, peers.id == i['PublicKey']) tic = time.perf_counter() get_latest_handshake(config_name, db, peers) @@ -203,11 +210,6 @@ def get_conf_peers_data(config_name): 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') @@ -216,7 +218,6 @@ def get_peers(config_name): db.close() return result - def get_conf_pub_key(config_name): conf = configparser.ConfigParser(strict=False) conf.read(wg_conf_path + "/" + config_name + ".conf") @@ -225,7 +226,6 @@ def get_conf_pub_key(config_name): conf.clear() return pub.decode().strip("\n") - def get_conf_listen_port(config_name): conf = configparser.ConfigParser(strict=False) conf.read(wg_conf_path + "/" + config_name + ".conf") @@ -233,7 +233,6 @@ def get_conf_listen_port(config_name): conf.clear() return port - def get_conf_total_data(config_name): db = TinyDB('db/' + config_name + '.json') upload_total = 0 @@ -250,7 +249,6 @@ def get_conf_total_data(config_name): db.close() return [total, upload_total, download_total] - def get_conf_status(config_name): ifconfig = dict(ifcfg.interfaces().items()) if config_name in ifconfig.keys(): @@ -258,24 +256,21 @@ def get_conf_status(config_name): else: return "stopped" - def get_conf_list(): conf = [] for i in os.listdir(wg_conf_path): - if not i.startswith('.'): - if ".conf" in i: - i = i.replace('.conf', '') - temp = {"conf": i, "status": get_conf_status(i), "public_key": get_conf_pub_key(i)} - if temp['status'] == "running": - temp['checked'] = 'checked' - else: - temp['checked'] = "" - conf.append(temp) + if is_match("^(.{1,}).(conf)$", i): + i = i.replace('.conf', '') + temp = {"conf": i, "status": get_conf_status(i), "public_key": get_conf_pub_key(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 - @app.before_request def auth_req(): conf = configparser.ConfigParser(strict=False) @@ -520,7 +515,7 @@ def get_conf(config_name): conf_data['checked'] = "nope" else: conf_data['checked'] = "checked" - return render_template('get_conf.html', conf=get_conf_list(), conf_data=conf_data) + return render_template('get_conf.html', conf=get_conf_list(), conf_data=conf_data, wg_ip=wg_ip) @app.route('/switch/', methods=['GET']) @@ -552,7 +547,7 @@ def add_peer(config_name): if type(keys) != list: return config_name+" is not running." if public_key in keys: - return "Key already exist." + return "Public key already exist." else: status = "" try: @@ -562,7 +557,7 @@ def add_peer(config_name): get_conf_peers_data(config_name) db = TinyDB("db/" + config_name + ".json") peers = Query() - db.update({"name": data['name']}, peers.id == public_key) + db.update({"name": data['name'], "private_key": data['private_key']}, peers.id == public_key) db.close() return "true" except subprocess.CalledProcessError as exc: @@ -617,8 +612,37 @@ def get_peer_name(config_name): db.close() return result[0]['name'] +@app.route('/generate_peer', methods=['GET']) +def generate_peer(): + 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_key = private.readline().strip() + public = open('public_key.txt') + public_key = public.readline().strip() + data = {"private_key": private_key, "public_key": public_key} + private.close() + public.close() + os.remove('private_key.txt') + os.remove('public_key.txt') + return jsonify(data) - +@app.route('/generate_public_key', methods=['POST']) +def generate_public_key(): + data = request.get_json() + private_key = data['private_key'] + pri_key_file = open('private_key.txt', 'w') + pri_key_file.write(private_key) + pri_key_file.close() + try: + check = subprocess.check_output("wg pubkey < private_key.txt > public_key.txt", shell=True) + public = open('public_key.txt') + public_key = public.readline().strip() + os.remove('private_key.txt') + os.remove('public_key.txt') + return jsonify({"status":'success', "msg":"", "data":public_key}) + except subprocess.CalledProcessError as exc: + os.remove('private_key.txt') + return jsonify({"status":'failed', "msg":"Key is not the correct length or format", "data":""}) def init_dashboard(): # Set Default INI File diff --git a/src/private_key.txt b/src/private_key.txt new file mode 100644 index 00000000..adb45a46 --- /dev/null +++ b/src/private_key.txt @@ -0,0 +1 @@ +NZV8Z5QOobhbM4f6RLtICNghumYT30aKUxaUNmEtulM= \ No newline at end of file diff --git a/src/public_key.txt b/src/public_key.txt new file mode 100644 index 00000000..6a93f060 --- /dev/null +++ b/src/public_key.txt @@ -0,0 +1 @@ +NZV8Z5QOobhbM4f6RLtICNghumYT30aKUxaUNmEtulM= diff --git a/src/static/dashboard.css b/src/static/dashboard.css index 482b6b2c..3d7c51f2 100644 --- a/src/static/dashboard.css +++ b/src/static/dashboard.css @@ -195,4 +195,40 @@ main{ /* padding: 0.75rem 1.5rem;*/ /* border-radius: 3rem;*/ /* font-size: 1rem;*/ -/*}*/ \ No newline at end of file +/*}*/ + +@-webkit-keyframes rotating /* Safari and Chrome */ { + from { + -webkit-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes rotating { + from { + -ms-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -webkit-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} +.rotating::before { + -webkit-animation: rotating 0.75s linear infinite; + -moz-animation: rotating 0.75s linear infinite; + -ms-animation: rotating 0.75s linear infinite; + -o-animation: rotating 0.75s linear infinite; + animation: rotating 0.75s linear infinite; +} \ No newline at end of file diff --git a/src/templates/configuration.html b/src/templates/configuration.html index 91835931..0e0114c5 100644 --- a/src/templates/configuration.html +++ b/src/templates/configuration.html @@ -23,16 +23,32 @@
-
- - + +
+ +
+
+ +
+ +
- + + +
+ +
+
- +
@@ -95,6 +111,23 @@
+ +