Installation

juist installierst du als Paket deines Systems, und zwar auf jedem Gerät, das in ein Netz soll. Jedes Release bringt fertige Pakete mit, dazu eine signierte Liste ihrer Prüfsummen.

Unterstützte Systeme #

juist läuft unter Linux und FreeBSD. Für Debian und Ubuntu gibt es ein .deb, für Fedora ein RPM und für FreeBSD 15 ein pkg-Paket. Jedes Release enthält die Pakete für amd64 und arm64, das RPM allerdings nur für x86_64. Auf einem anderen Linux mit systemd, etwa Arch oder Gentoo, installiert es make install aus dem Quellcode (Aus dem Quellcode bauen). Ein Telefon tritt stattdessen mit der App bei, siehe Android.

Das Paket installieren #

Die Paketquelle von juist installiert juist, und die Updates des Systems bringen danach jedes neue Release mit. Sie enthält die Pakete der Releases für Debian, Ubuntu, Fedora und FreeBSD. Um eine einzelne Datei zu installieren, nimmst du stattdessen das Paket des Releases (Aus einem Release).

Aus der Paketquelle #

Unter Debian, Ubuntu und Fedora:

curl -fsSL https://juist.nning.io/install | sh

Unter FreeBSD 15, als root:

fetch -o - https://juist.nning.io/install | sh

Das Skript trägt die Paketquelle und ihren Schlüssel bei apt, dnf oder pkg ein, installiert juist und startet unter FreeBSD den Daemon; wo es nicht root ist, nimmt es sudo. Um es vorher zu lesen, lade es als install.sh herunter und starte es mit sh install.sh. Von Hand sind es diese Schritte:

1auf einem Gerät mit Debian oder Ubuntu

Trage die Paketquelle und ihren Schlüssel ein und installiere dann juist:

sudo install -d -m 755 /etc/apt/keyrings
sudo curl -fsSL -o /etc/apt/keyrings/juist.gpg https://pkg.juist.nning.io/juist/key.gpg
echo "deb [signed-by=/etc/apt/keyrings/juist.gpg] https://pkg.juist.nning.io/juist/deb/ ./" | sudo tee /etc/apt/sources.list.d/juist.list
sudo apt update && sudo apt install juist

Das gilt für amd64 und arm64 gleichermaßen.

2auf einem Gerät mit Fedora

Trage die Paketquelle ein und installiere dann juist:

sudo tee /etc/yum.repos.d/juist.repo <<'EOF'
[juist]
name=juist
baseurl=https://pkg.juist.nning.io/juist/rpm
gpgcheck=0
repo_gpgcheck=1
gpgkey=https://pkg.juist.nning.io/juist/key.asc
EOF
sudo dnf install juist

Der Schlüssel signiert den Index der Paketquelle, der die Prüfsumme jedes Pakets enthält. So bleibt das RPM die Datei des Releases und selbst unsigniert.

3auf einem Gerät mit FreeBSD 15

Trage als root die Paketquelle und ihren Schlüssel ein, installiere juist und starte dann den Daemon:

mkdir -p /usr/local/etc/pkg/repos /usr/local/etc/pkg/keys
fetch -o /usr/local/etc/pkg/keys/juist.pub https://pkg.juist.nning.io/juist/freebsd.pub
cat > /usr/local/etc/pkg/repos/juist.conf <<'EOF'
juist: {
  url: "https://pkg.juist.nning.io/juist/freebsd/${ABI}",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/pkg/keys/juist.pub"
}
EOF
pkg install -r juist juist
sysrc juistd_enable=YES && service juistd start

Das gilt für amd64 und arm64 gleichermaßen; was juist mit pf macht, steht unter Aus einem Release. sha256 /usr/local/etc/pkg/keys/juist.pub gibt die Prüfsumme des Schlüssels aus, c649f2cd073f9e72825b0c1b8a2682f25c5c55405a178ea6d8a0f8b65ed89e3d.

dnf zeigt den Fingerabdruck des Schlüssels, wenn es ihn importiert, und unter Debian und Ubuntu zeigt ihn gpg --show-keys /etc/apt/keyrings/juist.gpg: 1D57474BAAC54CEEAD9168110EBE32412D806005.

Aus einem Release #

4auf einem Gerät mit Debian oder Ubuntu

Lade das Paket herunter und installiere es:

curl -LO https://github.com/nning/juist/releases/latest/download/juist_amd64.deb
sudo apt install ./juist_amd64.deb

Auf arm64 nimmst du juist_arm64.deb.

5auf einem Gerät mit Fedora

Installiere das Paket:

sudo dnf install https://github.com/nning/juist/releases/latest/download/juist.x86_64.rpm
6auf einem Gerät mit FreeBSD 15

Installiere das Paket als root mit pkg und starte dann den Daemon:

pkg add https://github.com/nning/juist/releases/latest/download/juist-freebsd15-amd64.pkg
sysrc juistd_enable=YES && service juistd start

Auf arm64 nimmst du juist-freebsd15-aarch64.pkg. Unter Linux startet das Paket den Daemon von selbst, unter FreeBSD startest du ihn einmal wie oben gezeigt.

Unter FreeBSD lässt juistd pf mit eigenen Regeln laufen, die die Adressen des Geräts im Netz dem Tunnel vorbehalten: Das LAN erreicht sie nicht. Lädt der Host eigene pf-Regeln, muss /etc/pf.conf die Anker von juist aufrufen, nat-anchor "juist/*", rdr-anchor "juist/*" und anchor "juist/*", vor jeder Regel, die mit quick durchlässt; sonst warnt juist health.

Installierst du später ein neueres Release, ersetzt es das alte, und der Zustand des Geräts bleibt erhalten. Einzelheiten stehen unter juist aktualisieren. Ein Paket aus der Paketquelle und eines aus einem Release sind dasselbe, jedes aktualisiert also das andere.

Den Download prüfen #

Jedes Release führt die SHA-256-Summen seiner Dateien in SHA256SUMS, signiert mit dem Schlüssel in packaging/release-signers. Leg diese Datei, den Download, SHA256SUMS und SHA256SUMS.sig in ein Verzeichnis und prüfe dann so:

ssh-keygen -Y verify -f release-signers -I juist -n juist-release -s SHA256SUMS.sig < SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS

Der erste Befehl meldet Good "juist-release" signature for juist with ED25519 key SHA256:a2nq8txrPWVfLfF4XGzyKrFo4t71aXkcDOGZNQJABLM, der zweite OK für jede heruntergeladene Datei.

Aus dem Quellcode bauen #

Zum Bauen brauchst du Go 1.21 oder neuer und make. make lässt Go selbst go1.27.3 herunterladen und baut damit, sodass ein Commit auf jedem Rechner exakt dieselben Bytes ergibt.

git clone https://github.com/nning/juist
cd juist
make install      # unter FreeBSD als root: gmake install

make install baut das Paket für das System, auf dem es läuft (auf Debian und Ubuntu das .deb, auf Fedora das RPM, auf FreeBSD das pkg-Paket), und installiert es. Rufst du es später erneut auf, ersetzt der neue Build den alten.

Gibt es weder apt noch dnf noch pkg, auf einem anderen Linux mit systemd, legt make install die Dateien des RPMs selbst an dieselben Stellen, legt den Benutzer juist an und startet juistd. Über ein juist aus einem Paket installiert es nicht. make uninstall entfernt sie wieder, ohne den Quellbaum sudo /usr/lib/juist/manual-install.sh uninstall; die Benutzer und /var/lib/juist mit den Schlüsseln des Geräts bleiben.

Soll ein Rechner juist nicht selbst bauen, baust du nur das Paket und kopierst es hinüber:

SystemBauenAuf dem anderen Rechner installieren
Debian, Ubuntumake debsudo apt install ./juist_*.deb
Fedoramake rpmsudo dnf install ./juist-*.rpm
FreeBSDmake pkg-freebsdpkg add ./juist-*.pkg

Die Pakete landen in build/deb, build/rpm/RPMS und build/freebsd. make deb DEB_ARCH=arm64 baut das .deb für eine andere Prozessorarchitektur, mit armhf und i386 funktioniert es genauso.

Im Container #

Eine App im Container kann ein eigenes Gerät sein, mit eigenen Adressen und einem eigenen Platz in den Zugriffsregeln: juistd läuft in einem zweiten Container, der sich den Netz-Namespace mit der App teilt, und legt dort juist0 an. Was die App zur Adresse eines Mitglieds öffnet, geht durch den Tunnel. Das Image baust du mit make image im Quellbaum und lädst es mit docker load.

7auf dem Gerät eines Admins
juist invite app
8auf dem Container-Host

In einer compose.yaml hält ein eigener Dienst, netns, den Namespace, damit juist und die App ihn behalten, wenn einer von beiden neu startet; JUIST_JOIN nimmt den Einladungslink:

services:
  netns:
    image: registry.k8s.io/pause:3.10
    restart: unless-stopped
  juist:
    image: juist:VERSION
    network_mode: service:netns
    user: "0:0"
    cap_drop: [ALL]
    cap_add: [NET_ADMIN]
    devices: [/dev/net/tun]
    environment:
      JUIST_JOIN: "juist:…"
    volumes:
      - type: volume
        source: juist
        target: /var/lib/juist
        volume:
          nocopy: true
    restart: unless-stopped
  app:
    image: …   # die App
    network_mode: service:netns
    depends_on: [juist]
    restart: unless-stopped
volumes:
  juist: {}
docker compose up -d

Wie der Beitritt lief, zeigt docker compose logs juist, die Adressen des Geräts docker compose exec juist juist status. Nach dem Beitritt ist der Link verbraucht und JUIST_JOIN wird ignoriert.

  • juistd braucht CAP_NET_ADMIN und /dev/net/tun, kein privileged. Docker gibt eine Capability nur root, also läuft juistd dort als root, ohne jede andere Capability, auf einem Volume, das root gehört: nocopy verhindert, dass es dem Benutzer des Images gehört. Podman gibt sie dem Benutzer des Images; dort kommt die compose.podman.yaml des Beispiels dazu.
  • Die Namen des Netzes werden in den Containern nicht aufgelöst, da dort kein systemd-resolved läuft, und juist health sagt das. Nimm die Adressen, die juist devices auflistet, oder trag Namen mit extra_hosts an netns in die /etc/hosts des Namespace ein, mit der IPv6-Adresse, die beim Umnummerieren gleich bleibt.
  • Startet netns neu, startet docker compose restart netns juist und die App mit ihm neu; sonst bleiben sie in seinem alten Namespace.
  • Statt netns kann ein Tailscale-Container im Userspace-Modus den Namespace halten, mit network_mode: service:tailscale; die beiden kommen sich nicht in die Quere.

Dasselbe mit Kommentaren, einer .env und Podmans Ergänzung: examples/sidecar im Repository.

Was das Paket installiert #

  • Den Befehl juist und den Daemon juistd. Was welches Programm tut, steht unter So funktioniert juist.
  • Unter Linux den Dienst juistd. Er startet sofort und wartet, bis du ein Netz anlegst oder einem beitrittst. Er läuft als Benutzer juist, nur mit CAP_NET_ADMIN, auf einem Relay auf Port 443 zusätzlich mit CAP_NET_BIND_SERVICE. Weitere Netze laufen als die Benutzer juist1 bis juist9, die das Paket ebenfalls anlegt.
  • Unter Linux zwei weitere Dienste: juist-ingress für einen Ingress, gestartet von juist ingress serve, und juist-serve, den TLS-Terminator von juist, den systemd startet, wenn juist publish oder juist share ihn braucht.
  • Firewall-Profile für ufw und firewalld: juist, juist-relay, juist-relay-443, juist-invite und juist-ingress. Läuft ufw oder firewalld, lässt das Paket außerdem Verkehr auf juist0 durch, den der Log-Abgleich und veröffentlichte Dienste brauchen. Das geschieht nur bei der ersten Installation, ein Upgrade lässt deine Firewall in Ruhe.
  • Eine polkit-Regel, die juistd erlaubt, das DNS des Netzes über systemd-resolved einzurichten. Sie braucht polkit, das das Paket empfiehlt; Minimalinstallationen wie Fedora Cloud haben es nicht. Unter Ubuntu 22.04, dessen polkit keine Regeln liest, legt das .deb dieselbe Erlaubnis in /var/lib/polkit-1/localauthority/10-vendor.d/60-juist.pkla ab.
  • Shell-Vervollständigung für bash, zsh und fish sowie die Man-Pages juist(1) und juistd(8).

Ob der Daemon läuft, siehst du so:

nas
$ juist status
nas · no network

Weiter geht es mit dem ersten Netz.

Deinstallieren #

Willst du nur ein Netz verlassen und juist behalten, nimm stattdessen juist reset, siehe Geräte entfernen.

Ist das Gerät Mitglied eines Netzes, nimm es zuerst heraus, damit das Netz es nicht weiter führt. Dazu ruft ein Admin auf seinem eigenen Gerät juist remove nas auf. Danach entfernst du das Paket:

sudo apt remove juist      # Debian, Ubuntu
sudo dnf remove juist      # Fedora
pkg delete juist           # FreeBSD, als root

Dabei wird juistd für jedes Netz auf dem Gerät beendet, und alles, was juist auf dem Rechner eingerichtet hat, wird rückgängig gemacht. Unter Linux sind das die Firewall-Regel für juist0, ein Ingress, ein Relay auf Port 443 und die Änderungen von juist exit serve.

Was nach dem Deinstallieren bleibt #

  • Unter Linux bleiben die Schlüssel und das Log des Geräts in /var/lib/juist, die eines weiteren Netzes in /var/lib/juist1 usw., ebenso die Systembenutzer juist, juist1 bis juist9, juist-ingress und juist-serve. Auf Debian und Ubuntu löscht sudo apt purge juist jedes dieser Verzeichnisse nur, wenn es leer ist. Andernfalls meldet es: juist: kept /var/lib/juist, which still holds this device's keys and log.
  • Auch /var/lib/juist-serve bleibt (unter FreeBSD /var/db/juist-serve). Darin liegt das ACME-Konto des TLS-Terminators, auf das die CAA-Einträge deiner veröffentlichten Namen verweisen können. sudo apt purge juist unter Debian und Ubuntu und sudo dnf remove juist unter Fedora melden das: juist: kept /var/lib/juist-serve, the terminator's ACME account, which CAA records may name.
  • Unter FreeBSD gibt das Entfernen eine einzige Zeile aus, die mit juist: kept beginnt und alles aufzählt, was bleibt.
  • Deine Admin-Schlüssel in ~/.config/juist gehören nicht zum Paket und bleiben beim Entfernen unberührt.

Fehlersuche #

  • make install meldet make install knows apt (Debian, Ubuntu), dnf (Fedora) and pkg (FreeBSD); use make deb, rpm or pkg-freebsd: Dieses System nutzt keinen der drei Paketmanager. Bau das Paket für eines der unterstützten Systeme und installiere es dort.
  • juist status meldet juist0 · not running, unter FreeBSD vor dem Aktivieren juistd not running: Starte den Daemon mit sudo systemctl enable --now juistd, unter FreeBSD als root mit sysrc juistd_enable=YES && service juistd start.
  • Unter Linux zeigt journalctl -u juistd das Log des Daemons; unter FreeBSD steht es in /var/log/juistd.log.