Skip to content
wavemesh

wave-mesh

Changelog

Changes to wave-mesh, loaded from the product repository. The changelog is currently written in German.

View the changelog on GitHub

Selbst hostbares Mesh-VPN auf WireGuard-Basis.


🔼 In Entwicklung (Ausblick auf nĂ€chstes Release)

Noch nichts seit v0.11.0.


✅ Stable v0.11.0 (22.10.2026)

EnthÀlt alles aus v0.11.0-develop.1 bis v0.11.0-develop.3.

Neue Funktionen (gegenĂŒber v0.10.0)

  • Admins und EigentĂŒmer Ă€ndern Rollen in der Mitgliederliste: Bei jedem Mitglied, dessen Rolle man Ă€ndern darf, steht jetzt eine Auswahl „Mitglied“/„Administrator“ mit „Speichern“. Der EigentĂŒmer stellt jedes andere Mitglied um, ein Administrator befördert Mitglieder zu Administratoren; einen anderen Administrator herabstufen darf nur der EigentĂŒmer. Die Rolle des EigentĂŒmers und die eigene Rolle bleiben unverĂ€ndert. Die neue Rolle gilt sofort auch fĂŒr Regeln mit role: in der Zugriffsrichtlinie, und die Änderung steht im Audit-Log (member.role). (seit develop.3)

Fehlerbehebungen (gegenĂŒber v0.10.0)

  • Der Client bricht beim Verbinden nicht mehr ab, wenn der Control-Server nicht erreichbar ist: Ist der Server beim Start oder bei wave login/ wave up nicht erreichbar (Verbindung verweigert, ZeitĂŒberschreitung, Netz nicht da, Server startet gerade neu) oder meldet das Betriebssystem beim Auflösen des Servernamens getaddrinfo ETIMEOUT, versucht der Client es mit wachsenden Pausen (0,5 bis 30 Sekunden) so lange erneut, bis die Verbindung steht oder du abbrichst. Das gilt fĂŒr wave up, wave login und den Dienst sowie fĂŒr die iOS- und die Android-App. Im Terminal steht dabei, warum und wann der nĂ€chste Versuch kommt; der Dienst zeigt „wartet auf den Control-Server“ statt „fehlgeschlagen“, und wave down beendet das Warten. Eine falsche Adresse, eine Ablehnung des Servers, Zertifikatsfehler und bei einem eben eingegebenen Login ein unbekannter Servername werden weiter sofort gemeldet. In den Apps gibt es das Abbrechen jetzt auch, solange noch verbunden wird. (seit develop.1, DNS-Timeout seit develop.2)

🔬 Development v0.11.0-develop.3 (22.10.2026)

Neue Funktionen

  • Admins und EigentĂŒmer Ă€ndern Rollen in der Mitgliederliste: Bei jedem Mitglied, dessen Rolle man Ă€ndern darf, steht jetzt eine Auswahl „Mitglied“/„Administrator“ mit „Speichern“. Der EigentĂŒmer stellt jedes andere Mitglied um, ein Administrator befördert Mitglieder zu Administratoren; einen anderen Administrator herabstufen darf nur der EigentĂŒmer. Die Rolle des EigentĂŒmers und die eigene Rolle bleiben unverĂ€ndert. Die neue Rolle gilt sofort auch fĂŒr Regeln mit role: in der Zugriffsrichtlinie, und die Änderung steht im Audit-Log (member.role).

🔬 Development v0.11.0-develop.2 (20.10.2026)

Fehlerbehebungen

  • Ein DNS-Timeout beim Verbinden bricht den Client nicht mehr ab: Meldet das Betriebssystem beim Auflösen des Servernamens getaddrinfo ETIMEOUT (oder antwortet der Namensserver nicht, lehnt ab oder fĂ€llt aus), wartet der Client jetzt mit wachsenden Pausen und versucht es erneut, bis die Verbindung steht. Das gilt auch fĂŒr ein GerĂ€t, das sich noch nie angemeldet hat, und fĂŒr den Linux-Dienst beim Start, der auf „wartet auf den Control-Server“ bleibt, statt „fehlgeschlagen“ zu zeigen. Ein unbekannter Servername bei einer eben eingegebenen Adresse und Zertifikatsfehler werden weiter sofort gemeldet. Die iOS- und die Android-App verhalten sich bei einem DNS-Timeout genauso.

🔬 Development v0.11.0-develop.1 (20.10.2026)

Fehlerbehebungen

  • Beim ersten Verbinden wartet der Client auf den Control-Server, statt abzubrechen: Ist der Server beim Start oder bei wave login/wave up nicht erreichbar (Verbindung verweigert, ZeitĂŒberschreitung, Netz nicht da, Server startet gerade neu), versucht der Client es mit wachsenden Pausen (0,5 bis 30 Sekunden) so lange erneut, bis die Verbindung steht oder du abbrichst. Das gilt fĂŒr wave up, wave login und den Dienst sowie fĂŒr die iOS- und die Android-App. Im Terminal steht dabei, warum und wann der nĂ€chste Versuch kommt; der Dienst zeigt „wartet auf den Control-Server“ statt „fehlgeschlagen“, und wave down beendet das Warten. Eine falsche Adresse, eine Ablehnung des Servers und Zertifikatsfehler werden weiter sofort gemeldet. Bei einem Login, den du gerade eingegeben hast, gilt ein unbekannter Servername ebenfalls weiter sofort als Fehler. In den Apps gibt es das Abbrechen jetzt auch, solange noch verbunden wird.

✅ Stable v0.10.0 (13.10.2026)

EnthÀlt alles aus v0.10.0-develop.1.

Neue Funktionen (gegenĂŒber v0.9.0)

  • Waves verkaufen, Teil Control-Server: Eine Verwaltungs-API unter /api/billing/*, ĂŒber die wave-mesh.org nach einer Zahlung mit Stripe einen Wave anlegt, ihn bei ausbleibender Zahlung pausiert und nach einer KĂŒndigung nach einer Frist löscht. Ein pausierter Wave behĂ€lt alle Daten, nur sehen sich seine GerĂ€te nicht mehr. Ein bezahlter Wave nimmt höchstens so viele Personen auf, wie gebucht sind. Der neue EigentĂŒmer legt sein Passwort ĂŒber einen Link fest, den die Seite ihm schickt. Ohne WAVE_BILLING_TOKEN gibt es nichts davon; selbst betriebene Server Ă€ndern sich nicht.
    • Ein bezahlter Wave gehört nur einem bestĂ€tigten Konto oder einem Platzhalter, nie einem unbestĂ€tigten Konto mit fremder Anmeldung. Meldet sich der EigentĂŒmer mit Google an, bevor er den Link nutzt, ĂŒbernimmt diese Anmeldung den Platzhalter, statt ein zweites Konto ohne Wave anzulegen.
    • Ein gekĂŒndigter Wave bleibt gekĂŒndigt, auch wenn ein veraltetes Ereignis spĂ€ter „aktiv“ meldet, und ein gebuchter Wave lĂ€sst sich nicht von Hand löschen, solange sein Abo lĂ€uft.
    • Ein pausierter Wave sagt auf seiner Karte, warum die GerĂ€te niemanden sehen, und bekommt keine Zertifikate, auch keines, das vor der Pause bestellt war. Ein beendetes Abo nennt das Datum der Löschung.
    • Hat sich der EigentĂŒmer schon mit Google angemeldet, bevor er den Link aus der Mail nutzt, zieht der bezahlte Wave in dieses Konto um, statt dass der Link verfĂ€llt. (neu in diesem Release)

Fehlerbehebungen (gegenĂŒber v0.9.0)

  • Ein Telefon auf Mobilfunk weckt seinen Wave nicht mehr bei jedem Aufwachen. Hinter dem NAT des Mobilfunkanbieters bekam es nach jedem Schlaf einen neuen Port und veröffentlichte ihn sofort — jedes Mal eine neue Netzkarte fĂŒr alle GerĂ€te im Wave, 73-mal in 18 Stunden. Ein neuer Port geht jetzt erst hinaus, wenn er sich ĂŒber eine halbe Minute hĂ€lt. Gilt fĂŒr die Apps, den Desktop-Client und den Connector. (seit develop.1)
  • Der Control-Server trennt schlafende Telefone nicht mehr jede Minute (Deployment deployment/server/overlays/prod): der Proxy davor lĂ€sst eine stille Verbindung jetzt eine Stunde offen statt 60 Sekunden. Wer einen eigenen nginx-Ingress vor /v1/control betreibt, setzt proxy-read-timeout und proxy-send-timeout ebenso. (seit develop.1)

🔬 Development v0.10.0-develop.1 (13.10.2026)

Fehlerbehebungen

  • Ein Telefon auf Mobilfunk weckt seinen Wave nicht mehr bei jedem Aufwachen. Hinter dem NAT des Mobilfunkanbieters bekam es nach jedem Schlaf einen neuen Port und veröffentlichte ihn sofort — jedes Mal eine neue Netzkarte fĂŒr alle GerĂ€te im Wave, 73-mal in 18 Stunden. Ein neuer Port geht jetzt erst hinaus, wenn er sich ĂŒber eine halbe Minute hĂ€lt. Gilt fĂŒr die Apps, den Desktop-Client und den Connector.
  • Der Control-Server trennt schlafende Telefone nicht mehr jede Minute (Deployment deployment/server/overlays/prod): der Proxy davor lĂ€sst eine stille Verbindung jetzt eine Stunde offen statt 60 Sekunden. Wer einen eigenen nginx-Ingress vor /v1/control betreibt, setzt proxy-read-timeout und proxy-send-timeout ebenso.

✅ Stable v0.9.0 (11.10.2026)

EnthÀlt alles aus v0.9.0-develop.1 bis v0.9.0-develop.3.

Neue Funktionen (gegenĂŒber v0.8.0)

  • Die Android-App sieht aus und verhĂ€lt sich wie die iPhone-App: dieselben Abschnitte und Texte, Anmelden ohne vorheriges Verbinden, Freigabe im Browser, Waves pausieren, prĂŒfen und verlassen, Protokoll teilen, Beitritt per QR-Code und „Automatisch verbinden“ nach einem Neustart. (seit develop.3)
  • Aus dem Cluster in den Wave: der Connector beantwortet die Namen selbst. Ein Dienst, der im Wave dazukommt, ist nach Sekunden auflösbar; der Eintrag in CoreDNS muss nie mehr angefasst werden. Wer die Egress-Komponente schon nutzt, stellt ihn einmal um (siehe coredns.example.yaml). (seit develop.1)

Fehlerbehebungen (gegenĂŒber v0.8.0)

  • Die iPhone-App hĂ€lt das Telefon nicht mehr stĂ€ndig wach — es wachte Tag und Nacht alle fĂŒnf bis sechs Sekunden auf, jetzt etwa zehnmal seltener. (seit develop.2)
  • Ein Connector im Cluster schiebt dem Wave nicht mehr jede Minute eine neue Netzkarte zu, die jedes Telefon weckte. (seit develop.2)
  • Die Android-App stĂŒrzte nach der Freigabe nicht mehr ab, behĂ€lt nach dem Verlassen des letzten Waves ihre Namensauflösung, steht nach dem Verbinden nicht mehr eine halbe Minute still und zeigt Fehler beim Anmelden an. (seit develop.3)
  • Der Update-Dialog unter macOS zeigt Umlaute richtig — statt „verf√Âșgbar“ steht dort wieder „verfĂŒgbar“. (neu in diesem Release)
  • Neue Karten im Zugriffsgraphen landen an einem freien Platz statt unter einer bestehenden. (seit develop.1)

🔬 Development v0.9.0-develop.3 (11.10.2026)

Neue Funktionen

  • Die Android-App sieht aus und verhĂ€lt sich wie die iPhone-App. Dieselben Abschnitte und Texte, auf Deutsch und Englisch, hell und dunkel. Anmelden startet den Tunnel von selbst, die Freigabeseite öffnet sich im Browser und verschwindet nach der Freigabe wieder. Jeder Wave lĂ€sst sich pausieren, prĂŒfen („Verbindung prĂŒfen“) und mit RĂŒckfrage verlassen; Dienste öffnen sich mit einem Tippen, Namen und Adressen lassen sich kopieren. Dazu ein eigener GerĂ€tename, ein teilbares Protokoll, Beitritt per QR-Code und „Automatisch verbinden“, das den Tunnel nach einem Neustart zurĂŒckbringt.

Fehlerbehebungen

  • Die Android-App stĂŒrzte direkt nach der Freigabe ab, sobald sie die erste Netzkarte ĂŒbernahm.
  • Nach dem Verlassen des letzten Waves löste das Android-Telefon keine Namen mehr auf.
  • Nach jedem Verbinden stand der Tunnel unter Android eine halbe Minute, weil er beim Start den Port wechselte.
  • Fehler beim Anmelden blieben unter Android unsichtbar, und „Anmelden“ ohne vorheriges „Verbinden“ tat nichts.

🔬 Development v0.9.0-develop.2 (11.10.2026)

Fehlerbehebungen

  • Die iPhone-App hĂ€lt das Telefon nicht mehr stĂ€ndig wach. Nach jedem Aufwachen fragte der Tunnel seine Server, ob die Verbindungen noch stehen — und die Antworten weckten das Telefon gleich wieder. So wachte es Tag und Nacht alle fĂŒnf bis sechs Sekunden auf. Jetzt fragt es höchstens einmal pro Minute; im ersten Protokoll danach wachte es etwa zehnmal seltener auf.
  • Weniger Unruhe im ganzen Wave durch einen Connector im Cluster. Ein Connector hinter dem NAT eines Kubernetes-Clusters meldete jede Minute eine neue Adresse, die niemand je erreicht hat, und jede Meldung schob allen GerĂ€ten im Wave eine neue Netzkarte zu — jedes Telefon wurde davon geweckt. Eine solche Adresse wird erst gemeldet, wenn sie sich bestĂ€tigt; bei einem NAT, das jedes Mal eine neue vergibt, bleibt es ruhig.

🔬 Development v0.9.0-develop.1 (11.10.2026)

Neue Funktionen

  • Aus dem Cluster in den Wave: der Connector beantwortet die Namen selbst. Ein Pod, der einen Namen im Wave aufruft, bekommt ihn jetzt vom Connector aufgelöst, der die Netzkarte kennt — ein Dienst, der im Wave dazukommt, ist nach Sekunden auflösbar, und ein Name, den es nicht gibt, ist sofort „gibt es nicht“ statt einer Adresse, an der die Verbindung erst abgewiesen wird. Der Eintrag in CoreDNS ist dafĂŒr ein einfaches forward auf eine feste Adresse und muss nie mehr angefasst werden. Wer die Egress-Komponente schon nutzt, stellt den CoreDNS-Eintrag einmal um (siehe coredns.example.yaml).

Fehlerbehebungen

  • Neue Karten im Zugriffsgraphen lagen unter alten. Wer einmal eine Karte verschoben hatte, bekam eine spĂ€ter hinzugefĂŒgte Karte (etwa „alle Dienste“) genau unter eine bestehende gelegt. Neue Karten rĂŒcken jetzt an einen freien Platz.

✅ Stable v0.8.0 (09.10.2026)

EnthÀlt alles aus v0.8.0-insiders.1 und v0.8.0-develop.1 bis v0.8.0-develop.3.

Neue Funktionen (gegenĂŒber v0.7.0)

  • Die Telefon-Apps fĂŒr iPhone, iPad und Android. Ein Telefon ist in mehreren Waves zugleich, mit direktem Weg und Relay als RĂŒckfall; jeder Wave hat seinen eigenen Schalter, verbindet sich nach Neustart und Netzwechsel von selbst wieder und sagt, was mit ihm nicht stimmt, statt nur „nicht verbunden“. Dazu ein eigener GerĂ€tename, ein teilbares Protokoll, „Verbindung prĂŒfen“ je Wave und Dienste, die sich mit einem Tippen öffnen. Die App nimmt keinem anderen VPN ungefragt den Platz weg. (seit develop.2)
  • Telefon per QR-Code hinzufĂŒgen: „Telefon hinzufĂŒgen“ in der WeboberflĂ€che zeigt einen Code, die Kamera öffnet die App mit dem Server schon eingetragen. (seit develop.3)
  • Mehrere Waves am selben Server, etwa fĂŒr getrennte Projekte: auf dem Desktop mit wave login <url> --new-wave, in der App mit „Weiteren Wave an diesem Server hinzufĂŒgen“. (seit develop.2)
  • In der WeboberflĂ€che erscheinen Telefone als iOS bzw. Android mit ihrer Version, GerĂ€te lassen sich umbenennen, und Mitglieder können einen Wave selbst verlassen. (seit develop.2)
  • svc:* in den Zugriffsregeln gibt alle Dienste im Wave frei, auch kĂŒnftige, aber kein GerĂ€t. (seit develop.1)
  • Apple-signierte und notarisierte macOS-Clients fĂŒr Intel und Apple Silicon. (seit insiders.1)

Fehlerbehebungen (gegenĂŒber v0.7.0)

  • Weniger Akkuverbrauch auf dem Telefon. Weder das Telefon noch die Desktops im Wave messen ruhende GerĂ€te stĂ€ndig neu oder schicken Keepalives; ruhende GerĂ€te stehen ĂŒberall als „ruht“. Der Server schickt keine neue Netzkarte mehr, wenn sich nichts geĂ€ndert hat. Beim ersten Paket nach einer Pause geht die Verbindung kurz ĂŒber das Relay, bis der direkte Weg wieder steht — ein Server ohne Relay findet zwischen zwei GerĂ€ten hinter NAT keinen direkten Weg mehr. (seit develop.2 und develop.3)
  • Ein neues GerĂ€t im Wave riss bestehende Verbindungen nicht mehr ab: Der Desktop-Client wechselt seinen Port nur noch, wenn gar kein Peer erreichbar ist. (seit develop.3)
  • Ein Connector, der nichts mehr trĂ€gt, wird neu gestartet, statt online auszusehen und keinen Dienst mehr erreichbar zu machen. (seit develop.3)
  • Der Connector meldet seine echte Version statt v0.0.0-dev. (seit develop.1)

GerÀte auf develop, die zwischendurch v0.8.0-insiders.1 installiert hatten, bekamen keine Develop-Builds mehr angeboten: 0.8.0-develop.N gilt nach Semver als Àlter als 0.8.0-insiders.1. Mit v0.8.0 sind alle KanÀle wieder auf demselben Stand.


🔬 Development v0.8.0-develop.3 (09.10.2026)

Neue Funktionen

  • „Verbindung prĂŒfen“ in der iPhone-App: pro Wave eine Seite, die in SĂ€tzen sagt, was geht und was nicht — Tunnel, Control-Server, Relay, Namensauflösung, jedes GerĂ€t (erreichbar, ruht, offline, nie erreicht) — und zu jedem Dienst eine echte Verbindung durch den Tunnel aufbaut.
  • Telefon per QR-Code hinzufĂŒgen: In der WeboberflĂ€che zeigt „Telefon hinzufĂŒgen“ bei jedem Wave einen Code. Die iPhone-Kamera öffnet damit die App mit dem Server schon eingetragen; die App fragt, bevor sie verbindet, und freigegeben wird wie immer im Browser.
  • Die iPhone-App schreibt ins Protokoll, was iOS ĂŒber sie misst: einmal am Tag CPU-Zeit, Daten ĂŒber Mobilfunk und WLAN und die Zeit im Hintergrund, getrennt fĂŒr App und Tunnel, und warum ein Lauf endete, wenn er abstĂŒrzte, hing oder zu viel CPU brauchte.
  • TestFlight per Knopfdruck, erst nach allen Tests: Vor dem Upload laufen Unit-Tests, Go-Kern, die End-to-End-Tests des Telefon-Kerns gegen echte Server und die iOS-Tests im Simulator; ein roter hĂ€lt den Build auf.
  • TestFlight per Knopfdruck: Der Workflow „TestFlight“ baut die iPhone-App aus dem gewĂ€hlten Stand, signiert sie und lĂ€dt sie hoch — gestartet von Hand in GitHub, auch aus der GitHub-App auf dem Telefon. Die Build-Nummer ist die nĂ€chste freie in App Store Connect, die SchlĂŒssel kommen aus 1Password.
  • Der Status des Telefons kennt je GerĂ€t die Byte-ZĂ€hler von WireGuard selbst — damit lĂ€sst sich sehen, ob ĂŒber eine Verbindung wirklich etwas lĂ€uft, statt es aus dem Pfad zu schließen.

Fehlerbehebungen

  • Die Telefone kommen endlich zur Ruhe. Das Telefon selbst sendete schon nichts mehr an ruhige GerĂ€te, aber jeder Laptop und jeder Server im Wave maß alle drei Sekunden jeden Weg zum Telefon und schickte alle 25 Sekunden ein Keepalive — und weckte damit das Mobilfunkmodem immer wieder. Jetzt verhalten sich auch die Desktop-Clients so wie das Telefon: Gemessen wird nur ein GerĂ€t, mit dem gerade gesprochen wird, Keepalives gibt es nicht mehr, und wave status sowie das Tray zeigen ruhende GerĂ€te als „ruht“. Wirksam wird das, sobald die Desktops diese Version haben. Beim ersten Paket nach einer Pause geht die Verbindung kurz ĂŒber das Relay, bis der direkte Weg wieder steht — ein Server ohne Relay findet zwischen zwei GerĂ€ten hinter NAT keinen direkten Weg mehr.
  • Mit zwei Waves auf dem iPhone ging der zweite nicht: Jeder Dienst im ersten Wave antwortete, im zweiten nichts, bis der erste pausiert wurde. iOS schickte alles mit der Adresse des ersten Waves los. Der Tunnel setzt jetzt selbst die richtige Absenderadresse je Wave.
  • Ein neues GerĂ€t im Wave riss bestehende Verbindungen ab. Der Desktop-Client wechselte seinen UDP-Port, sobald irgendein Peer noch keinen Weg hatte — und das hat jedes GerĂ€t, das gerade beitritt. Telefone, die ruhige GerĂ€te seit dem Akku-Fix nicht mehr stĂ€ndig anpingen, brauchten dann ĂŒber zehn Sekunden, um den neuen Port zu finden. Gewechselt wird jetzt nur noch, wenn gar kein Peer mehr erreichbar ist.
  • „Noch nicht erreicht“ stand auch bei GerĂ€ten, die nur ruhen: Seit das Telefon ruhige GerĂ€te nicht mehr anpingt, gibt es mit ihnen keinen Handshake, und das ist kein Fehler.
  • Der Server schickte stĂ€ndig neue Netzkarten an alle GerĂ€te, in einem Wave mit einem Dutzend GerĂ€ten etwa alle acht Sekunden: Jedes GerĂ€t, das seine Adressen neu meldete, löste eine aus, auch wenn sich nichts geĂ€ndert hatte. Das weckte jedes Telefon und kostete Akku. Gleiche Adressen Ă€ndern jetzt nichts mehr.
  • Ein Connector, der nichts mehr trĂ€gt, wird neu gestartet. Er konnte am Steuerkanal hĂ€ngen, beim Server als online gelten und trotzdem keinen einzigen Dienst mehr erreichbar machen. Eine Liveness-Probe fragt jetzt den Daemon: Tunnel oben, Relay verbunden, und mit mindestens einem Peer ein Handshake in den letzten zehn Minuten.

🔬 Development v0.8.0-develop.2 (08.10.2026)

Neue Funktionen

  • Die Telefon-Apps sind bereit fĂŒr App Store und Google Play. Sie heißen jetzt wave-mesh, tragen das Zeichen als App-Icon und Petrol als Akzent und zeigen vor der ersten Verbindung einmal, was mit Daten geschieht: kein Server von Moellenbeck Digital im Weg, keine Analyse, keine Werbung. Die iOS-App lĂ€uft auf iPhone und iPad ab iOS 17, die Android-App ab Android 10 und zielt auf API 36, wie Google Play es verlangt.
  • Die iPhone-App verbindet sich von selbst wieder nach Neustart und Netzwechsel, bis man ausdrĂŒcklich trennt.
  • Jeder Wave hat seinen eigenen Schalter, wie im Tray: pausieren, ohne ihn zu verlassen, und ohne neue BestĂ€tigung wieder einschalten.
  • Ein eigener GerĂ€tename statt „iPhone“; die App zeigt vorher, wie das GerĂ€t im Wave heißen wird („Möllenbeck“ wird zu moellenbeck, nicht m-llenbeck).
  • Eine wartende Anmeldung lĂ€sst sich abbrechen, „Wave verlassen“ fragt nach, und Namen und Adressen der GerĂ€te lassen sich kopieren.
  • Die iPhone-App hat ein Protokoll (teilbar), in dem steht, was Tunnel und App getan haben.
  • Aus der App in die WeboberflĂ€che, und Dienste öffnen sich mit einem Tippen. Ein Wave sagt, was mit ihm nicht stimmt — vom Server entfernt (mit „Erneut anmelden“), abgelehnte Netzkarte, nicht hochgekommen — statt nur „nicht verbunden“; bei jedem GerĂ€t steht der letzte Handshake.
  • Neben Tailscale: iOS lĂ€sst nur ein VPN zu. Die App nimmt beim ersten Öffnen keinem anderen den Platz weg, fragt, bevor sie einen anderen VPN verdrĂ€ngt, und „Automatisch verbinden“ lĂ€sst sich ausschalten.
  • Die BestĂ€tigungsseite teilt die Anmeldung mit Safari: wer im Control-Server angemeldet ist, muss sich nicht jedes Mal neu anmelden.
  • In der WeboberflĂ€che: Telefone erscheinen als iOS bzw. Android mit ihrer Version, GerĂ€te lassen sich umbenennen, und Mitglieder können einen Wave selbst verlassen.
  • Die iPhone-App sagt pro Wave, ob ein Relay da ist: „Relay verbunden“, „Relay nicht verbunden“ oder „Dieser Server bietet kein Relay an“ — ohne Relay bleiben GerĂ€te, die das Telefon nicht direkt erreicht, etwa ein Connector in einem Cluster, unerreichbar. Ein GerĂ€t, das der Server online nennt, mit dem aber noch nie ein Handshake zustande kam, steht als „Noch nicht erreicht“ da.
  • Das Protokoll der Telefon-Apps sagt, was mit DNS los ist: eine Zeile pro Wave mit Zone, eigener Adresse, Resolver und der Zahl der GerĂ€te und Dienste, und eine Zeile, wenn ein Name gefragt wurde, den die Netzkarte nicht kennt („dns: grafana.
 is not in the netmap of 
"), je Name höchstens einmal pro Minute.
  • Mehrere Waves am selben Server, fĂŒr getrennte Projekte oder Firmen auf einem Control-Server: auf dem Desktop mit wave login <url> --new-wave, in der iPhone-App mit „Weiteren Wave an diesem Server hinzufĂŒgen". Jeder ist eine eigene Anmeldung mit eigenen SchlĂŒsseln und Adressen, heißt nach seiner DNS-Zone (wave down project-b.wave.internal) und lĂ€sst sich einzeln pausieren und verlassen; die GerĂ€te des einen sehen die des anderen nicht.

Fehlerbehebungen

  • Die Telefon-Apps verbrauchen deutlich weniger Akku. Der Tunnel schickte stĂ€ndig Pakete, auch wenn gar nichts darĂŒber lief: alle drei Sekunden eine Messung an jedes GerĂ€t im Wave und alle 25 Sekunden ein Keepalive. Damit kam das Mobilfunkmodem nie zur Ruhe. Jetzt misst das Telefon nur noch GerĂ€te, mit denen es gerade spricht; die anderen stehen in der App als „ruht“. Auch das Aufwachen des iPhones baut nicht mehr jedes Mal alle Verbindungen neu auf, sondern fragt nur nach, ob sie noch stehen.
  • Das Protokoll der iPhone-App war nach lĂ€ngerer Laufzeit schwarz, und Teilen schickte nichts: es wurde als ein einziger Textblock gezeichnet, der fĂŒr iOS zu groß war, und als Text geteilt, den Messenger wie Telegram ab einer gewissen LĂ€nge nicht verschicken. Jetzt Zeile fĂŒr Zeile und als Datei wave-mesh-log-<datum>.txt.
  • Die iPhone-App ist sparsamer und robuster geworden, nachdem sie sich bei einem Tester von selbst beendet hatte. Ein Netzwechsel, der vor dem fertigen Start des Tunnels ankam, konnte den Tunnel abstĂŒrzen lassen. Die App las bei jedem Neuzeichnen das ganze Protokoll und stapelte Statusabfragen, wenn der Tunnel langsam antwortete; beides passiert nicht mehr.
  • Mit zwei Waves löste das iPhone nur die Namen des ersten auf, wenn der Server des anderen keine eigene Resolver-Adresse reserviert hatte. Dann stand eine Adresse des Telefons selbst in der DNS-Liste, und Anfragen dorthin kamen nie im Tunnel an. Sie wird nicht mehr angeboten; der Resolver an der reservierten Adresse beantwortet die Namen aller Waves.
  • Liegt die DNS-Zone eines Waves innerhalb der eines anderen (team.ops.example.com in ops.example.com), antwortet auf dem Telefon jetzt die nĂ€here Zone. Vorher meldete die Ă€ußere fĂŒr jedes GerĂ€t der inneren „gibt es nicht".
  • Auf dem Telefon kam nach dem Anmelden nichts an. Beide Apps lasen die Routen aus dem Kern in einer Form, die es nicht mehr gab; iOS wendete deshalb weder Adressen noch Routen noch DNS an, Android ebenso wenig. Ein Test hĂ€lt die Form jetzt zwischen Kern und App fest.
  • Anmelden auf dem iPhone tat nichts, solange der Tunnel aus war. Jetzt startet die App den Tunnel selbst, öffnet die BestĂ€tigungsseite direkt in der App und zeigt, wo die Anmeldung steht — und warum sie scheitert, statt die Eingabe still zu verwerfen. Ist schon ein Wave da, heißt der Bereich „Weiteren Wave hinzufĂŒgen".
  • Eine abgebrochene Anmeldung legte den Tunnel lahm. Wer die BestĂ€tigungsseite schloss, hinterließ einen nie bestĂ€tigten Wave, und an dem scheiterte danach jeder Start des Tunnels. Jetzt wird er vergessen, und ein Wave, der nicht hochkommt, hĂ€lt die anderen nicht mehr auf.
  • Mit zwei Waves sprang die Liste in der App jede Sekunde; sie bleibt jetzt in der Reihenfolge, in der die Waves dazukamen.
  • Auf dem Telefon rissen neue Netzkarten jedes Mal alle WireGuard-Sitzungen ab, und das Telefon meldete jede Minute seine Adressen neu — womit der Server dem ganzen Wave eine neue Netzkarte schickte. Beides passiert nur noch bei einer echten Änderung; nach einem Netzwechsel verbindet es sofort neu, und ein vom Server entferntes GerĂ€t hĂ€ngt nicht mehr ohne Hinweis.
  • Trennen konnte auf einem stillen Tunnel hĂ€ngen, bis zufĂ€llig ein Paket kam.
  • Die iOS-App ließ sich nicht bauen: die Tunnel-Extension nutzte Schnittstellen, die es nur unter macOS gibt, und den falschen Namen fĂŒr die RĂŒckrufe des Go-Kerns.
  • Die Android-App ließ sich nicht bauen: das Symbol ihrer Benachrichtigung war keine öffentliche Ressource von Android.

🔬 Development v0.8.0-develop.1 (06.10.2026)

Neue Funktionen

  • svc:* in den Zugriffsregeln: gibt alle Dienste im Wave frei — auch die, die ein Connector erst spĂ€ter meldet —, aber kein einziges GerĂ€t. Damit lĂ€sst sich „alles aus dem Cluster“ freigeben, ohne dass die Policy bei jedem neuen Ingress angepasst werden muss. Wie jeder Dienst nur als Ziel einer Regel; im Zugriffsgraphen steht dafĂŒr immer eine eigene Karte.

Fehlerbehebungen

  • Der Connector meldet in der GerĂ€teliste seine echte Version statt v0.0.0-dev (ab dem ersten Image, das mit diesem Release gebaut wird).

đŸ§Ș Insiders v0.8.0-insiders.1 (05.10.2026)

Verbesserungen

  • Apple-signierte und notarisierte macOS-Clients fĂŒr Intel und Apple Silicon. Sowohl wave als auch das beigelegte wireguard-go tragen eine Developer-ID- Signatur. Das bestehende Archivformat und der automatische Updateweg bleiben erhalten. Die Signaturen und Apple-Tickets werden vor der Veröffentlichung geprĂŒft.
  • Die macOS-Archive enthalten keine zusĂ€tzlichen Apple-Metadatendateien mehr.

Technische Änderungen

  • Release-Job auf macOS, isolierter temporĂ€rer SchlĂŒsselbund und eigener 1Password-Vault fĂŒr die Apple-Zugangsdaten; Bereinigung auch bei Fehlern.
  • Finale PrĂŒfsummen und Ed25519-Manifest werden erst nach der Apple-Signierung erstellt. Ein zusĂ€tzlicher Signierungsnachweis enthĂ€lt Hashes und Submission-IDs.
  • Automatisierte Tests fĂŒr SignaturprĂŒfung, abgelehnte Notarisierung, sichere Archivextraktion und Entfernung privater Dateien.

Bekannte EinschrÀnkungen

  • Einzelne Binaries unterstĂŒtzen kein Stapling: Gatekeeper benötigt fĂŒr das Notarisierungsticket eine Online-Verbindung. Die unabhĂ€ngige Download-, Installations- und Auto-Update-Abnahme auf einem weiteren Mac steht noch aus.

✅ Stable v0.7.0 (05.10.2026)

EnthÀlt alles aus v0.7.0-develop.1 bis v0.7.0-develop.3.

Neue Funktionen (gegenĂŒber v0.6.0)

  • Zwei-Faktor-Anmeldung mit einer Authenticator-App fĂŒr die Anmeldung mit E-Mail und Passwort. Eingerichtet wird auf der Seite „Dein Konto“ (die eigene Adresse oben rechts): QR-Code scannen, ersten Code bestĂ€tigen, zehn Wiederherstellungscodes sichern. FĂŒr das verlorene Telefon gibt es einen Wiederherstellungscode oder wave-admin disable-2fa <email>. (seit develop.1)
  • Aus einem Cluster in den Wave. Pods in einem Cluster mit Connector erreichen Dienste und GerĂ€te des Waves ĂŒber deren Namen, etwa https://plausible.wave.example.com — auch Dienste, die ein anderer Cluster in den Wave stellt. TLS bleibt Ende zu Ende; nur HTTP und HTTPS. Je Cluster einzuschalten mit der Komponente components/egress und einem CoreDNS-Eintrag nach Vorlage. (seit develop.3)

Wer sich ĂŒber Google oder Pocket ID anmeldet, nutzt deren zweiten Faktor. Die Clients haben sich seit v0.6.0 nicht geĂ€ndert; GerĂ€te auf dem Kanal stable bekommen v0.7.0 trotzdem angeboten.


🔬 Development v0.7.0-develop.3 (05.10.2026)

Neue Funktionen

  • Aus einem Cluster in den Wave. Pods in einem Cluster mit Connector erreichen Dienste und GerĂ€te des Waves ĂŒber deren Namen, etwa https://plausible.wave.example.com — auch Dienste, die ein anderer Cluster in den Wave stellt. TLS bleibt dabei Ende zu Ende; nur HTTP und HTTPS. Eingeschaltet wird es je Cluster mit der Komponente components/egress und einem CoreDNS-Eintrag, der als Vorlage beiliegt.

🔬 Development v0.7.0-develop.2 (04.10.2026)

Derselbe Inhalt wie develop.1. Dessen Build ist an einem Fehler im Testskript gescheitert und hat keine Images und kein Release hervorgebracht.


🔬 Development v0.7.0-develop.1 (04.10.2026)

Neue Funktionen

  • Zwei-Faktor-Anmeldung mit einer Authenticator-App fĂŒr die Anmeldung mit E-Mail und Passwort. Eingerichtet wird auf der neuen Seite „Dein Konto“ (die eigene Adresse oben rechts): QR-Code scannen, ersten Code bestĂ€tigen, zehn Wiederherstellungscodes sichern. Danach fragt die Anmeldung nach dem Passwort noch nach dem Code aus der App.
  • FĂŒr das verlorene Telefon: ein Wiederherstellungscode meldet einmal an, und der Betreiber kann den zweiten Faktor mit wave-admin disable-2fa <email> abschalten.

Wer sich ĂŒber Google oder Pocket ID anmeldet, nutzt deren zweiten Faktor; dort gibt es hier nichts einzurichten.


✅ Stable v0.6.0 (03.10.2026)

Neue Funktionen (gegenĂŒber v0.5.0)

  • Anmeldung ĂŒber Pocket ID und jeden anderen OpenID-Connect-Provider (Authelia, Authentik, Keycloak 
). Der Betreiber trĂ€gt Issuer, Client-ID und einen Namen ein; auf der Anmelde- und der Einladungsseite steht dann etwa „Weiter mit Pocket ID". Mit Pocket ID meldet sich niemand mehr mit einem Passwort an, nur noch mit einem Passkey.

Einladungen annehmen kann nur, wessen Adresse der Provider als bestĂ€tigt meldet — in Pocket ID ist das die Einstellung „Emails Verified". An den Clients hat sich nichts geĂ€ndert; GerĂ€te auf dem Kanal stable bekommen v0.6.0 trotzdem angeboten, mit demselben Code wie v0.5.0.


✅ Stable v0.5.0 (02.10.2026)

EnthÀlt alles aus v0.5.0-develop.1.

Neue Funktionen (gegenĂŒber v0.4.0)

  • Deutsch und Englisch ĂŒberall. WeboberflĂ€che, die Seiten des Control-Servers, wave, das Tray-Icon, wave-admin und die Apps gibt es in beiden Sprachen; ist die eigene keine davon, gilt Englisch. (seit develop.1)
  • Umschalter DE | EN in der Kopfzeile der WeboberflĂ€che, auch vor der Anmeldung. Ohne Wahl gilt die Sprache des Browsers. (seit develop.1)
  • wave und das Tray-Icon folgen der Systemsprache, WAVE_LANG=en oder WAVE_LANG=de legt sie fest. Meldungen des Dienstes erscheinen in der Sprache dessen, der sie liest. (seit develop.1)
  • Das Tray-MenĂŒ sagt jetzt, warum sich ein GerĂ€t nicht selbst aktualisiert. (seit develop.1)

Verbesserungen (gegenĂŒber v0.4.0)

  • Ist eine GerĂ€tefreigabe abgelaufen oder ein Wave noch leer, nennt die Seite den richtigen Befehl: wave login <control-server-url> statt wave up. (seit develop.1)

GerÀte auf dem Kanal stable bekommen diese Version von selbst angeboten. Die Protokolle des Dienstes und des Servers bleiben englisch.


🔬 Development v0.5.0-develop.1 (02.10.2026)

Neue Funktionen

  • Deutsch und Englisch ĂŒberall. WeboberflĂ€che, die Seiten des Control-Servers, wave, das Tray-Icon, wave-admin und die Apps gibt es in beiden Sprachen; ist die eigene keine davon, gilt Englisch.
  • Umschalter DE | EN in der Kopfzeile der WeboberflĂ€che, auch vor der Anmeldung. Ohne Wahl gilt die Sprache des Browsers.
  • wave und das Tray-Icon folgen der Systemsprache, WAVE_LANG=en oder WAVE_LANG=de legt sie fest. Meldungen des Dienstes erscheinen in der Sprache dessen, der sie liest.
  • Das Tray-MenĂŒ sagt jetzt, warum sich ein GerĂ€t nicht selbst aktualisiert.

Verbesserungen

  • Ist eine GerĂ€tefreigabe abgelaufen oder ein Wave noch leer, nennt die Seite den richtigen Befehl: wave login <control-server-url> statt wave up.

Protokolle des Dienstes und des Servers bleiben englisch, damit man sie durchsuchen und vergleichen kann.


✅ Stable v0.4.0 (02.10.2026)

EnthÀlt alles aus v0.4.0-develop.1 und v0.4.0-develop.2.

Neue Funktionen (gegenĂŒber v0.3.0)

  • Zugriffsregeln als Graph. Auf der Zugriffsseite eines Waves stehen Mitglieder, Gruppen, Rollen, Tags, Dienste und „alle“ als Karten; eine Regel ist ein Pfeil, den man von einer Karte zur anderen zieht, und die Ports hĂ€ngen an der Kante. Der erste Pfeil schaltet die Policy ein — ab dann gilt nur noch, was ein Pfeil erlaubt. (seit develop.1)
  • Gruppen und Tags direkt auf der Seite. Gruppen werden angelegt und mit Mitgliedern gefĂŒllt, Tags angelegt und GerĂ€ten gegeben. Die Seite zeigt dabei sofort, welche GerĂ€te eine Karte trifft und wer danach wen erreicht — noch bevor gespeichert ist. Gespeichert wird alles auf einmal, mit „RĂŒckgĂ€ngig“ und „Verwerfen“ davor. (seit develop.1)
  • Die Policy lĂ€sst sich weiterhin als JSON bearbeiten, aufklappbar unter dem Graphen. (seit develop.1)

Verbesserungen (gegenĂŒber v0.3.0)

  • Die Leiste zum Bearbeiten steht rechts neben dem Graphen, die Zugriffsseite ist dafĂŒr so breit wie die Kopfzeile. (seit develop.2)
  • Die Übersicht beginnt direkt mit den Wave-Karten. (seit develop.1)

An den Clients hat sich nichts geĂ€ndert. GerĂ€te auf dem Kanal stable bekommen v0.4.0 trotzdem angeboten und installieren sie — mit demselben Code wie v0.3.0.


🔬 Development v0.4.0-develop.2 (01.10.2026)

Verbesserungen

  • Die Leiste zum Bearbeiten steht rechts neben dem Graphen, nicht mehr darunter: wer eine Karte oder einen Pfeil antippt, sieht sofort, was sich dort einstellen lĂ€sst. Die Zugriffsseite ist dafĂŒr so breit wie die Kopfzeile; auf schmaleren Bildschirmen rutscht die Leiste weiter unter den Graphen.

🔬 Development v0.4.0-develop.1 (01.10.2026)

Neue Funktionen

  • Zugriffsregeln als Graph. Auf der Zugriffsseite eines Waves stehen Mitglieder, Gruppen, Rollen, Tags, Dienste und „alle“ als Karten; eine Regel ist ein Pfeil, den man von einer Karte zur anderen zieht, und die Ports hĂ€ngen an der Kante. Der erste Pfeil schaltet die Policy ein — ab dann gilt nur noch, was ein Pfeil erlaubt.
  • Gruppen und Tags direkt auf der Seite. Gruppen werden angelegt und mit Mitgliedern gefĂŒllt, Tags angelegt und GerĂ€ten gegeben. Die Seite zeigt dabei sofort, welche GerĂ€te eine Karte trifft und wer danach wen erreicht — noch bevor gespeichert ist. Gespeichert wird alles auf einmal, mit „RĂŒckgĂ€ngig“ und „Verwerfen“ davor.
  • Die Policy lĂ€sst sich weiterhin als JSON bearbeiten, aufklappbar unter dem Graphen.

Verbesserungen

  • Die Übersicht beginnt direkt mit den Wave-Karten, ohne Einleitung darĂŒber.

✅ Stable v0.3.0 (01.10.2026)

EnthÀlt alles aus v0.3.0-develop.1.

Neue Funktionen (gegenĂŒber v0.2.0)

  • Der Update-Dialog trĂ€gt das wave-Zeichen statt eines Systemsymbols — unter macOS im Dialog, unter Windows im Fenster und in seiner Titelleiste, unter Linux in der Benachrichtigung. Unter Windows ist der Dialog ein eigenes kleines Fenster mit „Install now" und „Later" statt einer Ja/Nein-Abfrage. (seit develop.1)

GerĂ€te mit v0.2.0 bekommen diese Version von selbst angeboten — und sehen dabei den Update-Dialog zum ersten Mal, noch in seiner alten Form.


🔬 Development v0.3.0-develop.1 (01.10.2026)

Neue Funktionen

  • Der Update-Dialog trĂ€gt das wave-Zeichen statt eines Systemsymbols — unter macOS im Dialog, unter Windows im Fenster und in seiner Titelleiste, unter Linux in der Benachrichtigung. Unter Windows ist der Dialog dafĂŒr ein eigenes kleines Fenster mit „Install now" und „Later" statt einer Ja/Nein-Abfrage.

✅ Stable v0.2.0 (01.10.2026)

Clients halten sich ab dieser Version selbst aktuell. EnthÀlt alles aus v0.2.0-develop.1 bis v0.2.0-develop.4.

Neue Funktionen (gegenĂŒber v0.1.0)

  • Clients aktualisieren sich selbst. Der Control-Server bietet neue Releases an, der Dienst installiert sie nach einer zufĂ€lligen Wartezeit von bis zu vier Stunden und kehrt von allein zur alten Version zurĂŒck, wenn die neue keinen Server erreicht. Installiert wird nur, was mit dem Release-SchlĂŒssel signiert ist, und nie eine Ă€ltere Version. (seit develop.1)
  • Neue Befehle: wave version zeigt die installierte Fassung und ob eine neuere ansteht, wave update installiert sie sofort, --channel und --auto-update on|off stellen Kanal und Automatik ein. (seit develop.1)
  • Update-Dialog: Eine neue Version meldet sich einmal mit einem Dialog, der mit einem Klick installiert; Tooltip und MenĂŒ des Tray-Icons nennen sie ebenfalls. (seit develop.1 und develop.4)
  • Client-Versionen in der WeboberflĂ€che: Die GerĂ€teliste zeigt, welche Version und welcher Update-Kanal auf jedem GerĂ€t lĂ€uft, live aktualisiert. (seit develop.2)

FĂŒr Betreiber

  • WAVE_UPDATE_CHANNELS legt fest, welche KanĂ€le ein Server anbietet (stable, insiders, develop; der erste ist die Vorgabe, ungesetzt stable). Ohne WAVE_GITHUB_TOKEN — Fine-grained, nur dieses Repository, „Contents: read" — wird nichts angeboten.
  • wave-admin devices zeigt Version und Kanal jedes GerĂ€ts.
  • Eine Datenbankmigration lĂ€uft beim Rollout von selbst mit.

Clients von v0.1.0 und Àlter können sich noch nicht selbst aktualisieren: auf jedem GerÀt einmal von Hand sudo ./wave install mit dieser Version, danach geht es von allein.


🔬 Development v0.2.0-develop.4 (01.10.2026)

Ein neues Update meldet sich jetzt mit einem Dialog.

✹ Update-Dialog mit „Install now"

Steht eine neue Version bereit, erscheint einmal ein Dialog, der beide Versionen nennt, sagt, wann sich das GerĂ€t sonst selbst aktualisiert, und mit einem Klick sofort installiert. Unter Linux ist das eine Desktop-Benachrichtigung mit dem Knopf „Install now" — wo der Benachrichtigungsdienst keine Knöpfe kennt, genĂŒgt ein Klick auf die Meldung —, unter macOS ein Dialog mit „Later" und „Install now", unter Windows eine Meldung mit Ja und Nein.

Nach „Later" kommt der Dialog fĂŒr diese Version nicht wieder; der Eintrag „Install update now" im MenĂŒ des Tray-Icons bleibt.

Zu sehen ist der Dialog ab dem ersten Update nach dieser Version: er muss im Tray stecken, das das Angebot bekommt.


🔬 Development v0.2.0-develop.3 (01.10.2026)

Keine neuen Funktionen: ein Release, an dem sich die Selbst-Updates erproben lassen. Ein GerÀt mit v0.2.0-develop.1 oder .2 auf dem Kanal develop sollte sich von selbst auf diese Version heben.


🔬 Development v0.2.0-develop.2 (01.10.2026)

Die WeboberflÀche zeigt, welche Version auf jedem GerÀt lÀuft.

✹ Client-Version in der GerĂ€teliste

In der GerĂ€teliste steht jetzt unter dem Betriebssystem, welche Version des Clients ein GerĂ€t fĂ€hrt und welchem Update-Kanal es folgt — etwa v0.2.0-develop.1 · develop. So ist auf einen Blick zu sehen, wer zurĂŒckhĂ€ngt. Die Anzeige folgt live: meldet sich ein GerĂ€t nach einem Update mit der neuen Version, Ă€ndert sie sich ohne Neuladen. GerĂ€te mit Clients von vor den Selbst-Updates melden ihre Version nicht und stehen dort als „Version unbekannt".


🔬 Development v0.2.0-develop.1 (01.10.2026)

Installierte Clients halten sich ab jetzt selbst aktuell.

✹ Clients aktualisieren sich selbst

Bisher blieb ein installiertes GerĂ€t auf seiner Version stehen, bis jemand ein neues Archiv holte und wave install noch einmal ausfĂŒhrte. Jetzt bietet der Control-Server seinen GerĂ€ten neue Releases an, und der Dienst installiert sie nach einer zufĂ€lligen Wartezeit von bis zu vier Stunden selbst. Erreicht die neue Fassung danach binnen fĂŒnf Minuten keinen Server, kehrt das GerĂ€t von allein zur alten zurĂŒck und nimmt diese Version nie wieder.

Installiert wird nur, was mit dem Release-SchlĂŒssel signiert ist, den das Programm mitbringt — der Control-Server reicht Releases nur weiter und kann nichts unterschieben. Ältere Versionen werden nie installiert.

wave version                     # welche Fassung, und ob eine neuere ansteht
wave update                      # die neuere jetzt statt spÀter
wave update --channel insiders   # ein anderer Kanal, sofern der Server ihn anbietet
wave update --auto-update off    # nur noch anzeigen

Das Tray-Icon nennt ein anstehendes Update im Tooltip, im MenĂŒ (mit „Install update now") und im Fenster.

FĂŒr Betreiber

  • Welche KanĂ€le ein Server anbietet, legt WAVE_UPDATE_CHANNELS fest: stable, insiders, develop, mehrere mit Komma, der erste ist die Vorgabe. Ungesetzt ist es stable. Ein GerĂ€t kann sich einen anderen aus der Liste wĂŒnschen, keinen darĂŒber hinaus.
  • Ohne WAVE_GITHUB_TOKEN wird nichts angeboten. Nötig ist ein Fine-grained Token nur fĂŒr dieses Repository mit „Contents: read"; er bleibt auf dem Server.
  • wave-admin devices zeigt jetzt die Version jedes GerĂ€ts und seinen Kanal. GerĂ€te mit Ă€lteren Clients stehen dort als „version unknown".
  • Eine neue Datenbankmigration lĂ€uft beim Rollout von selbst mit.

Der erste Client mit dieser Funktion muss noch einmal von Hand installiert werden; ab dann geht es von allein.


✅ Stable v0.1.0 (01.10.2026)

Die erste stabile Version: sie enthĂ€lt alles aus v0.1.0-insiders.1 bis v0.1.0-insiders.9 und dazu die Änderung unten.

📩 Neues Zuhause: moellenbeck-digital

wave-mesh liegt jetzt im Repository moellenbeck-digital/wave-mesh. Die Images kommen ab dieser Version aus ghcr.io/moellenbeck-digital/wave-mesh/*; wer sie bisher unter ghcr.io/pinguin45orga/wave-mesh/* bezogen hat, stellt die Adresse um. An bestehenden Anmeldungen, GerÀten und Adressen Àndert sich nichts.

Das Wichtigste aus den Vorschau-Versionen

  • Zugriffsregeln: Eine Policy legt fest, wer wen erreicht — nach Personen, Gruppen, Rollen, Diensten oder Tags, mit Ports und Richtung. Ohne Policy erreicht weiterhin jedes GerĂ€t jedes andere. (seit insiders.5)
  • Verlauf: Jede Änderung an einem Wave wird mit Zeit und Person festgehalten. (seit insiders.5)
  • Neuer Name und eigenes Icon: Aus wave-net wurde wave-mesh, mit eigenem Zeichen im Tray und im Browser-Tab. (seit insiders.7 und insiders.9)
  • Neue Lizenz: Elastic License 2.0 statt MIT. (seit insiders.9)
  • Schonender fĂŒrs Netz: Keine wachsenden Adresslisten mehr, die Heimrouter volllaufen ließen, und deutlich weniger Anfragen an Adressen, die nie antworten. (seit insiders.1 und insiders.6)
  • Robuster nach Ruhezustand und WLAN-Aussetzern: Die Relay-Verbindung baut sich selbst neu auf, und der Verkehr kehrt auf den direkten Weg zurĂŒck. (seit insiders.2)

đŸ§Ș Insiders v0.1.0-insiders.9 (01.10.2026)

Neu gegenĂŒber v0.1.0-insiders.8.

✹ Ein eigenes Icon

wave-mesh hat ein Zeichen: drei verbundene Knoten auf einer Scheibe, die Grundlinie eine Welle. Es steht im Tray unter Linux, Windows und macOS und als Symbol im Browser-Tab der OberflĂ€che. Der Tray zeigt den Zustand wie bisher an der Farbe — Petrol verbunden, Gelb verbindend, Grau getrennt. Unter macOS ersetzt es den farbigen Punkt in der MenĂŒleiste; dort ist es neu und noch nicht auf echter Hardware erprobt.

📄 Neue Lizenz: Elastic License 2.0

wave-mesh steht ab dieser Version unter der Elastic License 2.0 statt MIT. Benutzen, verĂ€ndern und weitergeben bleibt erlaubt, auch im eigenen Unternehmen; nicht erlaubt ist, wave-mesh Dritten als gehosteten oder verwalteten Dienst anzubieten. FrĂŒhere Versionen bleiben unter MIT.


đŸ§Ș Insiders v0.1.0-insiders.8 (30.09.2026)

Neu gegenĂŒber v0.1.0-insiders.7.

🐛 Logo im Seitenkopf

Der Seitenkopf der OberflĂ€che zeigte noch „wavenet“; jetzt steht dort „wavemesh“.


đŸ§Ș Insiders v0.1.0-insiders.7 (30.09.2026)

Neu gegenĂŒber v0.1.0-insiders.6.

✹ Neuer Name: wave-mesh

Das Projekt heißt jetzt wave-mesh statt wave-net — in der OberflĂ€che, in der Beschreibung des Dienstes auf dem GerĂ€t und im Repository. Die Images liegen ab dieser Version unter ghcr.io/pinguin45orga/wave-mesh/*. An bestehenden Anmeldungen, GerĂ€ten und Adressen Ă€ndert sich nichts.


đŸ§Ș Insiders v0.1.0-insiders.6 (30.09.2026)

Neu gegenĂŒber v0.1.0-insiders.5.

🐛 Weniger Fehlversuche ins Leere

Ein GerĂ€t probiert jede Adresse, unter der ein anderes vielleicht erreichbar ist — auch solche, die von hier aus gar nicht erreichbar sind, etwa das Heimnetz eines anderen Standorts. Eine Adresse, die nie antwortete, bekam bisher viermal pro Sekunde eine Anfrage, und zwar dauerhaft. Das kostete VerbindungseintrĂ€ge im eigenen Router und fĂŒllte das Log mit Hunderten von Meldungen wie „socket error(s) ignored“ pro Minute. Nach den ersten fĂŒnf Sekunden wird eine solche Adresse jetzt nur noch alle drei Sekunden gefragt, so oft wie eine funktionierende. Verbindungen kommen genauso schnell zustande wie vorher, auch auf den Telefonen.


đŸ§Ș Insiders v0.1.0-insiders.5 (29.09.2026)

Neu gegenĂŒber v0.1.0-insiders.2. Die Tags v0.1.0-insiders.3 und .4 wurden nie veröffentlicht: der Test der Zugriffsregeln fand zuerst einen Fehler in sich selbst und dann einen echten — unter Ubuntu 24.04 hĂ€tten Linux-GerĂ€te die Ports nicht durchgesetzt. Beides ist hier behoben.

✹ Zugriffsregeln: wer wen erreicht

Bisher erreichte in einem Wave jedes GerĂ€t jedes andere, auf allen Ports. Das bleibt so, solange niemand etwas anderes festlegt. Jetzt lĂ€sst sich fĂŒr einen Wave eine Policy setzen, und dann ist nur noch erlaubt, was eine Regel nennt: etwa „meine GerĂ€te erreichen das NAS, aber nur fĂŒr Dateifreigaben“, oder „der Kubernetes-Connector erreicht niemanden von sich aus“.

  • Regeln nennen Personen, Gruppen, Rollen, Dienste oder Tags. Ein Tag kennzeichnet eine Maschine — tag:nas, tag:server — und ein getaggtes GerĂ€t zĂ€hlt nicht mehr als GerĂ€t seines Besitzers.
  • Ein GerĂ€t, das eine Regel nicht erlaubt, ist fĂŒr die anderen gar nicht erst da. Das gilt sofort fĂŒr jedes GerĂ€t, auch fĂŒr eines mit Ă€lterer Version.
  • Die erlaubten Ports und die Richtung setzt jedes GerĂ€t selbst durch: unter Linux und im Kern der Telefon-Apps geprĂŒft, unter macOS und Windows neu und dort noch nicht auf echter Hardware erprobt. Welches GerĂ€t die Ports hĂ€lt, zeigt die neue Zugriffsseite.
  • Verwaltet wird auf der neuen Seite Zugriff in der Wave-Karte, fĂŒr EigentĂŒmer und Admins, oder mit wave-admin.

✹ Verlauf

Jede Änderung an einem Wave — Regeln, Tags, Mitglieder, Einladungen, GerĂ€te, Domain — wird mit Zeit und Person festgehalten und ist auf der Zugriffsseite zu sehen.


đŸ§Ș Insiders v0.1.0-insiders.2 (28.09.2026)

Neu gegenĂŒber v0.1.0-insiders.1.

🐛 Nach dem Ruhezustand wieder erreichbar

Wachte ein Laptop aus dem Ruhezustand auf, blieb seine Verbindung zum Relay still tot: die Anzeige sagte „relay connected“, aber GerĂ€te, die nur ĂŒber das Relay erreichbar sind — etwa ein Connector in einem Kubernetes-Cluster — standen auf „connecting
“, bis wave neu gestartet wurde. Jetzt prĂŒft wave die Relay-Verbindung alle 15 Sekunden und baut sie neu auf, sobald sie nicht mehr antwortet. Das gilt ebenso fĂŒr den Kern der Telefon-Apps, wo Schlafen der Normalfall ist.

🐛 Der Verkehr findet ins lokale Netz zurĂŒck

Nach einem kurzen Aussetzer im WLAN konnte der Verkehr zwischen zwei GerĂ€ten im selben Netz auf dem Umweg ĂŒber den Router hĂ€ngen bleiben, obwohl der direkte Weg lĂ€ngst wieder da und mehr als doppelt so schnell war. Jetzt wechselt wave zurĂŒck, sobald der direkte Weg deutlich schneller ist.


đŸ§Ș Insiders v0.1.0-insiders.1 (28.09.2026)

Die erste Vorschau-Version: sie enthĂ€lt alles aus den Development-Builds bis v0.1.0-develop.28 und dazu die beiden Änderungen unten.

🐛 wave legt keinen Router mehr lahm

Ein GerĂ€t hinter einem NAT, das jeder Verbindung einen neuen Port gibt — ein Kubernetes-Knoten, ein Handy-Hotspot —, meldete jede Minute eine neue eigene Adresse und vergaß nie eine alte. Nach zwei Tagen waren es beim Connector gut 2600, und jedes andere GerĂ€t im Wave versuchte sie alle mehrmals pro Sekunde. Jeder dieser Versuche belegt auf dem Router davor einen Eintrag, und ein Heimrouter ist damit irgendwann voll: das Internet wird fĂŒr alle im Haus langsam oder bricht ab.

Jetzt verfallen solche Adressen nach wenigen Minuten, GerĂ€te vergessen Adressen, die ein anderes GerĂ€t nicht mehr meldet, und der Server gibt je GerĂ€t nur noch eine kleine Zahl weiter — auch fĂŒr GerĂ€te, die noch eine Ă€ltere Version fahren. Das gilt ebenso fĂŒr den Kern der Telefon-Apps.

🐛 Die ganze Zeile klappt die Dienste auf

Im Tray-Fenster unter macOS reagierte nur das kleine Dreieck auf einen Klick, nicht der Name und die Adresse daneben. Jetzt klappt die ganze Zeile auf.


🔬 Development v0.1.0-develop.28 (26.09.2026)

Die Dienste eines Clusters stehen jetzt ĂŒberall dort, wo auch die GerĂ€te stehen — und ein Klick öffnet sie.

✹ Dienste auf Klick, unter ihrem GerĂ€t

Ein Connector bringt so viele Namen mit, wie der Cluster Ingresse hat. In der WeboberflĂ€che standen sie bisher alle ausgeschrieben unter ihrem GerĂ€t und schoben die GerĂ€teliste aus dem Blick; auf dem GerĂ€t selbst — im Tray-Fenster und in wave status — gab es sie ĂŒberhaupt nicht zu sehen.

Jetzt klappt ein Klick auf ein GerĂ€t seine Dienste darunter auf, ein zweiter klappt sie wieder zu, und ein Klick auf einen Dienst öffnet ihn im Browser. Das gilt fĂŒr die WeboberflĂ€che und fĂŒr das Tray-Fenster auf allen drei Plattformen; welche GerĂ€te offen sind, ĂŒberlebt dabei die laufende Aktualisierung. GerĂ€te ohne Dienste bleiben, was sie waren.

wave status schreibt sie stattdessen eingerĂŒckt unter ihre Maschine — im Terminal gibt es nichts anzuklicken. Es ist auch die einzige Ansicht, die die Dienste des eigenen GerĂ€ts zeigt: wer den Client selbst als Connector fĂ€hrt, sah sie bislang nirgends.

🔗 Ein Link, ĂŒberall derselbe

Ob ein Dienst http oder https spricht, weiß nur der Cluster; unter welcher Domain er hĂ€ngt, nur der Wave. Beides weiß der Server — und er schreibt die Adresse jetzt einmal aus und schickt genau diese an alle: an den Browser, an jedes GerĂ€t, an die Shell. Vorher setzte sie sich jede Ansicht selbst zusammen, und vier Schreibweisen derselben Adresse sind vier Gelegenheiten, auseinanderzulaufen. Ein Dienst, der nur Klartext spricht, wird damit nirgends mehr als https-Link angeboten — ein Link, der ins Leere gefĂŒhrt hĂ€tte.


🔬 Development v0.1.0-develop.27 (26.09.2026)

Die GerÀteliste in der OberflÀche aktualisiert sich von selbst.

✹ GerĂ€te, Status und Dienste ohne Neuladen

Bisher zeigte die Übersicht den Stand vom Moment des Aufrufs: ein GerĂ€t, das sich gerade verband, eines, das dazukam oder entfernt wurde, ein Cluster, der andere Dienste meldete — nichts davon erreichte eine Seite, die schon offen war. Man hat neu geladen und nachgesehen.

Die Karte hĂ€ngt jetzt an einer laufenden Verbindung zum Control-Server und zeichnet neu, sobald sich etwas Ă€ndert: der Punkt neben einem GerĂ€t, die Zahl in „3 von 5 GerĂ€ten verbunden", die Liste selbst und die Dienste darunter.

Zu sehen bekommt man dabei nur die Waves, in denen man ist — wer aus einem Wave entfernt wird, sieht dessen GerĂ€te auch in einem offenen Tab nicht weiter. Reißt die Verbindung ab, sagt die Seite es und verbindet sich von selbst wieder; bis dahin steht dort der Stand vom Laden, statt still zu veralten.


🔬 Development v0.1.0-develop.26 (24.09.2026)

Das Tray-Fenster unter macOS geht wieder beim ersten Klick auf.

🐛 Die Karte unter macOS brauchte zwei Klicks

Wer das Fenster ĂŒber das Icon öffnete, danach woanders hin klickte und dann wieder aufs Icon, sah nichts passieren — erst der zweite Klick brachte die Karte zurĂŒck.

Dahinter steckte eine Karte, die sich nicht weggerĂ€umt hat. Sie sollte verschwinden, sobald man sich etwas anderem zuwendet, blieb aber stehen; der nĂ€chste Klick aufs Icon tat deshalb genau das, was ein Klick auf eine offene Karte tut — er hat sie geschlossen. Sie rĂ€umt sich jetzt selbst weg, sobald sie den Fokus verliert, und der Klick, der das ausgelöst hat, macht sie nicht im selben Atemzug wieder auf.


🔬 Development v0.1.0-develop.25 (23.09.2026)

Ein fremdes GerĂ€t kommt nicht mehr durch einen angeklickten Link in den Wave, und ein Telefon, das das Netz wechselt, bleibt ĂŒber das Relay erreichbar.

🔒 Ein GerĂ€t freizugeben ist ein Knopfdruck, nicht das Öffnen eines Links

Bisher genĂŒgte es, den Anmeldelink zu öffnen — damit war das GerĂ€t im Wave. Das reicht nicht: einen solchen Link bekommt jeder, der wave login gegen den Server laufen lĂ€sst, und dafĂŒr braucht es weder Konto noch Einladung. Danach genĂŒgte es, ein angemeldetes Mitglied auf den Link zu locken, und ein fremdes GerĂ€t saß im Wave — nachgestellt, mit Adresse, in jeder Netzkarte und auf jedem Interface.

Die Seite zeigt jetzt nur noch; aufgenommen wird das GerÀt erst mit dem Absenden des Formulars. Der eine eingesparte Klick war genau der, der den Schritt getragen hat. Gefragt wird dabei immer, auch wenn es nur einen Wave gibt.

🐛 Ein Telefon, das das Netz wechselt, bleibt ĂŒber das Relay erreichbar

Verband sich ein GerĂ€t neu — WLAN auf Mobilfunk, der Normalfall auf dem Telefon —, rĂ€umte die alte, zufallende Verbindung die gerade angelegte neue wieder weg. Zu sehen war davon nichts: das GerĂ€t galt weiter als verbunden, nur kam ĂŒber das Relay nichts mehr bei ihm an.

🛠 Weniger AngriffsflĂ€che in den Images

Ein AbhĂ€ngigkeits-Audit hat vier LĂŒcken aufgedeckt und alle sind zu: Release-Bau und Connector-Image stehen auf derselben, unterstĂŒtzten Go-Fassung wie der Rest des Repos; das Connector-Image schleppt keinen Compiler-Baum mehr mit, den nie jemand ausfĂŒhrt; und die Datenbankschicht ist auf eine Fassung ohne bekannte Schwachstelle gehoben.


🔬 Development v0.1.0-develop.24 (23.09.2026)

Einen Wave zu administrieren braucht im Container keinen Pfad in den Workspace mehr.

🛠 Die Operator-CLI liegt als Binary im Control-Image

wave-admin steht im Image auf dem PATH. Wer einen Wave administriert, tippt also docker exec <container> wave-admin members <wave> statt den Pfad in den Workspace — und kann das Binary aus dem Image herauskopieren und anderswo benutzen, weil alles darin steckt.

Aus dem Repo heraus Ă€ndert sich nichts: bun apps/control/src/admin.ts ist weiterhin dasselbe Programm, und die Hilfe nennt von selbst den Weg, ĂŒber den sie gerade aufgerufen wurde, statt auf ein Verzeichnis zu zeigen, das nicht da ist.


🔬 Development v0.1.0-develop.23 (23.09.2026)

wave lĂ€uft jetzt auch auf dem Telefon — jedenfalls ĂŒberall dort, wo es sich ohne Telefon nachweisen lĂ€sst —, und wer seine Domain bei IONOS oder INWX hat, bekommt seine Zertifikate ab jetzt ohne Handarbeit.

v0.1.0-develop.22 gibt es gar nicht. Der Tag existiert, aber der Lauf kam nicht bis zu den Images: die End-to-End-Tests scheiterten daran, dass der Go-Kern in einem Netz-Namespace gebaut wird, in dem es kein Netz gibt — und die dort eingestellte Go-Version war eine Ă€ltere, als der Kern verlangt, also wollte Go sich erst eine nachladen. Derselbe Inhalt trĂ€gt jetzt die .23.

đŸ“± Mobile: ein Go-Kern fĂŒr iOS und Android (D10 / M10)

Vom bisherigen Client lĂ€uft auf einem Telefon nichts: kein Bun.spawn fĂŒr wireguard-go, kein ip oder resolvectl, und die iOS-Tunnel-Extension ist bei rund 50 MB gedeckelt. Portabel ist allein der Vertrag. Neu ist deshalb ein gemeinsamer Kern in Go unter mobile/core, dazu die beiden Plattform-Hosts — NEPacketTunnelProvider in Swift, VpnService in Kotlin —, die absichtlich dĂŒnn bleiben: sie tun nur, was ausschließlich die Plattform kann.

  • Ein Tunnel, mehrere Waves. Beide Plattformen erlauben genau einen Tunnel je App. Also liegt unten ein GerĂ€t und darĂŒber je Wave ein eigenes WireGuard-Device, dazwischen ein Demultiplexer, der nach ZielprĂ€fix sortiert. Ein Telefon kann damit in zwei Waves gleichzeitig sein, mit getrennten SchlĂŒsseln — derselbe öffentliche SchlĂŒssel in jeder Netmap wĂŒrde sonst zwei Waves mit einem gemeinsamen Mitglied erlauben, das GerĂ€t wiederzuerkennen.
  • Ein UDP-Port fĂŒr alles. Der Loopback-Socket je Peer entfĂ€llt: als Bibliothek nimmt wireguard-go eine conn.Bind entgegen, und jede Wave bekommt davon eine Sicht, die nur ihre Pakete liefert. Ein Pfadwechsel fasst die WireGuard-Konfiguration weiterhin nie an — dort steht jetzt der Peer statt einer Adresse.
  • Ein Resolver mit Suffix-Tabelle, ohne eigenen Socket. Die Anfrage kommt als Paket auf dem Tunnel an und die Antwort geht genauso zurĂŒck, samt PrĂŒfsummen. PTR inklusive, damit ping <name> nicht acht Sekunden auf eine RĂŒckwĂ€rtsauflösung wartet, die niemand beantwortet.
  • Der Netzwechsel ist der Normalfall. WLAN → LTE löst sofort einen Rebind und neue Kandidaten aus, statt darauf zu warten, dass Peers unerreichbar werden. Das ist der Unterschied zwischen einer Pause, die niemand bemerkt, und zehn Sekunden ohne alles.
  • Zwei Waves dĂŒrfen sich weder Adressen noch SchlĂŒssel teilen. Auf einem gemeinsamen Socket entscheidet der AbsenderschlĂŒssel im Klartext, welcher Peer ein Disco-Paket geschickt hat — ein bösartiger Control-Server könnte sich sonst in das Nachschlagen einer fremden Wave hĂ€ngen. Die zweite Wave wird abgelehnt, und beide werden genannt.

Der Kern lĂ€uft an einem echten TUN. Zwei E2E-Skripte setzen genau den Code, der auf ein Telefon geht, auf ein echtes Tunnelinterface — die Gegenstelle ist jeweils der gewöhnliche Client, also wird zugleich ĂŒber die Implementierungsgrenze geprĂŒft. mobile-core.sh: ein Interface trĂ€gt zwei Waves, ein UDP-Port fĂŒr beide, ein Peer in jeder erreichbar, der Resolver antwortet ohne Socket fĂŒr beide Zonen, ein Neustart kommt mit denselben Adressen und demselben Port zurĂŒck. mobile-nat.sh: derselbe Kern hinter einem NAT puncht einen direkten Pfad, und hinter zwei symmetrischen NATs, wo Punching nicht gelingen kann, lĂ€uft der Verkehr ĂŒber das Relay. Damit ist abgedeckt, was M10 verlangt — zwei Waves gleichzeitig, direkter Pfad und Relay-Fallback.

Vier Fehler sind dabei aufgefallen, keiner an einem Unit-Test: ein Tunnel, der genau einmal hochkam und danach „bind is closed" meldete; ein Neustart, nach dem die Peers 15 Sekunden ins Leere sendeten; ein GerĂ€t mit zwei Waves, das die erste erreichte und die zweite nicht, bei bestĂ€tigten Pfaden zu beiden; und ein Absturz, sobald zum ersten Mal ein Relay im Spiel war.

🔎 Jeder Wave reserviert eine Adresse fĂŒr seinen Resolver

Die 53. seines Blocks. Der Allokator vergibt sie nie an ein GerĂ€t, und die Netmap schickt sie mit. Nötig ist das fĂŒr Clients, deren Resolver keinen eigenen Socket hat: erreicht wird er nur, wenn seine Adresse in den Tunnel geroutet und niemandem zugewiesen ist — eine Adresse, die das Interface hĂ€lt, beantwortet der Kernel lokal, wo nichts lauscht.

Das Feld ist dabei optional geworden statt vorbelegt: ein Wave, der vor der Reservierung nummeriert wurde, kann die Adresse lÀngst an einen Knoten vergeben haben, und dann bleibt sie weg, statt das DNS aller GerÀte auf ein GerÀt zu zeigen. Nebenbei ist damit eine Regelverletzung raus, die eine einwandfreie Netmap irgendwann als gefÀlscht hÀtte melden können: unterhalb von Netmap darf nichts einen Default haben.

Auf einem Telefon gelaufen ist nichts davon. Es gibt hier weder einen Mac noch ein Android-GerĂ€t; fĂŒr iOS fehlt zusĂ€tzlich das Xcode-Projekt und ein bezahlter Developer-Account, und der iOS-Simulator kann Network Extensions ohnehin nicht ausfĂŒhren. Derselbe Stand wie beim Windows-Tray: benannt, nicht verschwiegen.

🔑 Zwei weitere DNS-Provider: IONOS und INWX

set-dns-provider kennt jetzt vier statt zwei. Wer seine Domain bei IONOS oder INWX hat, bekommt damit unbeaufsichtigte Erneuerungen, statt fĂŒr jede einen TXT-Record von Hand anzulegen.

Die beiden Neuen sind nicht dieselbe Sorte Zugangsdaten wie die beiden Alten, und das ist beim Einrichten zu wissen:

  • IONOS meint hier Hosting DNS — die gewöhnliche Domain bei ionos.de — und nicht IONOS Cloud DNS. Getrennte Produkte mit getrennten APIs; der Key des einen ergibt beim anderen 401. Der Zugang ist ein API-Key der Form <public prefix>.<secret>.
  • INWX hat keinen Token, der sich auf eine Zone einschrĂ€nken ließe: es meldet sich mit Benutzername und Passwort an, bei aktiver Zwei-Faktor-Auth zusĂ€tzlich mit einem TOTP-Code, fĂŒr den das Shared Secret hinterlegt wird. Diese Zugangsdaten können alles, was das Konto kann — ein Sub-Account nur fĂŒr diese Domain ist die einzige Art, das einzugrenzen, und set-dns-provider sagt das beim Abfragen. Abgelegt wird die Angabe als JSON in derselben versiegelten Spalte wie ein Token.

WAVE_DNS_SECRET gilt unverĂ€ndert fĂŒr beide: ohne den Wert wird nichts gespeichert. Und set-dns-provider probiert die Zugangsdaten weiterhin sofort gegen die echte Zone — was nicht schreiben kann, wird nicht behalten.

GeprĂŒft ist das gegen nachgebaute APIs, nicht gegen die echten: die Sitzung von INWX samt Ablauf und zweitem Faktor, die AnfĂŒhrungszeichen, in denen IONOS seine TXT-Werte zurĂŒckgibt, und fĂŒr beide der Fall, auf den es ankommt — ein Wildcard-Auftrag und sein Apex schreiben denselben Recordnamen mit verschiedenen Werten, und keiner darf den anderen wegrĂ€umen.


🔬 Development v0.1.0-develop.21 (22.09.2026)

Das Tray-Icon ist unter Windows nach dem Install sofort da, und der Link zu einem Dienst fĂŒhrt endlich dorthin, wo er hinfĂŒhren soll.

v0.1.0-develop.20 gibt es nicht zum Herunterladen. Der Tag existiert, und control und relay liegen unter dieser Nummer auf der Registry, aber der Lauf kam nicht bis zum Release: der Speicher der Organisation war voll, und damit schlug das Hochladen der Client-Archive fehl. Was dort hineingehört hĂ€tte, steht hier. Wer develop fĂ€hrt, holt sich .21 — dort stimmen alle vier Images wieder ĂŒberein.

Neue Funktionen

  • Unter Windows steht das Tray-Icon direkt nach wave install da. Bisher wurde dort nur ein Anmelde-Task registriert — das Icon kam also erst beim nĂ€chsten Ab- und Anmelden, oder man startete wave tray von Hand, und der Schlusshinweis musste genau das zugeben. Jetzt startet es sofort, so wie es launchd und systemd auf den anderen beiden ohnehin tun. Es bleibt ein optionaler Schritt: ein Eingabeaufforderungs-Fenster als Administrator eines anderen Kontos kann keine fremde Sitzung bespielen, und ein Icon, das nicht startet, ist kein Tunnel, der gescheitert ist.
  • Das Icon verschwindet nicht mehr nach drei Tagen. Der Aufgabenplaner beendet eine Aufgabe ohne ausdrĂŒckliche Zeitangabe nach drei Tagen, und auf einem Laptop ließ er sie im Akkubetrieb meist gar nicht erst starten — beides Voreinstellungen, die sich nur ĂŒber eine Definitionsdatei abschalten lassen, und beides Fehlerbilder, die man morgens ohne Anhaltspunkt vorfindet. Ein Absturz fĂŒhrt jetzt außerdem zu einem Neustart statt zum Ende.
  • Der Link zu einem Dienst spricht das Protokoll seines Ingress. Die OberflĂ€che baute jede Dienstadresse als https, und bei einem Cluster, der einen davon im Klartext ausliefert, ging der Link ins Leere. Ob TLS beendet wird, weiß nur der Cluster — es hĂ€ngt am Ingress beziehungsweise am Listener des Gateways —, und er sagt es jetzt: OberflĂ€che und admin.ts services bauen den Link daraus. Wird ein Name ĂŒber beide Wege bedient, gewinnt https.

Wichtig zu wissen

  • Eine Version entsteht erst, wenn der Tunnel im Test wirklich hochkommt. Die End-to-End-Tests — zwei Knoten im Tunnel, ein GerĂ€t in zwei Waves, Hole Punching durch zwei NATs, RĂŒckfall aufs Relay — laufen jetzt im Release-Lauf und halten Images und Binaries auf. Vorher liefen sie neben dem Release auf Pull Requests, konnten also rot sein, wĂ€hrend eine Version herausging. Der Preis dafĂŒr steht in derselben Zeile: auf einen Push oder Pull Request reagiert nichts mehr, PrĂŒfungen vor dem Commit sind damit Handarbeit.

🔼 Development v0.1.0-develop.19 (21.09.2026)

Ein GerÀt bekam die Adresse eines Dienstes -- und unter Windows kam daraufhin gar kein Tunnel mehr hoch.

Fehlerbehebungen

  • Ein neues GerĂ€t konnte die Adresse eines Dienstes bekommen. GerĂ€te und Dienste teilen sich in einem Wave eine Nummerierung, aber nur die Dienste wurden mit Blick auf beide Seiten vergeben. Ein GerĂ€t, das nach einem Dienst dazukam, landete deshalb womöglich auf dessen Adresse -- und das fiel nicht dort auf, sondern auf ebendiesem GerĂ€t, als etwas, das nach Netz aussieht: Der Tunnel kam nicht hoch, weil die Route fĂŒr diese Adresse mit der eigenen Adresse kollidierte. Neue GerĂ€te bekommen jetzt Adresse und Namen, die noch niemand hĂ€lt; ein GerĂ€t kann sich damit auch nicht mehr so nennen wie ein Dienst.
  • Unter Windows scheiterte der Start an einer Route, die schon da war. Windows legt zu jeder Adresse eines Adapters selbst eine Route an. Der Client zĂ€hlte die nicht mit, legte sie ein zweites Mal an, und die Absage darauf brach den ganzen Start ab. Angelegt wird jetzt nur, was fehlt.
  • Ein gescheiterter Start rĂ€umt hinter sich auf. Vorher blieben Interface, Port, Adressen und Routen liegen; der nĂ€chste Versuch scheiterte dann an den Resten des vorigen statt an dem, was wirklich schiefging -- unter Windows dauerhaft, weil eine liegengebliebene Route dort jeden weiteren Versuch abweist.

🔬 Development v0.1.0-develop.18 (21.09.2026)

Windows holt beim Tray auf.

Neue Funktionen

  • Das Tray-Fenster gibt es jetzt auch unter Windows. Ein Linksklick aufs Icon öffnet dieselbe Karte, die Linux und macOS schon zeigen: oben der GerĂ€tename, darunter jeder Wave mit einem eigenen Schalter zum Verbinden und Trennen, darunter die Maschinen mit Adresse, Namen und dem Weg, ĂŒber den sie gerade erreicht werden — samt Knopf, der den Namen in die Zwischenablage legt. Vorher fiel der Linksklick dort ins Leere und alles hing am MenĂŒ der rechten Maustaste; das gibt es unverĂ€ndert weiter. Das Fenster verschwindet, sobald man sich etwas anderem zuwendet, und auf Escape.

    UngeprĂŒft auf echter Hardware — hier steht keine Windows-Maschine. GeprĂŒft ist, wo jedes Element landet und was ein Klick darauf auslöst.


🔬 Development v0.1.0-develop.17 (21.09.2026)

Fehlerbehebungen

  • Die Ereignisliste des Clients ist wieder brauchbar. Sie bestand zuletzt fast nur aus socket error (ignored): unknown — einer Meldung ohne Inhalt, die im Sekundentakt kam und die acht Zeilen verdrĂ€ngte, fĂŒr die die Liste da ist. Ursache sind ICMP-Ablehnungen von Adressen, die ein Peer angeboten hat und die von hier aus nicht erreichbar sind; das ist normal. Sie werden jetzt gezĂ€hlt, und höchstens einmal pro Minute steht dort, wie viele es waren.

🔬 Development v0.1.0-develop.16 (21.09.2026)

Zwei kleine Dinge in der OberflÀche, die vorher fehlten.

Neue Funktionen

  • Ein Dienst ist jetzt anklickbar. Unter dem Connector steht seine Adresse als vollstĂ€ndige URL und fĂŒhrt direkt dorthin — erreichbar fĂŒr jeden im Wave und fĂŒr sonst niemanden, denn außerhalb löst der Name nicht einmal auf.
  • Der Name eines Waves lĂ€sst sich Ă€ndern, von EigentĂŒmer und Administratoren, in der Wave-Karte ĂŒber der Domain. Das ist der billige Schritt: kein GerĂ€t kennt den Namen, es muss also auch keines etwas ĂŒbernehmen. Anders als beim Wechsel der Domain, bei dem jedes GerĂ€t eine neue Netzkarte braucht.

🔬 Development v0.1.0-develop.15 (21.09.2026)

Die Dienste eines Clusters sind jetzt auch zu sehen — und der Weg dorthin funktioniert im echten Cluster.

Neue Funktionen

  • Die OberflĂ€che zeigt die Dienste eines Connectors. Unter dem GerĂ€t stehen die Namen, die es beantwortet, mit ihrer Adresse im Wave; am GerĂ€tenamen sagt ein Abzeichen, wie viele es sind. Vorher sah ein Connector aus wie eine Maschine, die beigetreten ist und seitdem nichts tut — die Dienste waren in der Netzkarte, in den Routen und im Resolver, nur nirgends zu sehen.

Fehlerbehebungen

  • Der interne Ingress-Controller antwortete auf alles mit 404. Ihm fehlte ein Leserecht, ohne das er seine Konfiguration nie veröffentlicht — und das stand nirgends im Log, sondern nur als wiederholter Rechte-Fehler zu einer Ressource, die mit Ingresses nichts zu tun hat.

🔬 Development v0.1.0-develop.14 (21.09.2026)

Das erste Mal, dass ein Cluster wirklich einen Dienst in einen Wave gestellt hat — und die Fehler, die dabei sichtbar wurden.

Fehlerbehebungen

  • Ein Dienst aus dem Cluster war nicht erreichbar. Name und Adresse kamen an, jedes GerĂ€t hatte die Route, und trotzdem antwortete nichts: Der Connector hielt die Adressen seiner Dienste fĂŒr seine eigenen und leitete sie deshalb nicht weiter — das Paket blieb bei ihm liegen. Aufgefallen ist das erst im echten Cluster, weil es den Fehler ohne Dienste gar nicht gibt.

Neue Funktionen

  • Die Clusterseite bringt ihren eigenen Ingress-Controller mit (Traefik, Klasse wave, nur ClusterIP), und davor eine Regel, die nur den Connector durchlĂ€sst. Erst das macht „nur aus dem Wave erreichbar" wahr: wave kann einen Dienst erreichbar machen, unerreichbar machen muss der Cluster. Wer schon einen internen Controller hat, nimmt diesen heraus.
  • Der Connector behĂ€lt seine Anmeldung. Er lĂ€uft als StatefulSet mit einem Volume, heißt dauerhaft wave-connector-0 und hinterlĂ€sst nicht mehr bei jedem Rollout ein weiteres GerĂ€t in der Wave, um das sich jemand kĂŒmmern muss.

🔬 Development v0.1.0-develop.13 (21.09.2026)

Das Kustomize-Setup ist einmal auf einem echten Cluster gelaufen — und das hat es verĂ€ndert.

Neue Funktionen

  • Die Datenbank gehört zum Setup. deployment/server bringt Postgres mit, statt es als Zusatz anzubieten: ein Wave braucht eine Datenbank, und eine optionale hieß, dass jedes Overlay daran denken muss. Was ein einzelner Pod mit einem Volume nicht kann — Backup, Failover, Point-in-Time-Restore —, steht dort, wo er definiert ist; der Patch, der ihn fĂŒr einen verwalteten Dienst wieder herausnimmt, liegt im Prod-Overlay bereit.
  • Zugang zu den privaten Images. Jeder Pod nennt ein Image-Pull-Secret, und jedes Overlay erzeugt es aus einer dockerconfig.json neben seiner kustomization.yaml — bisher konnte nur ziehen, wer die Images öffentlich hatte.
  • STUN ohne Load Balancer. Wo die Plattform kein UDP ĂŒber ihren Load Balancer trĂ€gt — bei Hetzner etwa —, geht STUN im Prod-Overlay direkt ĂŒber einen hostPort auf den Knoten. Das ist sogar der bessere Weg: ohne kube-proxy im Pfad kann nichts die reflexive Adresse verfĂ€lschen. Der Preis steht daneben: der Pod ist damit an den Knoten gebunden, dessen Adresse die GerĂ€te kennen.

Fehlerbehebungen

  • Der Relay startete in Kubernetes gar nicht. Ein Service namens wave-relay lĂ€sst Kubernetes die alte Docker-Link-Variable WAVE_RELAY_PORT=tcp://
 setzen — und genau daraus liest der Relay seinen Port. Er endete mit „options.port 
 Received NaN", bevor er lauschte. Diese Variablen sind jetzt in allen Pods abgeschaltet; gefunden wird hier alles ĂŒber DNS.
  • Das dokumentierte kubectl exec zum Anlegen eines Kontos brauchte -it. admin.ts set-password fragt das Passwort auf stdin ab; ohne Terminal bekam es eine leere Pipe und schob es auf die PasswortlĂ€nge.

🔬 Development v0.1.0-develop.12 (21.09.2026)

Ein Wave stellt jetzt Zertifikate auf seine GerĂ€tenamen aus, nimmt die Dienste eines Kubernetes-Clusters auf — und lĂ€sst sich selbst auf Kubernetes betreiben.

Neue Funktionen

  • GĂŒltige Let's-Encrypt-Zertifikate auf GerĂ€tenamen. wave cert holt fĂŒr ein GerĂ€t ein Zertifikat auf seinen Namen im Wave; der Dienst erneuert es von da an unbeaufsichtigt, in dem Fenster, das die CA vorschlĂ€gt (ARI), sonst bei zwei Dritteln der Laufzeit. --hook 'systemctl reload caddy' sagt, was danach neu geladen werden soll, wave certs zeigt, was das GerĂ€t hĂ€lt.
  • Der Control-Server schreibt in die Zone des Waves. Ein auf die Zone beschrĂ€nkter API-Token — Cloudflare oder Hetzner — wird einmal je Wave hinterlegt (admin.ts set-dns-provider) und beim Hinterlegen sofort ausprobiert; genau dieser Schreibtest ist zugleich die Domain-Verifikation. Gespeichert wird der Token nur verschlĂŒsselt (WAVE_DNS_SECRET).
  • Oder von Hand, bei jedem Hoster (set-dns-provider <wave> manual). wave cert druckt dann den TXT-Record, den es braucht, und wartet darauf; sobald er in der Zone steht, lĂ€uft die Ausstellung weiter. Nachgesehen wird bei den autoritativen Nameservern der Zone, damit ein Resolver, der die Abwesenheit des Records gecacht hat, nicht eine Stunde lang blockiert. Ctrl-C ist dabei ungefĂ€hrlich: derselbe Auftrag wird beim nĂ€chsten wave cert weitergefĂŒhrt.
  • Ein Kubernetes-Cluster kann Dienste in den Wave stellen (D11). Ein Ingress mit ingressClassName: wave bekommt einen Namen und eine eigene Adresse im Wave; erreichbar ist er dann genau ĂŒber den Wave und sonst nirgends. DafĂŒr gibt es apps/connector (hĂ€lt den Tunnel, leitet weiter) und apps/operator (liest die Ingresses) samt Manifesten in deployment/cluster/. Im Cluster gefahren wurde das noch nicht.
  • Kustomize-Setup fĂŒr den ganzen Stapel (deployment/): Control-Server, Frontend und Relay in deployment/server, Connector und Operator in deployment/cluster — zwei BĂ€ume, weil sie in verschiedenen Clustern laufen. Dazu veröffentlicht ein Release jetzt auch die Images web und connector, nicht mehr nur control und relay.
  • Pre-Auth-Keys (admin.ts auth-key <wave>, wave login --auth-key): Enrolment ohne Browser, fĂŒr Maschinen, an denen niemand sitzt. Einmalig, ablaufend und widerrufbar, auf Wunsch wiederverwendbar.
  • Ein Wave lĂ€sst sich löschen — vom EigentĂŒmer, und nur mit getipptem Namen. Jeder andere Schnitt ist umkehrbar, dieser nicht: jedes GerĂ€t verliert seine Anmeldung, die Adressen fallen zurĂŒck und die Domain wird wieder frei. Auf der Shell heißt es admin.ts delete-wave <wave> und nennt vorher, wie viele GerĂ€te und Mitglieder daran hĂ€ngen.

Wichtig zu wissen

  • Ein Dienst ist eine Adresse, kein Knoten. Er hat keine SchlĂŒssel und ist kein WireGuard-Peer: seine Adresse steht in den allowedIps des Connectors, und damit routet ihn jedes GerĂ€t, ohne etwas Neues zu lernen.
  • Der private SchlĂŒssel entsteht auf dem GerĂ€t und bleibt dort. Zum Server geht nur der Zertifikatsantrag, zurĂŒck kommt die öffentliche Kette — und kein GerĂ€t bekommt je ein DNS-Token, denn wer _acme-challenge schreiben darf, darf die ganze Zone schreiben.
  • Ausgestellt wird auf den eigenen GerĂ€tenamen. Ein Wave unter dem Platzhalter .internal bekommt prinzipiell keines — dafĂŒr muss erst eine eigene Domain eingetragen sein.
  • Ein Wildcard braucht die Freigabe des Betreibers (admin.ts allow-wildcard <wave> <gerĂ€t>), dann holt ihn wave cert --wildcard samt dem Namen der Zone selbst. Der Grund fĂŒr die Freigabe: *.wave.example.com gehört keinem GerĂ€t, sondern allen — wer den SchlĂŒssel hĂ€lt, kann jeder Name im Wave sein. Gedacht ist er fĂŒr eine Maschine mit mehreren Diensten; auf mehrere verteilt wĂ€re er das Gegenteil von dem, wofĂŒr der Rest gebaut ist. ZurĂŒcknehmen geht mit deny-wildcard.
  • Von Hand heißt auch: Erneuerung von Hand. Der Dienst meldet dann, welcher Record fehlt, und versucht es spĂ€ter wieder — unbeaufsichtigt erneuert nur, wer einen Provider-Token hinterlegt hat.
  • Vorgabe ist das Staging-Verzeichnis von Let's Encrypt. Auf die echte Ausstellung schaltet WAVE_ACME_DIRECTORY um; deren Rate Limits verbrennt ein Fehlversuch fĂŒr eine Woche.
  • Jeder ausgestellte Name landet dauerhaft in den öffentlichen CT-Logs. Deshalb wird nur auf Zuruf ausgestellt und nicht fĂŒr jedes GerĂ€t automatisch.

🔬 Development v0.1.0-develop.6 (17.09.2026)

Die Domain eines Waves gehört jetzt seinem EigentĂŒmer — sie wird beim Anlegen angegeben statt vergeben.

Neue Funktionen

  • Beim Anlegen eines Waves wird nach Name und Domain gefragt. Der erste Login legt kein Netz mehr ungefragt an: er fĂŒhrt auf ein Formular, und erst das Absenden erzeugt den Wave. Vorbelegt ist <name>.wave.internal — wer keine eigene Domain hat, behĂ€lt das einfach und Ă€ndert nichts an seinem Vorgehen.
  • Eine eigene Domain benennt die GerĂ€te. TrĂ€gt man dort wave.example.com ein, heißt der Laptop laptop.wave.example.com. Das ist der Schritt, ohne den es spĂ€ter kein öffentliches HTTPS-Zertifikat auf einen GerĂ€tenamen geben kann: fĂŒr die Platzhalter-Domain *.wave.internal ist das grundsĂ€tzlich nicht möglich, weil sie niemandem gehört. Die Zertifikate selbst gibt es weiterhin nicht — nur die Voraussetzung dafĂŒr.
  • Die Domain lĂ€sst sich spĂ€ter wechseln, in der Wave-Karte der OberflĂ€che fĂŒr EigentĂŒmer und Administratoren, auf der Shell des Servers mit admin.ts set-domain <wave> <domain>. Verbundene GerĂ€te ĂŒbernehmen die neuen Namen mit der nĂ€chsten Netzkarte. Zu wissen ist dabei: der Wechsel benennt jedes GerĂ€t im Wave um.
  • wave status bleibt offen und zeichnet mit. Pfad, Laufzeit und das Alter des letzten Handshakes aktualisieren sich im Sekundentakt, bis Strg-C — diese Werte sagen erst etwas, wenn man sie sich bewegen sieht. FĂŒr Skripte und die einzelne Momentaufnahme gibt es weiterhin wave status --once, und am Rohr verhĂ€lt sich das Kommando unverĂ€ndert.

Fehlerbehebungen

  • Es entsteht kein Wave mehr, den niemand bestellt hat. Weil die Anmeldung selbst keinen anlegt, kann auch keiner nebenbei entstehen — etwa wenn man sich anmeldet, bevor man eine Einladung in ein fremdes Netz öffnet. Vorher entschied die Reihenfolge zweier Klicks, ob man hinterher einen Wave zu viel hatte.
  • Eine schon belegte Domain wird benannt, nicht mit einem Serverfehler quittiert. Zwei Waves können nicht dieselbe Zone beantworten; der Versuch scheiterte bisher unverstĂ€ndlich, jetzt sagt die Seite, was los ist.
  • Das erste GerĂ€t eines frischen Kontos lĂ€uft nicht mehr ins Leere. wave login fĂŒhrt durch Anmeldung, Wave-Formular und GerĂ€tefreigabe hindurch; vorher endete die Freigabe mit einer Fehlermeldung, weil es noch kein Netz gab, in das das GerĂ€t gehört hĂ€tte.

🔬 Development v0.1.0-develop.5 (17.09.2026)

Neue Funktionen

  • Ein einzelnes GerĂ€t lĂ€sst sich entfernen, ohne das Mitglied mit hinauszuwerfen — fĂŒr die Maschine, die verloren, verkauft oder irgendwo stehen geblieben ist, also gerade die, auf der wave logout niemand mehr ausfĂŒhren kann. In der GerĂ€teliste steht dafĂŒr ein Knopf, sichtbar fĂŒr EigentĂŒmer und Admins; auf der Shell des Servers gibt es admin.ts devices <wave> und admin.ts remove-device <wave> <name|id>. Das entfernte GerĂ€t wird dabei getrennt, nicht bloß vergessen.

Fehlerbehebungen

  • Die Verbindung zu einem Peer wechselt nicht mehr stĂ€ndig zwischen direkt und Relay. Über WLAN schwankt die gemessene Laufzeit desselben Pfades leicht zwischen 14 und 110 ms; entschieden wurde bisher auf der letzten Messung, und damit wechselte der Pfad bei fast jeder Sondierung. Jetzt zĂ€hlt ein gleitender Mittelwert, und der Pfad, der den Verkehr schon trĂ€gt, gibt ihn nur an einen deutlich besseren ab. Von einem Pfad, der nicht mehr antwortet, fĂ€llt der Verkehr weiterhin sofort herunter.

🔬 Development v0.1.0-develop.4 (17.09.2026)

Behebt, dass wave login den Freigabe-Link nicht mehr anzeigte.

Fehlerbehebungen

  • wave login zeigt den Freigabe-Link wieder an. Lief ein Dienst, gab das Kommando gar nichts aus und wartete bis zu 15 Minuten stumm — ausgerechnet auf das Öffnen des Links, den es hĂ€tte anzeigen sollen. Unter Windows fiel das ab v0.1.0-develop.3 auf, weil es dort erstmals einen laufenden Dienst gibt; unter Linux und macOS betraf es jeden, der den Dienst installiert hatte.
  • wave up sagt jetzt, wenn es etwas ablehnt. Wurde ein Wave nicht eindeutig benannt oder war die Adresse keine, entschied der Dienst das fĂŒr sich und die Ausgabe schwieg dazu.

🔬 Development v0.1.0-develop.3 (17.09.2026)

Macht den Windows-Client einrichtbar — bisher ließ er sich ĂŒberhaupt nicht in Betrieb nehmen — und legt jedem Archiv bei, was der Tunnel braucht.

Nichts mehr nachinstallieren

  • wireguard-go liegt jetzt in jedem Archiv bei, fĂŒr Linux, macOS und Windows in der jeweils passenden Architektur; unter Windows zusĂ€tzlich wintun.dll. wave install legt beides neben das Binary — der Dienst lĂ€uft als root beziehungsweise LocalSystem und findet nichts, was nur im PATH des Benutzers steht. Das go install golang.zx2c4.com/wireguard@latest aus der Einrichtung entfĂ€llt damit.
  • Fehlt eine der beiden Dateien, sagt wave install es und endet mit einem Fehler, statt eine Einrichtung zu melden, aus der kein Tunnel werden kann.

Windows

  • Der Client lĂ€sst sich einrichten und trĂ€gt einen Tunnel. Bisher scheiterte wave login mit „Diese Sicherheitskennung kann nicht als Besitzer des Objekts zugeordnet werden", und wave install legte einen Dienst an, der nie startete. Beides hatte dieselbe Ursache: der Tunnel muss als LocalSystem laufen, und ein Prompt „als Administrator" genĂŒgt dafĂŒr nicht.
  • Eingerichtet wird jetzt eine geplante Aufgabe statt eines Dienstes. Sie lĂ€uft als LocalSystem beim Systemstart und kommt nach einem Absturz von selbst wieder. Nachsehen lĂ€sst sie sich mit schtasks /query /tn "wave daemon", nicht in services.msc. Beim Beenden werden die Waves erst ordentlich abgebaut, damit keine DNS-Regeln in der Registry zurĂŒckbleiben.
  • wave install sagt jetzt, wenn etwas schiefgegangen ist. Zuvor meldete es „installed and running" und endete erfolgreich, auch wenn jeder einzelne Schritt gescheitert war — und die Fehlermeldungen der Windows-Werkzeuge kamen als nackte Zahlen heraus.

Was weiterhin fehlt

Die Liste aus v0.1.0-develop.1 gilt unverĂ€ndert, bis auf den ersten Punkt: wireguard-go und wintun.dll liegen jetzt bei. Der Windows-Client ist weiterhin nie auf echter Hardware gelaufen — auch das hier Beschriebene ist geprĂŒft, soweit sich das ohne Windows-Maschine prĂŒfen lĂ€sst.


🔬 Development v0.1.0-develop.1 (17.09.2026)

Die erste Version ĂŒberhaupt. Sie ist zum Ausprobieren gedacht, nicht fĂŒr den Dauerbetrieb — siehe „Was noch fehlt" am Ende dieses Abschnitts.

Das Netz

  • GerĂ€te finden sich selbst und verbinden sich direkt. Jedes GerĂ€t meldet sich bei einem Control-Server an und bekommt eine signierte Netzkarte; den Tunnel bauen die GerĂ€te danach untereinander auf, ohne dass Verkehr ĂŒber den Server lĂ€uft.
  • Auch hinter NAT, ohne Portfreigabe. Zwei GerĂ€te hinter getrennten Routern stanzen sich gegenseitig einen Weg; keine Konfiguration am Router nötig.
  • Relay als RĂŒckfallebene. Wo ein direkter Weg unmöglich ist — etwa hinter symmetrischem NAT — lĂ€uft die Verbindung ĂŒber ein Relay, verschlĂŒsselt wie jede andere. Taucht spĂ€ter doch ein direkter Weg auf, wird ohne Abriss umgeschaltet.
  • Namen statt Adressen. ping laptop findet das GerĂ€t im eigenen Wave. RĂŒckwĂ€rtsauflösung inklusive, damit nichts mehr auf Namensabfragen wartet, die niemand beantwortet. Nur die Namen des Waves werden umgeleitet, die ĂŒbrige Namensauflösung des Rechners bleibt unangetastet.

Anmelden und verwalten

  • Anmeldung im Browser, per Passwort oder ĂŒber einen OIDC-Anbieter.
  • Mehrere Menschen in einem Wave. Rollen (EigentĂŒmer, Admin, Mitglied), Einladungen per einmaligem Link, und das Entfernen eines Mitglieds nimmt dessen GerĂ€te mit.
  • WeboberflĂ€che fĂŒr GerĂ€te, Waves, Mitglieder und Einladungen.
  • Ein GerĂ€t kann in mehreren Waves gleichzeitig sein — etwa einem privaten und einem beruflichen, auf verschiedenen Servern, mit getrennten SchlĂŒsseln.

Auf dem eigenen Rechner

  • Ein einziges Binary fĂŒr alles: wave up, wave status, wave login, wave profiles, dazu Dienst und Tray-Icon. wave install richtet die Maschine ein, beigetreten wird danach mit wave login <server-url>.
  • Tray-Icon unter Linux und macOS, mit einem Fenster, in dem sich jeder Wave einzeln schalten lĂ€sst.
  • Windows ist neu dazugekommen: Tunnel, Adressen, Routen, Split-DNS, Windows-Dienst und Tray-Icon.
  • Fertige Binaries hĂ€ngen an diesem Release — Linux, macOS und Windows, jeweils fĂŒr amd64 und arm64, mit PrĂŒfsummen.
  • Server als Container-Images fĂŒr Control und Relay, fĂŒr amd64 und arm64.

Was noch fehlt

  • wireguard-go wird nicht mitgeliefert und muss vorhanden sein (go install golang.zx2c4.com/wireguard@latest oder das Paket der Distribution). Unter Windows zusĂ€tzlich wintun.dll.
  • Der Windows-Client ist nie auf echter Hardware gelaufen. Er ist gebaut und geprĂŒft, soweit sich das ohne Windows-Maschine prĂŒfen lĂ€sst — mehr nicht. Unter Windows fehlt außerdem das Fenster hinter dem Tray-Icon; dort trĂ€gt das MenĂŒ alles.
  • Keine Zugriffsregeln. Alle GerĂ€te aller Mitglieder eines Waves sehen sich gegenseitig.
  • Keine Zertifikate und keine automatische Domain-Einrichtung. Namen funktionieren im Wave, öffentliche Zertifikate dafĂŒr gibt es noch nicht.
  • Keine Clients fĂŒr iOS und Android. Wie sie gebaut wĂŒrden, ist entschieden und dokumentiert, gebaut sind sie nicht.

Release-Prozess

Features durchlaufen die Phasen sequentiell, bevor sie alle Nutzer erreichen:

🔬 Development  →  đŸ§Ș Insiders  →  ✅ Stable
   (Vorabbau)      (Early Adopter)   (Alle Nutzer)
PhaseZielgruppeBeschreibung
🔬 DevelopmentEntwicklerVorabbau zum Ausprobieren. Kann kaputt sein.
đŸ§Ș InsidersEarly AdopterVorschau-Version zum Testen vor dem Stable-Release.
✅ StableAlle NutzerProduktionsreife Version.

Hinweis: Jeder Abschnitt listet nur die Änderungen, die neu in dieser Phase sind.