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 @@