A mesh VPN with no coordination server
WireGuard carries the traffic. Who belongs to the network is a log signed by your admins, and every device checks that log for itself.
Packages for Debian, Ubuntu, Fedora and FreeBSD →- No server in the middle
- Devices find each other on the LAN, through each other, or through the public BitTorrent DHT. They punch through NAT, and fall back to a relay that one of your own devices runs.
- Changes need your admins
- Admitting or removing a device takes a quorum of admins, each with a key on their own devices. The keys stay in the keystore; the daemon never holds them.
- Fail-closed
- Once a network has vouchers, a device that too few of them have vouched for in 48 hours keeps tunnels only to vouchers, so it cannot carry a removed device along.
Your first network #
On the first device, juist create makes a network and juist invite prints
a code for the LAN and a link for anywhere else. The new device joins with
either. Both then show four words, and the invite admits the device only once
you have compared them.
$ juist create home
created network "home"
$ juist invite
invite to "home", expires in 1h; on the new device:
juist join 'juist:Kx7q…@192.168.1.20:41642'
juist join 42-drumbeat-tolerance-glucose # same LAN
nas wants to join; compare with the words it shows:
atlas-amulet-banjo-asteroid
same? [y/N] y
admitting nas (nid:fcRW83T_…)
admitted nas at 198.18.36.2
nas joined
Features #
For networks of 25 to 100 devices with a few admins.
| Feature | What it does |
|---|---|
| Mesh and NAT traversal # | WireGuard tunnels between every pair of devices, direct where NAT allows. |
| Post-quantum tunnels # | Every handshake mixes in a key a quantum computer cannot recover, one each two devices hold alone. |
| Invites # | A code for the LAN or a link for anywhere. Both devices show four words to compare. |
| Android* # | A phone joins by the invite's QR code or code, reaches the members at their addresses, and shows how each is reached. |
| Admins and quorum # | Every change takes k of n admins. One that needs more is carried to their devices. |
| Access policy # | Which device may open what on which, and use which exit node or subnet. The rest is refused. |
| Several networks # | One device in several networks, each with an admin key of its own. |
| Exit nodes # | A device's internet traffic and DNS through another member. |
| Subnet routers # | The LAN behind one member, reached from the others. |
| Names** # | Every member as DEVICE.NETWORK.juist, and public names pointed at members. |
| Publishing services # | A member's service reached from the internet by name, through an ingress. |
| HTTP/3 # | Published names over QUIC, through the ingress, for browsers that find it or are told of it by DNS. |
| Names for members alone*** # | A published name with the CA's certificate that the internet does not reach, opened by the members the access policy names it for. |
| TCP services # | A game server or any other TCP service on a port of its own on every ingress, passed on unread. |
| Sharing # | A file, a directory or a web server, from the internet at once, under a device's own name. A directory downloads as a ZIP. |
| Status page # | Devices, their reach, published names and the log's changes on one page, for members, and as much for anyone else as you choose. |
| Relays # | Where NAT wins, traffic goes through a member with a public address. |
| HTTPS alone # | From a network that lets nothing out but HTTPS, through relays on 443 under public names, and a company's proxy. |
| Renaming and renumbering # | The network or a device gets another name, the devices other IPv4 addresses. Nothing is set up again. |
| Key backups # | An admin key as one line, for a password manager. |
| Break-glass # | A secret shown once at creation and kept offline ends the network for good, with no admin needed. |
| Freshness and removal # | A removed device is told. With vouchers, one cut off for 48 h keeps tunnels only to vouchers. |
Every feature runs on Linux and FreeBSD, and the app on Android. * On Android 12 or newer, as a member without names, roles or subnets. ** Only on Linux with systemd-resolved. *** Reached from Linux with systemd-resolved.
Publishing services #
A member’s service, such as a NAS at home, can be reached from the internet by name. A device with a public address, the ingress, reads the name the client asks for and passes the connection through the tunnel. TLS ends at the member, so the ingress never sees the content.
- browseranywhere
Asks for docs.example.org.
- TLSvpsingress
Reads the name in the TLS ClientHello and passes the connection on.
- WireGuardnastarget
Ends TLS, with a certificate from Let's Encrypt.
- HTTP127.0.0.1:8080service
Gets the plain connection.
How to set it up is in the handbook.
Trade-offs #
Without a server in the middle, some things are weaker than with one. Each entry says what can happen, why juist accepts it, and what you can change. All of them are in 02-threat-model.md.
Membership #
Revocation is eventually consistent #
juist admins vouchers M
- What happens
- A device cut off from the network keeps tunnels to a removed device until it hears of the removal.
- Why accepted
- There is no server that every device could ask. The freshness lease bounds it: a device no voucher has vouched for in 48 h keeps tunnels only to vouchers.
- What you can do
- Make always-on devices vouchers, and require M of them, so that the bound holds against M − 1 dishonest ones. A new network has none, and no bound.
Losing a quorum of admin keys is final #
more admins than the quorum needs
- What happens
- With fewer than k admin keys left, no change can be signed again, ever.
- Why accepted
- A way around the quorum would be one for an attacker too.
- What you can do
- Give the network more admins than the quorum needs, each on devices of their own.
Reachability #
Symmetric NAT everywhere needs a relay #
juist grant vps relay
- What happens
- Where every device sits behind symmetric NAT, no direct tunnel forms.
- Why accepted
- The relay is one of your own members and sees only WireGuard ciphertext.
- What you can do
- Grant
relayto a device with a public address.
Public helpers see addresses #
--no-dht --no-stun
- What happens
- The public BitTorrent DHT and STUN servers see the addresses that use them.
- Why accepted
- Nothing they return is trusted. A compromised helper can delay connections, but cannot change who belongs to the network.
- What you can do
- Run juistd without them, and give devices addresses they can reach.
Cryptography #
A tunnel starts on the group's key #
no setting
- What happens
- Until two devices have a key of their own, a log sync after their tunnel comes up, their traffic is protected by a key any member could derive.
- Why accepted
- Against everyone outside the network it is post-quantum from the start; only a member, or a device removed since, with a quantum computer could read those first seconds.
- What you can do
- Nothing.
juist statussays which tunnels are on the group’s key.