Merge pull request #742 from mvajid/add-ssltls

Added SSL/TLS natively.
This commit is contained in:
Donald Zou 2025-05-13 20:37:11 +08:00 committed by GitHub
commit 02f7eb0c82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 38 deletions

View File

@ -25,7 +25,7 @@ from modules.PeerJob import PeerJob
from modules.SystemStatus import SystemStatus from modules.SystemStatus import SystemStatus
SystemStatus = SystemStatus() SystemStatus = SystemStatus()
DASHBOARD_VERSION = 'v4.2.3' DASHBOARD_VERSION = 'v4.2.2'
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')
@ -432,6 +432,7 @@ class WireguardConfiguration:
original = [l.rstrip("\n") for l in f.readlines()] original = [l.rstrip("\n") for l in f.readlines()]
try: try:
start = original.index("[Interface]") start = original.index("[Interface]")
# Clean # Clean
for i in range(start, len(original)): for i in range(start, len(original)):
if original[i] == "[Peer]": if original[i] == "[Peer]":
@ -444,7 +445,7 @@ class WireguardConfiguration:
setattr(self, key, False) setattr(self, key, False)
else: else:
setattr(self, key, "") setattr(self, key, "")
# Set # Set
for i in range(start, len(original)): for i in range(start, len(original)):
if original[i] == "[Peer]": if original[i] == "[Peer]":
@ -458,10 +459,7 @@ class WireguardConfiguration:
setattr(self, key, StringToBoolean(value)) setattr(self, key, StringToBoolean(value))
else: else:
if len(getattr(self, key)) > 0: if len(getattr(self, key)) > 0:
if key not in ["PostUp", "PostDown", "PreUp", "PreDown"]: setattr(self, key, f"{getattr(self, key)}, {value}")
setattr(self, key, f"{getattr(self, key)}, {value}")
else:
setattr(self, key, f"{getattr(self, key)}; {value}")
else: else:
setattr(self, key, value) setattr(self, key, value)
except ValueError as e: except ValueError as e:
@ -472,12 +470,11 @@ class WireguardConfiguration:
self.Status = self.getStatus() self.Status = self.getStatus()
def __dropDatabase(self): def __dropDatabase(self):
existingTables = [self.Name, f'{self.Name}_restrict_access', f'{self.Name}_transfer', f'{self.Name}_deleted'] existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
# existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
for t in existingTables: for t in existingTables:
sqlUpdate("DROP TABLE '%s'" % t) sqlUpdate("DROP TABLE '%s'" % t['name'])
# existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall() existingTables = sqlSelect(f"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '{self.Name}%'").fetchall()
def createDatabase(self, dbName = None): def createDatabase(self, dbName = None):
if dbName is None: if dbName is None:
@ -807,9 +804,6 @@ class WireguardConfiguration:
return ResponseObject(False, "Failed to save configuration through WireGuard") return ResponseObject(False, "Failed to save configuration through WireGuard")
self.getPeers() self.getPeers()
if numOfDeletedPeers == 0 and numOfFailedToDeletePeers == 0:
return ResponseObject(False, "No peer(s) to delete found", responseCode=404)
if numOfDeletedPeers == len(listOfPublicKeys): if numOfDeletedPeers == len(listOfPublicKeys):
return ResponseObject(True, f"Deleted {numOfDeletedPeers} peer(s)") return ResponseObject(True, f"Deleted {numOfDeletedPeers} peer(s)")
@ -951,8 +945,7 @@ class WireguardConfiguration:
}, },
"ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))), "ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))),
"TotalPeers": len(self.Peers), "TotalPeers": len(self.Peers),
"Protocol": self.Protocol, "Protocol": self.Protocol
"Table": self.Table,
} }
def backupConfigurationFile(self) -> tuple[bool, dict[str, str]]: def backupConfigurationFile(self) -> tuple[bool, dict[str, str]]:
@ -1054,7 +1047,7 @@ class WireguardConfiguration:
dataChanged = False dataChanged = False
with open(self.configPath, 'r') as f: with open(self.configPath, 'r') as f:
original = [l.rstrip("\n") for l in f.readlines()] original = [l.rstrip("\n") for l in f.readlines()]
allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort", "Table"] allowEdit = ["Address", "PreUp", "PostUp", "PreDown", "PostDown", "ListenPort"]
if self.Protocol == 'awg': if self.Protocol == 'awg':
allowEdit += ["Jc", "Jmin", "Jmax", "S1", "S2", "H1", "H2", "H3", "H4"] allowEdit += ["Jc", "Jmin", "Jmax", "S1", "S2", "H1", "H2", "H3", "H4"]
start = original.index("[Interface]") start = original.index("[Interface]")
@ -1211,15 +1204,15 @@ AmneziaWG Configuration
""" """
class AmneziaWireguardConfiguration(WireguardConfiguration): class AmneziaWireguardConfiguration(WireguardConfiguration):
def __init__(self, name: str = None, data: dict = None, backup: dict = None, startup: bool = False): def __init__(self, name: str = None, data: dict = None, backup: dict = None, startup: bool = False):
self.Jc = "" self.Jc = 0
self.Jmin = "" self.Jmin = 0
self.Jmax = "" self.Jmax = 0
self.S1 = "" self.S1 = 0
self.S2 = "" self.S2 = 0
self.H1 = "" self.H1 = 1
self.H2 = "" self.H2 = 2
self.H3 = "" self.H3 = 3
self.H4 = "" self.H4 = 4
super().__init__(name, data, backup, startup, wg=False) super().__init__(name, data, backup, startup, wg=False)
@ -1244,7 +1237,6 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
}, },
"ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))), "ConnectedPeers": len(list(filter(lambda x: x.status == "running", self.Peers))),
"TotalPeers": len(self.Peers), "TotalPeers": len(self.Peers),
"Table": self.Table,
"Protocol": self.Protocol, "Protocol": self.Protocol,
"Jc": self.Jc, "Jc": self.Jc,
"Jmin": self.Jmin, "Jmin": self.Jmin,
@ -1442,7 +1434,7 @@ class AmneziaWireguardConfiguration(WireguardConfiguration):
f.write(p['preshared_key']) f.write(p['preshared_key'])
subprocess.check_output( subprocess.check_output(
f"{self.Protocol} set {self.Name} peer {p['id']} allowed-ips {p['allowed_ip'].replace(' ', '')}{f' preshared-key {uid}' if presharedKeyExist else ''}", f"{self.Protocol} set {self.Name} peer {p['id']} allowed-ips {p['allowed_ip'].replace(' ', '')}{f' preshared-key {uid}' if presharedKeyExist else ''} advanced-security {p['advanced_security']}",
shell=True, stderr=subprocess.STDOUT) shell=True, stderr=subprocess.STDOUT)
if presharedKeyExist: if presharedKeyExist:
os.remove(uid) os.remove(uid)
@ -1721,7 +1713,7 @@ PersistentKeepalive = {str(self.keepalive)}
f.write(preshared_key) f.write(preshared_key)
newAllowedIPs = allowed_ip.replace(" ", "") newAllowedIPs = allowed_ip.replace(" ", "")
updateAllowedIp = subprocess.check_output( updateAllowedIp = subprocess.check_output(
f"{self.configuration.Protocol} set {self.configuration.Name} peer {self.id} allowed-ips {newAllowedIPs} {f'preshared-key {uid}' if pskExist else 'preshared-key /dev/null'}", f"{self.configuration.Protocol} set {self.configuration.Name} peer {self.id} allowed-ips {newAllowedIPs} {f'preshared-key {uid}' if pskExist else 'preshared-key /dev/null'} advanced-security {advanced_security}",
shell=True, stderr=subprocess.STDOUT) shell=True, stderr=subprocess.STDOUT)
if pskExist: os.remove(uid) if pskExist: os.remove(uid)
@ -2442,7 +2434,7 @@ def API_updatePeerSettings(configName):
allowed_ip, endpoint_allowed_ip, mtu, keepalive) allowed_ip, endpoint_allowed_ip, mtu, keepalive)
return peer.updatePeer(name, private_key, preshared_key, dns_addresses, return peer.updatePeer(name, private_key, preshared_key, dns_addresses,
allowed_ip, endpoint_allowed_ip, mtu, keepalive, "off") allowed_ip, endpoint_allowed_ip, mtu, keepalive, data.get('advanced_security', 'off'))
return ResponseObject(False, "Peer does not exist") return ResponseObject(False, "Peer does not exist")
@ -2471,11 +2463,11 @@ def API_deletePeers(configName: str) -> ResponseObject:
peers = data['peers'] peers = data['peers']
if configName in WireguardConfigurations.keys(): if configName in WireguardConfigurations.keys():
if len(peers) == 0: if len(peers) == 0:
return ResponseObject(False, "Please specify one or more peers", status_code=400) return ResponseObject(False, "Please specify one or more peers")
configuration = WireguardConfigurations.get(configName) configuration = WireguardConfigurations.get(configName)
return configuration.deletePeers(peers) return configuration.deletePeers(peers)
return ResponseObject(False, "Configuration does not exist", status_code=404) return ResponseObject(False, "Configuration does not exist")
@app.post(f'{APP_PREFIX}/api/restrictPeers/<configName>') @app.post(f'{APP_PREFIX}/api/restrictPeers/<configName>')
def API_restrictPeers(configName: str) -> ResponseObject: def API_restrictPeers(configName: str) -> ResponseObject:
@ -2612,7 +2604,7 @@ def API_addPeers(configName):
"endpoint_allowed_ip": endpoint_allowed_ip, "endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": mtu, "mtu": mtu,
"keepalive": keep_alive, "keepalive": keep_alive,
"advanced_security": "off" "advanced_security": data.get("advanced_security", "off")
}) })
if addedCount == bulkAddAmount: if addedCount == bulkAddAmount:
break break
@ -2682,7 +2674,7 @@ def API_addPeers(configName):
"DNS": dns_addresses, "DNS": dns_addresses,
"mtu": mtu, "mtu": mtu,
"keepalive": keep_alive, "keepalive": keep_alive,
"advanced_security": "off" "advanced_security": data.get("advanced_security", "off")
}] }]
) )
return ResponseObject(status=status, message=result['message'], data=result['peers']) return ResponseObject(status=status, message=result['message'], data=result['peers'])
@ -2960,7 +2952,7 @@ def API_isTotpEnabled():
@app.get(f'{APP_PREFIX}/api/Welcome_GetTotpLink') @app.get(f'{APP_PREFIX}/api/Welcome_GetTotpLink')
def API_Welcome_GetTotpLink(): def API_Welcome_GetTotpLink():
if not DashboardConfig.GetConfig("Account", "totp_verified")[1]: if not DashboardConfig.GetConfig("Account", "totp_verified")[1]:
DashboardConfig.SetConfig("Account", "totp_key", pyotp.random_base32(), True) DashboardConfig.SetConfig("Account", "totp_key", pyotp.random_base32())
return ResponseObject( return ResponseObject(
data=pyotp.totp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).provisioning_uri( data=pyotp.totp.TOTP(DashboardConfig.GetConfig("Account", "totp_key")[1]).provisioning_uri(
issuer_name="WGDashboard")) issuer_name="WGDashboard"))
@ -3137,7 +3129,9 @@ def peerJobScheduleBackgroundThread():
def gunicornConfig(): def gunicornConfig():
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip") _, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
_, app_port = DashboardConfig.GetConfig("Server", "app_port") _, app_port = DashboardConfig.GetConfig("Server", "app_port")
return app_ip, app_port _, certfile = DashboardConfig.GetConfig("Server", "certfile")
_, keyfile = DashboardConfig.GetConfig("Server", "keyfile")
return app_ip, app_port, certfile, keyfile
def ProtocolsEnabled() -> list[str]: def ProtocolsEnabled() -> list[str]:
from shutil import which from shutil import which

View File

@ -2,17 +2,19 @@ import os.path
import dashboard, configparser import dashboard, configparser
from datetime import datetime from datetime import datetime
global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger global sqldb, cursor, DashboardConfig, WireguardConfigurations, AllPeerJobs, JobLogger
app_host, app_port = dashboard.gunicornConfig() app_host, app_port, certfile, keyfile = dashboard.gunicornConfig()
date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S') date = datetime.today().strftime('%Y_%m_%d_%H_%M_%S')
def post_worker_init(worker): def post_worker_init(worker):
dashboard.startThreads() dashboard.startThreads()
worker_class = 'gthread' worker_class = 'gthread'
workers = 1 workers = 4
threads = 1 threads = 4
bind = f"{app_host}:{app_port}" bind = f"{app_host}:{app_port}"
daemon = True daemon = True
certfile = f"{certfile}"
keyfile = f"{keyfile}"
pidfile = './gunicorn.pid' pidfile = './gunicorn.pid'
wsgi_app = "dashboard:app" wsgi_app = "dashboard:app"
accesslog = f"./log/access_{date}.log" accesslog = f"./log/access_{date}.log"