diff options
author | Himbeer <himbeer@disroot.org> | 2024-08-19 18:23:43 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-08-19 18:23:43 +0200 |
commit | 4be9a79311189238e2448c820ad3b0cb04bb7ac7 (patch) | |
tree | 164fccf680e0128f4d84e9833e8a0927ef21a261 /src | |
parent | d14e8876bcdabf9022afd72c01594fc68004c43e (diff) |
Populate VPN server management page
Diffstat (limited to 'src')
-rw-r--r-- | src/vpn.html | 159 | ||||
-rw-r--r-- | src/vpn.js | 162 |
2 files changed, 321 insertions, 0 deletions
diff --git a/src/vpn.html b/src/vpn.html index 19bebe3..b4b11d7 100644 --- a/src/vpn.html +++ b/src/vpn.html @@ -42,6 +42,165 @@ <button id="disconnect-submit" type="submit">🚪 Abmelden</button> </form> </div> + + <br /> + + <form id="profile-form"> + <fieldset> + <legend>Clientseitige Konfiguration</legend> + + <p> + 1. WireGuard installieren: <a + href="https://www.wireguard.com/install/" + target="_blank">https://www.wireguard.com/install/</a> + + <br /> + + 2. Tunnel hinzufügen / Add a tunnel / + + + <br /> + + 3. Gerätenummer ermitteln: Beliebige Zahl zwischen 100 und 239 wählen, die nicht bereits für ein anderes Gerät verwendet wird + + <br /> + + 4. Daten selbst eingeben / Create from scratch + + <br /> + + 5. "Generate keypair" drücken und privaten Schlüssel / Private key in die Zwischenablage kopieren + + <br /> + + 6. Gerätedaten eintragen + + <br /><br /> + + - Name: wg0 (beliebig wählbar)<br /> + - Privater Schlüssel / Private key: Mit weiterer Betätigung von "Generate keypair" automatisch erzeugen lassen<br /> + - Öffentlicher Schlüssel / Public key: Wird ebenfalls von "Generate keypair" erzeugt<br /> + - Adressen / Addresses: 10.128.50.GERÄTENUMMER/32, fd0b:9272:534e:6::GERÄTENUMMER/128 (Achtung: Für Firewallausnahme stattdessen 10.128.60.GERÄTENUMMER/32, fd0b:9272:534e:7::GERÄTENUMMER/128 verwenden)<br /> + - Listen port: Keine Angabe (automatisch)<br /> + - MTU: Keine Angabe (automatisch)<br /> + - DNS-Server / DNS servers: 10.128.50.254, fd0b:9272:534e:6::1 (Achtung: Für Firewallausnahme stattdessen 10.128.60.254, fd0b:9272:534e:7::1 verwenden)<br /> + + <br /> + + 7. Gerät hinzufügen / Add peer + + <br /><br /> + + - Öffentlicher Schlüssel / Public key: <span id="profile-pubkey">Siehe Diagnoseprotokoll</span><br /> + - Symmetrischer Schlüssel / Preshared key: Aus Zwischenablage einfügen<br /> + - Endpunkt / Endpoint: rtr.himbeerserver.de:51820 (Achtung: Für Firewallausnahme stattdessen rtr.himbeerserver.de:51821 verwenden)<br /> + - Erlaubte IP-Adressen / Allowed IPs: 0.0.0.0/0, ::/0<br /> + - Private IP-Adressen ignorieren / Exclude private IPs: Nein (bei Zugriff aus dem öffentlichen Internet egal, bei Zugriff aus dem Heimnetz relevant)<br /> + - Keep-Alive / Persistent keepalive: Keine Angabe (deaktiviert), kann ggf. auf 25 gesetzt werden<br /> + + <br /> + + 8. Speichern + </p> + </fieldset> + </form> + + <form id="server-form"> + <fieldset> + <legend>Server</legend> + + <div class="row"> + <label for="server-pubkey">Öffentlicher Schlüssel / Public key:</label> + <span id="server-pubkey">Siehe Diagnoseprotokoll</span> + </div> + + <br /> + + <div class="row"> + <button id="server-restart">🔄 VPN-Server-Neustart</button> + </div> + + <p>Information: Ein Neustart des VPN-Servers dauert ca. 30 Sekunden. + Eventuell gehen dabei bestehende VPN-Verbindungen verloren. Bei + Fehlkonfiguration ist mit großer Wahrscheinlichkeit kein + VPN-Verbindungsaufbau mehr möglich.</p> + </fieldset> + </form> + + <br /> + + <form id="client-form"> + <fieldset> + <legend>Clients</legend> + + <table id="client-clients"> + <th> + <td>Öffentlicher Schlüssel / Public key</td> + <td>Symmetrischer Schlüssel / Preshared key</td> + <td>Erlaubte IP-Adressen / Allowed IPs</td> + </th> + </table> + + <div class="row"> + <output id="client-status">Warte auf Initialisierung...</output> + </div> + + <p>Information: Es ist zulässig (aber nicht sinnvoll), mehrere + Clients mit dem gleichen Namen zu erstellen. Beim Löschen werden alle + Clients mit passendem Namen entfernt, unabhängig davon, welcher + Client tatsächlich gelöscht werden sollte.</p> + </fieldset> + </form> + + <br /> + + <form id="add-form"> + <fieldset> + <legend>Client hinzufügen</legend> + + <label for="add-name" form="add-form">Name:</label> + <div class="row"> + <input id="add-name" /> + </div> + + <br /> + + <label for="add-pubkey" form="add-form">Öffentlicher Schlüssel / Public key:</label> + <div class="row"> + <input id="add-pubkey" /> + </div> + + <br /> + + <label for="add-psk" form="add-form">Symmetrischer Schlüssel / Preshared key:</label> + <div class="row"> + <input id="add-psk" type="password" /> + </div> + <br /> + <div class="row"> + <button id="add-show">🔒 Symmetrischen Schlüssel ein-/ausblenden</button> + </div> + + <br /> + + <label for="add-allowedips" form="add-form">Erlaubte IP-Adressen / Allowed IPs:</label> + <div class="row"> + <input id="add-allowedips" placeholder="z.B. 10.128.50.100/32 fd0b:9272:534e:6::100/128" /> + </div> + + <br /> + + <div class="row"> + <button id="add-submit" type="submit">Client hinzufügen</button> + </div> + + <p id="add-status"></p> + + <p>Information: Es ist zulässig (aber nicht sinnvoll), mehrere + Clients mit dem gleichen Namen zu erstellen. Beim Löschen wird der + erste Client mit passendem Namen entfernt, unabhängig davon, welcher + Client tatsächlich gelöscht werden sollte.</p> + </fieldset> + </form> </div> </body> </html> @@ -1,4 +1,166 @@ const { invoke } = window.__TAURI__.tauri; +const { ask, message } = window.__TAURI__.dialog; + +let clientTableEl; +let clientStatusEl; + +let addNameEl; +let addPubkeyEl; +let addPskEl; +let addAllowedIpsEl; +let addSubmitEl; +let addStatusEl; + +async function serverRestart() { + const error = await invoke("kill", { process: "rsdsl_wgd", signal: "term" }); + + if (error !== "") { + await message("Befehl konnte nicht erteilt werden: " + error, { + kind: "error", + title: "VPN-Server-Neustart nicht erfolgt" + }); + } +} + +async function deleteClient(name) { + const statusText = await invoke("vpndel", { name: name }); + + if (statusText === "Löschung erfolgreich") { + await loadClients(); + await message("Zum Anwenden der Änderung muss der VPN-Server manuell neu gestartet werden.", { + kind: "info", + title: "VPN-Server-Neustart erforderlich", + }); + } else { + await message("Befehl konnte nicht erteilt werden: " + statusText, { + kind: "error", + title: "Clientlöschung nicht erfolgt", + }); + } +} + +async function loadClients() { + const clients = await invoke("vpnclients", {}); + + clientStatusEl.innerText = clients.status_text; + + let first = true; + for (let child of clientTableEl.querySelectorAll("tr")) { + if (first) { + first = false; + continue; + } + + clientTableEl.removeChild(child); + child.remove(); + } + + for (let client of clients.clients) { + let name = document.createElement("td"); + name.innerText = client.name; + + let pubkey = document.createElement("td"); + pubkey.innerText = client.pubkey; + + let psk = document.createElement("td"); + psk.innerText = client.psk; + + let allowedIps = document.createElement("td"); + allowedIps.innerText = client.allowed_ips; + + let deleter = document.createElement("button"); + deleter.innerText = "🗑"; + deleter.addEventListener("click", async function(e) { + e.preventDefault(); + + const confirmed = await ask("Möchten Sie die VPN-Zugangsberechtigung für " + client.name + " wirklich entfernen?", { + kind: "warn", + title: "Entfernen bestätigen" + }); + + if (confirmed) { + await deleteClient(client.name); + } + }); + + let row = document.createElement("tr"); + row.appendChild(name); + row.appendChild(pubkey); + row.appendChild(psk); + row.appendChild(allowedIps); + row.appendChild(deleter); + + clientTableEl.appendChild(row); + } +} + +function showPsk() { + switch (addPskEl.type) { + case "password": + addPskEl.type = "text"; + break; + case "text": + addPskEl.type = "password"; + break; + } +} + +async function addClient() { + addNameEl.disabled = true; + addPubkeyEl.disabled = true; + addPskEl.disabled = true; + addAllowedIpsEl.disabled = true; + addSubmitEl.disabled = true; + addStatusEl.innerText = "Änderungsanfrage..."; + document.body.style.cursor = "progress"; + + addStatusEl.innerText = await invoke("vpnadd", { + name: addNameEl.value, + pubkey: addPubkeyEl.value, + psk: addPskEl.value, + allowedIps: addAllowedIpsEl.value, + }); + + addNameEl.disabled = false; + addPubkeyEl.disabled = false; + addPskEl.disabled = false; + addAllowedIpsEl.disabled = false; + addSubmitEl.disabled = false; + document.body.style.cursor = "default"; + + await loadClients(); + await message("Zum Anwenden der Änderung muss der VPN-Server manuell neu gestartet werden.", { + kind: "info", + title: "VPN-Server-Neustart erforderlich", + }); +} window.addEventListener("DOMContentLoaded", () => { + document.querySelector("#server-restart").addEventListener("click", (e) => { + e.preventDefault(); + serverRestart(); + }); + + clientTableEl = document.querySelector("#client-clients"); + clientStatusEl = document.querySelector("#client-status"); + + loadClients(); + + addNameEl = document.querySelector("#add-name"); + addPubkeyEl = document.querySelector("#add-pubkey"); + addPskEl = document.querySelector("#add-psk"); + addAllowedIpsEl = document.querySelector("#add-allowedips"); + addSubmitEl = document.querySelector("#add-submit"); + addStatusEl = document.querySelector("#add-status"); + + document.querySelector("#add-show").addEventListener("click", (e) => { + e.preventDefault(); + showPsk(); + }); + document.querySelector("#add-form").addEventListener("submit", (e) => { + e.preventDefault(); + addClient(); + }); }); + +setInterval(loadClients, 10000); |