diff --git a/.all-contributorsrc b/.all-contributorsrc
index 4a636dd..eb8b2ff 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -41,10 +41,19 @@
"contributions": [
"code"
]
+ },
+ {
+ "login": "marneu",
+ "name": "Markus Neubauer",
+ "avatar_url": "https://avatars.githubusercontent.com/u/5978293?v=4",
+ "profile": "http://www.std-soft.com",
+ "contributions": [
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
- "projectName": "wireguard-dashboard",
+ "projectName": "WGDashboard",
"projectOwner": "donaldzou",
"repoType": "github",
"repoHost": "https://github.com",
diff --git a/.gitignore b/.gitignore
index 8104ed3..6ec7b5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,7 @@ src/wg-dashboard.ini
src/static/pic.xd
*.conf
private_key.txt
-public_key.txt
\ No newline at end of file
+public_key.txt
+venv/**
+log/**
+*~
\ No newline at end of file
diff --git a/README.md b/README.md
index 333bd4b..cad7393 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,14 @@
-Please provide your OS name and version if you can run the dashboard on it perfectly in #31 , since I only tested on Ubuntu. Thank you!
-
+> Hi! I'm planning the next major update for this project, please let me know if you have any suggestions or feature requests ;) You can create an issue with the "Feature request" template. Cheers!
+### Help Wanted
+
+> If anyone know a better way to distribute releases of python application other than GitHub, please let me know in #103 !
+
+> Please provide your OS name and version if you can run the dashboard on it perfectly in #31 , since I only tested on Ubuntu. Thank you!
+
+
@@ -13,6 +19,7 @@
+
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.
Note: This project is not affiliate to the official WireGuard Project ;)
@@ -426,7 +433,7 @@ Bug Fixed:
## ✨ Contributors
-[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)
+[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -436,10 +443,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
diff --git a/src/dashboard.py b/src/dashboard.py
index c9a2c47..0dca1f3 100644
--- a/src/dashboard.py
+++ b/src/dashboard.py
@@ -23,7 +23,7 @@ from flask_qrcode import QRcode
from tinydb import TinyDB, Query
from icmplib import ping, multiping, traceroute, resolve, Host, Hop
# Dashboard Version
-dashboard_version = 'v2.3.1'
+dashboard_version = 'v3.0'
# Dashboard Config Name
configuration_path = os.getenv('CONFIGURATION_PATH', '.')
db_path = os.path.join(configuration_path, 'db')
@@ -47,10 +47,22 @@ def regex_match(regex, text):
pattern = re.compile(regex)
return pattern.search(text) is not None
-# Check IP format (IPv4 only now)
-# TODO: Add IPv6 support
+# Check IP format
def check_IP(ip):
- return regex_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}", ip)
+ ip_patterns = (
+ r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}",
+ r"[0-9a-fA-F]{0,4}(:([0-9a-fA-F]{0,4})){1,7}$"
+ )
+
+ for match_pattern in ip_patterns:
+ match_result = regex_match(match_pattern, ip)
+ if match_result:
+ result = match_result
+ break
+ else:
+ result = None
+
+ return result
# Clean IP
def clean_IP(ip):
@@ -60,11 +72,22 @@ def clean_IP(ip):
def clean_IP_with_range(ip):
return clean_IP(ip).split(',')
-# Check IP with range (IPv4 only now)
-# TODO: Add IPv6 support
+# Check IP with range
def check_IP_with_range(ip):
- return regex_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|\/)){4}(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|" +
- "18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)(,|$)", ip)
+ ip_patterns = (
+ r"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|\/)){4}([0-9]{1,2})(,|$)",
+ r"[0-9a-fA-F]{0,4}(:([0-9a-fA-F]{0,4})){1,7}\/([0-9]{1,3})(,|$)"
+ )
+
+ for match_pattern in ip_patterns:
+ match_result = regex_match(match_pattern, ip)
+ if match_result:
+ result = match_result
+ break
+ else:
+ result = None
+
+ return result
# Check allowed ips list
def check_Allowed_IPs(ip):
@@ -78,14 +101,14 @@ def check_DNS(dns):
dns = dns.replace(' ','').split(',')
status = True
for i in dns:
- if not (regex_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}", i) or regex_match("(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]",i)):
+ if not (check_IP(i) or regex_match("(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]",i)):
return False
return True
-# Check remote endpoint (Both IPv4 address and valid hostname)
-# TODO: Add IPv6 support
+# Check remote endpoint
def check_remote_endpoint(address):
- return (regex_match("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}", address) or regex_match("(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]",address))
+
+ return (check_IP(address) or regex_match("(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z][a-z]{0,61}[a-z]", address))
"""
@@ -999,7 +1022,9 @@ def download(config_name):
private_key = peer['private_key']
allowed_ip = peer['allowed_ip']
DNS = peer['DNS']
+ MTU = peer['mtu']
endpoint_allowed_ip = peer['endpoint_allowed_ip']
+ keepalive = peer['keepalive']
filename = peer['name']
if len(filename) == 0:
filename = "Untitled_Peers"
@@ -1016,10 +1041,10 @@ def download(config_name):
filename = "".join(filename.split(' '))
filename = filename + "_" + config_name
- def generate(private_key, allowed_ip, DNS, public_key, endpoint):
- yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = "+endpoint_allowed_ip+"\nEndpoint = " + endpoint
+ def generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive):
+ yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\nMTU = " + MTU + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + endpoint+ "\nPersistentKeepalive = " + keepalive
- return app.response_class(generate(private_key, allowed_ip, DNS, public_key, endpoint),
+ return app.response_class(generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive),
mimetype='text/conf',
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
else:
@@ -1120,6 +1145,7 @@ def init_dashboard():
config['Server'] = {}
if 'wg_conf_path' not in config['Server']:
config['Server']['wg_conf_path'] = '/etc/wireguard'
+ # TODO: IPv6 for the app IP might need to configure with Gunicorn...
if 'app_ip' not in config['Server']:
config['Server']['app_ip'] = '0.0.0.0'
if 'app_port' not in config['Server']:
diff --git a/src/templates/get_conf.html b/src/templates/get_conf.html
index 1032ad7..4b95885 100644
--- a/src/templates/get_conf.html
+++ b/src/templates/get_conf.html
@@ -182,7 +182,7 @@
{% if i['private_key'] %}
-
+
diff --git a/src/wg-dashboard.service b/src/wg-dashboard.service
index 9a596df..d6ca41f 100644
--- a/src/wg-dashboard.service
+++ b/src/wg-dashboard.service
@@ -1,11 +1,14 @@
[Unit]
-After=netword.service
+After=syslog.target network-online.target
+ConditionPathIsDirectory=/etc/wireguard
[Service]
-WorkingDirectory=
-ExecStart=/usr/bin/python3 dashboard.py
+Environment="VIRTUAL_ENV={{VIRTUAL_ENV}}"
+WorkingDirectory={{APP_ROOT}}
+ExecStart={{VIRTUAL_ENV}}/bin/python3 {{APP_ROOT}}/dashboard.py
+PrivateTmp=yes
Restart=always
[Install]
-WantedBy=default.target
\ No newline at end of file
+WantedBy=multi-user.target
diff --git a/src/wgd.sh b/src/wgd.sh
index 3676947..bc0705f 100755
--- a/src/wgd.sh
+++ b/src/wgd.sh
@@ -20,6 +20,17 @@ help () {
printf "=================================================================================\n"
}
+_check_and_set_venv(){
+ # deb/ubuntu users: might need a 'apt install python3.8-venv'
+ # set up the local environment
+ APP_ROOT=`pwd`
+ VIRTUAL_ENV="${APP_ROOT%/*}/venv"
+ if [ ! -d $VIRTUAL_ENV ]; then
+ python3 -m venv $VIRTUAL_ENV
+ fi
+ . ${VIRTUAL_ENV}/bin/activate
+}
+
install_wgd(){
# Check Python3 version
version_pass=$(python3 -c 'import sys; print("1") if (sys.version_info.major == 3 and sys.version_info.minor >= 7) else print("0");')
@@ -33,9 +44,24 @@ install_wgd(){
then mkdir "log"
fi
printf "| Installing latest Python dependencies |\n"
+
+ # set up the local environment
+ _check_and_set_venv
+
python3 -m pip install -r requirements.txt > /dev/null 2>&1
printf "| WGDashboard installed successfully! |\n"
- printf "| Starting Dashboard |\n"
+
+ printf "| Preparing the systemctl unit file |\n"
+ sed -i "s#{{APP_ROOT}}#${APP_ROOT}#" wg-dashboard.service
+ sed -i "s#{{VIRTUAL_ENV}}#${VIRTUAL_ENV}#" wg-dashboard.service
+ cat wg-dashboard.service | sudo SYSTEMD_EDITOR=tee systemctl edit --force --full wg-dashboard.service
+ systemctl daemon-reload
+ printf "| Consider 'systemctl enable wg-dashboard' |\n"
+ printf " and 'systemctl start wg-dashboard'\n"
+ printf " use '${0} stop' before starting with systemctl\n"
+ echo
+
+ printf "| Now starting Dashboard in background |\n"
start_wgd
}
@@ -50,6 +76,7 @@ check_wgd_status(){
}
start_wgd () {
+ _check_and_set_venv
printf "%s\n" "$dashes"
printf "| Starting WGDashboard in the background. |\n"
if [ ! -d "log" ]
@@ -67,6 +94,7 @@ stop_wgd() {
start_wgd_debug() {
printf "%s\n" "$dashes"
+ _check_and_set_venv
printf "| Starting WGDashboard in the foreground. |\n"
python3 "$app_name"
printf "%s\n" "$dashes"
@@ -84,6 +112,7 @@ update_wgd() {
git stash > /dev/null 2>&1
git pull https://github.com/donaldzou/wireguard-dashboard.git $new_ver --force > /dev/null 2>&1
printf "| Installing latest Python dependencies |\n"
+ _check_and_set_venv
python3 -m pip install -r requirements.txt > /dev/null 2>&1
printf "| Update Successfully! |\n"
start_wgd
@@ -142,4 +171,3 @@ if [ "$#" != 1 ];
help
fi
fi
-