Relays, ports and firewalls
When two devices cannot reach each other directly, a member of your own network passes their traffic on. This page also lists the ports juist uses and what to open where.
What a relay does #
juist usually gets a direct tunnel through NAT. It fails only if both devices sit behind symmetric NAT, a strict kind that picks a new port for every destination. Then the two need a relay.
A relay is a member with a public address, such as a VPS, that passes traffic between devices that cannot reach each other. No third party ever relays your traffic. Only members can use the relay, and it sees only encrypted WireGuard traffic.
A relay also helps with invites. When you run juist invite on a laptop
behind NAT, the invite also waits at the relay, and the link names the relay,
so a new device can join from anywhere
(Invites). The invite’s secret never reaches
the relay.
Setting up a relay #
Join the network, then open the ports with ufw:
sudo juist join 'juist:…'
sudo ufw allow juist && sudo ufw allow juist-relayOr, with firewalld:
sudo firewall-cmd --permanent --add-service=juist --add-service=juist-relay && sudo firewall-cmd --reloadGive the VPS the role relay:
juist grant vps relayThe Relays line in juist status then counts it as available.
juist revoke vps relay takes the role away. It is best to give the role to
two or more devices with public addresses. In a network of more than two
devices, juist health warns as long as no device may relay.
A relay on 443 #
A relay can also serve a public name on port 443, like any HTTPS server. A device on a network that lets nothing else out reaches the relay there, either by itself or in HTTPS-only mode.
Point a name such as relay.example.org at the relay, with an A record, and
an AAAA record if the relay has IPv6.
Have the relay serve the name:
sudo juist set --relay-name relay.example.orgjuistd listens on 443/tcp at the relay’s addresses, ufw or firewalld let it
in, and Let’s Encrypt issues a certificate for the name. juist status then
says:
Relay name relay.example.org, on 443
- Every device learns the name from the relay’s announcement.
- Port 443 needs a privilege only root can give.
sudo juist setgives juistdCAP_NET_BIND_SERVICEfor this alone, through a systemd drop-in.sudo juist set --relay-name ""takes it away with the name. - On FreeBSD, juistd’s helper binds 443 only while root’s permission is in place and no other program listens on 443. If pf runs, it must let the traffic in.
- If the name is gone but the privilege remains,
juist healthwarns, andjuist resettakes the privilege away. - Members use the name only once the server there proves it is this relay.
- If the relay is also the network’s
ingress, the ingress holds 443 and
passes the name’s connections to the relay. Without
--relay-name, it servesrelay.DOMAIN, which the domain’s wildcard record already points at the ingress.relayis then no name to publish. - If several ingresses relay, one of them takes
relay.DOMAIN, asjuist statusthere says. Give the others their own names, and pointrelay.DOMAINat that one alone. - A CAA record for the name must allow Let’s Encrypt.
- On a device in several networks, only the default network’s juistd serves a name on 443.
Ports #
| Port | For | Open it where |
|---|---|---|
| 41643/udp | WireGuard and path discovery | a device with a public address |
| 41645/tcp, 41645/udp | the relay, and the STUN replies members use to measure it | a device granted relay |
| 443/tcp | the relay under its public name | a relay with a name; juist set --relay-name opens it |
| 41642/tcp | accepting an invite by code on the LAN | the inviting device, while juist invite runs |
| 443/tcp, 443/udp, 80/tcp | the names devices publish, over TLS and QUIC | a device granted ingress; juist ingress serve opens them |
| the TCP ports names are published on | those names | every ingress; it opens and closes them as names are added and removed |
Devices behind NAT need no open ports. Link invites need none either: if the new device cannot reach the inviting device directly, the two meet through a relay right away, or through the public DHT within about a minute.
A device in several networks runs one juistd
per network. The n-th one uses these ports plus 10·n, for example 41653/udp
for juistd@juist1.
Firewalls #
The packages install ufw and firewalld profiles named juist, juist-relay,
juist-relay-443, juist-invite and juist-ingress. The profiles cover the
first network’s ports; juist status gives the port numbers for the others.
Log sync runs inside the tunnel, on TCP 41644 on juist0 (41654 on
juist1, and so on). The packages let it in if ufw or firewalld runs. A
firewall you configured by hand must let it in too. Otherwise the device
keeps its tunnels but misses changes to the network, removals included, and
juist health reports this. An exit node
also answers DNS there, on UDP and TCP 41646.
Upgrading from a build whose juist profile opened every port: ufw keeps the
old ports until sudo ufw app update juist, while firewalld narrows juist
to 41643/udp right away. In both cases, a relay needs juist-relay added.
Running without public helpers #
By default, juistd asks public STUN servers (Google, Cloudflare) for its public address, and uses the public BitTorrent DHT to find members it lost track of. Both see addresses, never contents.
Once you have a relay of your own, the network can run without either. On every device, run:
sudo systemctl edit juistdand enter:
[Service]
ExecStart=
ExecStart=/usr/bin/juistd --home /var/lib/juist --socket /run/juist/juistd.sock --tun juist0 --no-dht --no-stunDevices then find each other on the LAN and through members they already know.
The relay tells each device its public address, and invite links meet through
it. man juistd lists every option.
Troubleshooting #
juist health says | What to do |
|---|---|
no tunnel traffic from … | open 41643/udp on a device with a public address, or grant one relay |
no device reaches this relay | open 41645/tcp and udp on the relay, and in any firewall in front of it |
no device may relay | run juist grant DEVICE relay for a device with a public address |
no certificate for relay.example.org yet | point the name at the relay, and let 443/tcp reach it |
the relay cannot take 443 | another program holds 443 there, or juistd lacks the capability juist set grants |
members are not told of …: this device does not relay | grant the device relay: juist grant DEVICE relay |
log sync … fails in the tunnel | let juist0 through the other device’s firewall, as the hint says |
no answer from … | the device is offline, or its 41643/udp is closed |