Reach your devices from anywhere.Through your own server.
At the office, at home or on the road: wave-mesh connects laptops, servers, NAS boxes and clusters directly over WireGuard, even behind NAT and without port forwarding. You run the coordination server yourself, and it never sees a private key.
Every path is direct. The devices found each other through their NATs.
- Linux
- macOS
- Windows
- Kubernetes
- iOSin progress
- Androidin progress
One binary for Linux, macOS and Windows, each on amd64 and arm64.
On the network in three steps
A wave is a network. You start the server once; after that every device needs two commands.
Read the full guideStart the control server
Control server, relay and Postgres via Kustomize in your own Kubernetes cluster; a single server with k3s is enough. The server hands out addresses, names and rules.
$ cd deployment/server/overlays/mywave$ kubectl apply -k .Install the client
A single binary from the releases page.
installsets up the service and tray icon; day-to-day use needs nosudoafter that.$ sudo ./wave installLog in and connect
wave loginnames your server and prints a link to log in. From then on the device finds every other device in the wave on its own, and it can join as many waves as you like.$ wave login https://control.example.com$ wave up
What a wave does
Direct whenever possible
Each device learns its public address over STUN, and both sides punch through their NAT at the same moment. When that fails, say behind symmetric NAT on mobile data, traffic goes through a relay. When the direct path opens up, the connection switches over without dropping.
Covered by end-to-end tests through real NATs that run in CI.
wave0 10.77.0.2
name laptop.wave.example.com
dns *.wave.example.com
relay connected wss://relay.example.com
PEER ADDRESS PATH HANDSHAKE
nas 10.77.0.3 direct 192.168.1.20:41641 3ms 12s ago
workstation 10.77.0.4 via relay 61ms 8s ago
cluster 10.77.0.9 direct 203.0.113.7:41641 18ms 31s ago
↳ https://grafana.wave.example.com 10.77.128.1
wave 0.4.0Names under your domain
Give a wave a DNS suffix you own, and your devices are called laptop.wave.example.com instead of 10.77.0.5. A local resolver answers only the wave's names; everything else goes to your usual DNS untouched.
- laptop.wave.example.com10.77.0.2connected
- nas.wave.example.com10.77.0.3connected
- workstation.wave.example.com10.77.0.4connected
- build-runner.wave.example.com10.77.0.73 hours ago
Real certificates for every device
Every device gets a Let's Encrypt certificate for its name. The private key is created on the device and never leaves it. Renewal runs unattended via Cloudflare, Hetzner, IONOS or INWX. Without credentials it still works; you then add the TXT record yourself.
$ wave cert
This wave answers dns-01 by hand, so laptop.wave.example.com needs a record first:
name _acme-challenge.laptop.wave.example.com
type TXT
value 0Zq8…
Waiting... Ctrl-C is safe: `wave cert` takes the same order up again.Access as a graph
Members, groups, tags and services sit side by side as cards. A rule is an arrow, and the ports hang off the edge. The page shows who can reach whom before you save.
Services from your cluster
A plain Ingress with the class wave makes an internal service reachable inside the wave and nowhere else. The connector in the cluster has no inbound port.
Signed updates
The service installs new versions on its own, but only with a valid Ed25519 signature. If the new build cannot reach a server, it rolls itself back.
Several waves per device
A laptop can be in your company's wave and your own at the same time. If their addresses overlap, the client refuses the second wave instead of silently overwriting a route.
What the server knows, and what it doesn't
wave-mesh keeps three layers strictly apart. The control server only hands out public keys, and the relay only forwards ciphertext. Neither can decrypt the traffic between your devices.
| Layer | Job | Knows private keys |
|---|---|---|
| Control server | Identity, authorization, network map, DNS | no |
| Relay | Reflect addresses, forward ciphertext | no |
| Device | WireGuard tunnel, local configuration | only its own |
Signed network map
The control server signs the network map with its Ed25519 key, and devices only accept what matches.
Authenticated discovery
Even the packets devices use to find each other are encrypted: X25519 and XChaCha20-Poly1305.
Login you control
Email and password with Argon2id, or Google sign-in. The operator creates accounts; there is no open sign-up.
What it costs
wave-mesh is licensed under the Elastic License 2.0. Running it yourself is free and stays free.
Run it yourself
€0no device limit
Every feature, on your own infrastructure. Use it, change it and run it inside your company.
- Control server and relay
- Clients for every platform
- Updates through your server
Run by us
€4per user per month
We run the control server and relays; you just connect devices. Let us know if you want in.
- Control server and relays run by us
- Updates and backups included
- Your own domain for your devices
Installation in your cloud
€4,650one-off
We install wave-mesh in your company's cloud. Afterwards, an optional maintenance package covers updates and operations.
- Control server and relays in your cloud
- Your clusters and devices connected
- Optional: maintenance package for updates and operations
Offers for businesses. All prices exclude statutory VAT; our terms apply. The one thing not allowed is offering wave-mesh to third parties as a hosted or managed service.
Roadmap
Everything under “Available” ships in the stable releases. “Next” is in progress or planned; new additions are listed in the changelog.
Available
- Direct connections through NAT
- Relay when punching fails
- Names under your own domain
- Let's Encrypt certificates
- Services from your Kubernetes cluster
- Access rules and audit log
- Signed self-updates
Next
- iOS and Android appscore done, apps in progress
- Subnet routers and exit nodes
- Wave services on the open internet
Questions
How is this different from a hosted mesh VPN?
You own the coordination server: it runs on your infrastructure, not at a vendor. Your devices have names under your own domain, and each one gets a publicly valid certificate.
How fast is it?
Today the data path runs in userspace. Expect 100 to 300 Mbit/s per device. A faster path through kernel WireGuard is planned but not built yet.
Do I need my own domain?
No. Without a domain your devices live under .internal and are still reachable by name. Publicly valid certificates need a domain you own.
What does the licence allow?
Using, changing and redistributing it, including inside your company. Offering wave-mesh to third parties as a hosted or managed service is not allowed.
What do I need on the server?
A Kubernetes cluster; a single server with k3s is enough. Control server, relay and Postgres ship as ready-made images and are set up with Kustomize. From outside you need HTTPS and UDP 3478 for STUN.
Bring your devices together.
One server, one binary per device, and everything talks directly.