1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-10-01 09:00:13 +02:00

Merge branch 'main' into change-path

This commit is contained in:
Galonza Peter 2021-12-25 23:17:40 +03:00
commit d06dddfa24
7 changed files with 108 additions and 31 deletions

View File

@ -41,10 +41,19 @@
"contributions": [ "contributions": [
"code" "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, "contributorsPerLine": 7,
"projectName": "wireguard-dashboard", "projectName": "WGDashboard",
"projectOwner": "donaldzou", "projectOwner": "donaldzou",
"repoType": "github", "repoType": "github",
"repoHost": "https://github.com", "repoHost": "https://github.com",

5
.gitignore vendored
View File

@ -11,4 +11,7 @@ src/wg-dashboard.ini
src/static/pic.xd src/static/pic.xd
*.conf *.conf
private_key.txt private_key.txt
public_key.txt public_key.txt
venv/**
log/**
*~

View File

@ -1,8 +1,14 @@
<hr> <hr>
<p align=center>Please provide your OS name and version if you can run the dashboard on it perfectly in <a href="https://github.com/donaldzou/wireguard-dashboard/issues/31">#31</a>, since I only tested on Ubuntu. Thank you!</p>
<hr>
> 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 <a href="https://github.com/donaldzou/wireguard-dashboard/issues/103">#103</a>!
> Please provide your OS name and version if you can run the dashboard on it perfectly in <a href="https://github.com/donaldzou/wireguard-dashboard/issues/31">#31</a>, since I only tested on Ubuntu. Thank you!
<hr>
<p align="center"> <p align="center">
<img alt="WGDashboard" src="img/logo.png" width="128"> <img alt="WGDashboard" src="img/logo.png" width="128">
</p> </p>
@ -13,6 +19,7 @@
</p> </p>
<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>
</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>
@ -426,7 +433,7 @@ Bug Fixed:
## ✨ Contributors ## ✨ Contributors
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![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-)
<!-- ALL-CONTRIBUTORS-BADGE:END --> <!-- ALL-CONTRIBUTORS-BADGE:END -->
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 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
<!-- markdownlint-disable --> <!-- markdownlint-disable -->
<table> <table>
<tr> <tr>
<td align="center"><a href="https://github.com/antonioag95"><img src="https://avatars.githubusercontent.com/u/30556866?v=4?s=100" width="100px;" alt=""/><br /><sub><b>antonioag95</b></sub></a><br /><a href="https://github.com/donaldzou/wireguard-dashboard/commits?author=antonioag95" title="Tests">⚠️</a> <a href="https://github.com/donaldzou/wireguard-dashboard/commits?author=antonioag95" title="Code">💻</a></td> <td align="center"><a href="https://github.com/antonioag95"><img src="https://avatars.githubusercontent.com/u/30556866?v=4?s=100" width="100px;" alt=""/><br /><sub><b>antonioag95</b></sub></a><br /><a href="https://github.com/donaldzou/WGDashboard/commits?author=antonioag95" title="Tests">⚠️</a> <a href="https://github.com/donaldzou/WGDashboard/commits?author=antonioag95" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/tonjo"><img src="https://avatars.githubusercontent.com/u/4726289?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tonjo</b></sub></a><br /><a href="https://github.com/donaldzou/wireguard-dashboard/commits?author=tonjo" title="Code">💻</a></td> <td align="center"><a href="https://github.com/tonjo"><img src="https://avatars.githubusercontent.com/u/4726289?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tonjo</b></sub></a><br /><a href="https://github.com/donaldzou/WGDashboard/commits?author=tonjo" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/reafian"><img src="https://avatars.githubusercontent.com/u/11992416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Richard Newton</b></sub></a><br /><a href="https://github.com/donaldzou/wireguard-dashboard/commits?author=reafian" title="Code">💻</a></td> <td align="center"><a href="https://github.com/reafian"><img src="https://avatars.githubusercontent.com/u/11992416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Richard Newton</b></sub></a><br /><a href="https://github.com/donaldzou/WGDashboard/commits?author=reafian" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/davejlong"><img src="https://avatars.githubusercontent.com/u/175317?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Long</b></sub></a><br /><a href="https://github.com/donaldzou/wireguard-dashboard/commits?author=davejlong" title="Code">💻</a></td> <td align="center"><a href="http://www.davejlong.com"><img src="https://avatars.githubusercontent.com/u/175317?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Long</b></sub></a><br /><a href="https://github.com/donaldzou/WGDashboard/commits?author=davejlong" title="Code">💻</a></td>
<td align="center"><a href="http://www.std-soft.com"><img src="https://avatars.githubusercontent.com/u/5978293?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Markus Neubauer</b></sub></a><br /><a href="https://github.com/donaldzou/WGDashboard/commits?author=marneu" title="Code">💻</a></td>
</tr> </tr>
</table> </table>

View File

@ -23,7 +23,7 @@ from flask_qrcode import QRcode
from tinydb import TinyDB, Query from tinydb import TinyDB, Query
from icmplib import ping, multiping, traceroute, resolve, Host, Hop from icmplib import ping, multiping, traceroute, resolve, Host, Hop
# Dashboard Version # Dashboard Version
dashboard_version = 'v2.3.1' dashboard_version = 'v3.0'
# 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')
@ -47,10 +47,22 @@ def regex_match(regex, text):
pattern = re.compile(regex) pattern = re.compile(regex)
return pattern.search(text) is not None return pattern.search(text) is not None
# Check IP format (IPv4 only now) # Check IP format
# TODO: Add IPv6 support
def check_IP(ip): 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 # Clean IP
def clean_IP(ip): def clean_IP(ip):
@ -60,11 +72,22 @@ def clean_IP(ip):
def clean_IP_with_range(ip): def clean_IP_with_range(ip):
return clean_IP(ip).split(',') return clean_IP(ip).split(',')
# Check IP with range (IPv4 only now) # Check IP with range
# TODO: Add IPv6 support
def check_IP_with_range(ip): 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|" + ip_patterns = (
"18|19|20|21|22|23|24|25|26|27|28|29|30|31|32)(,|$)", ip) 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 # Check allowed ips list
def check_Allowed_IPs(ip): def check_Allowed_IPs(ip):
@ -78,14 +101,14 @@ def check_DNS(dns):
dns = dns.replace(' ','').split(',') dns = dns.replace(' ','').split(',')
status = True status = True
for i in dns: 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 False
return True return True
# Check remote endpoint (Both IPv4 address and valid hostname) # Check remote endpoint
# TODO: Add IPv6 support
def check_remote_endpoint(address): 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'] private_key = peer['private_key']
allowed_ip = peer['allowed_ip'] allowed_ip = peer['allowed_ip']
DNS = peer['DNS'] DNS = peer['DNS']
MTU = peer['mtu']
endpoint_allowed_ip = peer['endpoint_allowed_ip'] endpoint_allowed_ip = peer['endpoint_allowed_ip']
keepalive = peer['keepalive']
filename = peer['name'] filename = peer['name']
if len(filename) == 0: if len(filename) == 0:
filename = "Untitled_Peers" filename = "Untitled_Peers"
@ -1016,10 +1041,10 @@ def download(config_name):
filename = "".join(filename.split(' ')) filename = "".join(filename.split(' '))
filename = filename + "_" + config_name filename = filename + "_" + config_name
def generate(private_key, allowed_ip, DNS, public_key, endpoint): def generate(private_key, allowed_ip, DNS, MTU, public_key, endpoint, keepalive):
yield "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + DNS + "\n\n[Peer]\nPublicKey = " + public_key + "\nAllowedIPs = "+endpoint_allowed_ip+"\nEndpoint = " + endpoint 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', mimetype='text/conf',
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"}) headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
else: else:
@ -1120,6 +1145,7 @@ def init_dashboard():
config['Server'] = {} config['Server'] = {}
if 'wg_conf_path' not in config['Server']: if 'wg_conf_path' not in config['Server']:
config['Server']['wg_conf_path'] = '/etc/wireguard' 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']: if 'app_ip' not in config['Server']:
config['Server']['app_ip'] = '0.0.0.0' config['Server']['app_ip'] = '0.0.0.0'
if 'app_port' not in config['Server']: if 'app_port' not in config['Server']:

View File

@ -182,7 +182,7 @@
<button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-x-circle-fill"></i></button> <button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="{{i['id']}}" data-toggle="modal"><i class="bi bi-x-circle-fill"></i></button>
{% if i['private_key'] %} {% if i['private_key'] %}
<div class="share_peer_btn_group" style="margin-left: auto !important; display: inline"> <div class="share_peer_btn_group" style="margin-left: auto !important; display: inline">
<button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="{{ qrcode("[Interface]\nPrivateKey = "+i['private_key']+"\nAddress = "+i['allowed_ip']+"\nDNS = "+i['DNS']+"\n\n[Peer]\nPublicKey = "+conf_data['public_key']+"\nAllowedIPs = "+i['endpoint_allowed_ip']+"\nEndpoint = "+wg_ip+":"+conf_data['listen_port']) }}"> <button type="button" class="btn btn-outline-success btn-qrcode-peer btn-control" img_src="{{ qrcode("[Interface]\nPrivateKey = "+i['private_key']+"\nAddress = "+i['allowed_ip']+"\nMTU = "+i['mtu']+"\nDNS = "+i['DNS']+"\n\n[Peer]\nPublicKey = "+conf_data['public_key']+"\nAllowedIPs = "+i['endpoint_allowed_ip']+"\nPersistentKeepalive = "+i['keepalive']+"\nEndpoint = "+wg_ip+":"+conf_data['listen_port']) }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="width: 19px;" fill="#28a745"><path d="M3 11h8V3H3v8zm2-6h4v4H5V5zM3 21h8v-8H3v8zm2-6h4v4H5v-4zM13 3v8h8V3h-8zm6 6h-4V5h4v4zM13 13h2v2h-2zM15 15h2v2h-2zM13 17h2v2h-2zM17 17h2v2h-2zM19 19h2v2h-2zM15 19h2v2h-2zM17 13h2v2h-2zM19 15h2v2h-2z"/></svg>
</button> </button>
<a href="/download/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}" class="btn btn-outline-info btn-download-peer btn-control"> <a href="/download/{{ conf_data['name'] }}?id={{ i['id']|urlencode }}" class="btn btn-outline-info btn-download-peer btn-control">

View File

@ -1,11 +1,14 @@
[Unit] [Unit]
After=netword.service After=syslog.target network-online.target
ConditionPathIsDirectory=/etc/wireguard
[Service] [Service]
WorkingDirectory=<your dashboard directory full path here> Environment="VIRTUAL_ENV={{VIRTUAL_ENV}}"
ExecStart=/usr/bin/python3 <your dashboard directory full path here>dashboard.py WorkingDirectory={{APP_ROOT}}
ExecStart={{VIRTUAL_ENV}}/bin/python3 {{APP_ROOT}}/dashboard.py
PrivateTmp=yes
Restart=always Restart=always
[Install] [Install]
WantedBy=default.target WantedBy=multi-user.target

View File

@ -20,6 +20,17 @@ help () {
printf "=================================================================================\n" 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(){ install_wgd(){
# Check Python3 version # 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");') 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" then mkdir "log"
fi fi
printf "| Installing latest Python dependencies |\n" 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 python3 -m pip install -r requirements.txt > /dev/null 2>&1
printf "| WGDashboard installed successfully! |\n" 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 start_wgd
} }
@ -50,6 +76,7 @@ check_wgd_status(){
} }
start_wgd () { start_wgd () {
_check_and_set_venv
printf "%s\n" "$dashes" printf "%s\n" "$dashes"
printf "| Starting WGDashboard in the background. |\n" printf "| Starting WGDashboard in the background. |\n"
if [ ! -d "log" ] if [ ! -d "log" ]
@ -67,6 +94,7 @@ stop_wgd() {
start_wgd_debug() { start_wgd_debug() {
printf "%s\n" "$dashes" printf "%s\n" "$dashes"
_check_and_set_venv
printf "| Starting WGDashboard in the foreground. |\n" printf "| Starting WGDashboard in the foreground. |\n"
python3 "$app_name" python3 "$app_name"
printf "%s\n" "$dashes" printf "%s\n" "$dashes"
@ -84,6 +112,7 @@ update_wgd() {
git stash > /dev/null 2>&1 git stash > /dev/null 2>&1
git pull https://github.com/donaldzou/wireguard-dashboard.git $new_ver --force > /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" printf "| Installing latest Python dependencies |\n"
_check_and_set_venv
python3 -m pip install -r requirements.txt > /dev/null 2>&1 python3 -m pip install -r requirements.txt > /dev/null 2>&1
printf "| Update Successfully! |\n" printf "| Update Successfully! |\n"
start_wgd start_wgd
@ -142,4 +171,3 @@ if [ "$#" != 1 ];
help help
fi fi
fi fi