Relayium

Relayium als dauerhaft laufenden Empfangsdienst betreiben

Zuletzt aktualisiert: 2026-08-06

relayium serve --once nimmt eine eingehende Übertragung entgegen und beendet sich dann — gut für ein gelegentliches Pull. Willst du aber eine Maschine zu einer dauerhaften Anlaufstelle machen — einen Heimserver, auf dem nachts Backups landen, eine Build-Maschine, zu der CI Artefakte pusht, ein NAS, an das dein Handy jederzeit Fotos schicken kann —, soll serve durchgehend laufen, statt für jede Übertragung von Hand gestartet zu werden.

Diese Anleitung behandelt das Starten eines dauerhaft laufenden Listeners, das Genehmigen, wer pushen darf, das Vorab-Autorisieren von Peers für den Fall, dass niemand am Terminal sitzt, den Betrieb unter systemd sowie das Zulassen, dass ein sync --delete-Sender Löschungen spiegelt.

Bevor du loslegst

Alles unten ist die relayium-CLI, installiere sie also zuerst, falls noch nicht geschehen. Unter macOS oder Linux legt ein Befehl ein vorgebautes Binary in deinen PATH:

curl -fsSL https://relayium.com/install.sh | sh

Den Listener starten

Was du vor Schritt 1 brauchst

  • Die CLI auf beiden Rechnern. relayium version gibt auf jedem eine Versionszeile aus; antwortet die Shell mit command not found, ist sie dort noch nicht installiert.
  • Ein Verzeichnis für eingehende Dateien auf diesem Rechner und den Plattenplatz für das, was darin landen wird.
  • Eine für den Sender erreichbare Adresse und einen offenen eingehenden Port. Ohne --port lauscht serve auf 9031.
  • Wenn dieser Rechner ohne Terminal laufen soll — und genau darum geht es bei einem Dienst — den Fingerprint des Senders, vorab. Dazu gibt es unten einen eigenen Abschnitt, und er ist mit Abstand der häufigste Grund, warum ein dauerhaft laufender Empfänger alles ablehnt.

serve lauscht über eine TLS-1.3-Verbindung mit Pinning auf Pushes per daemon-direct (relayium://host:port) und schreibt das Empfangene in ein Verzeichnis. Zum Starten muss nichts vorab geteilt werden — keine Fingerprints zum Kopieren, kein Server zum Registrieren:

relayium serve --dir ~/inbox
relayium serve --dir /srv/drop --port 9040   # abweichender Port
relayium serve --dir ~/inbox --allow-delete  # einem sync --delete-Sender erlauben, Löschungen zu spiegeln
  1. Leg fest, wo Dateien landen sollen, und starte den Listener. Bis hierher muss nichts vorab ausgetauscht werden.

    relayium serve --dir ~/inbox
  2. Schieb vom sendenden Rechner aus etwas an diesen Host, adressiert über seine relayium://-Adresse.

    relayium push ./report.pdf relayium://drop.example.com:9031
  3. Zurück auf dem Empfänger: beantworte die Freigabeabfrage. Ein y schreibt den Fingerprint in authorized_fingerprints, und spätere Pushes desselben Rechners fragen nie wieder.

  4. Prüfe, dass die Datei wirklich in --dir gelandet ist und nicht in dem Verzeichnis, aus dem du serve gestartet hast.

    ls -l ~/inbox

So sieht ein funktionierender Listener aus

serve sagt gleich zu Beginn, dass es noch keine autorisierten Peers hat, fragt beim ersten Push eines neuen Rechners nach und bleibt bei jedem weiteren still. Der Sender endet mit 0, und die Datei liegt in --dir.

$ relayium serve --dir ~/inbox
no authorized peers yet — you'll be asked to approve each new peer on its first push.
Incoming push from 203.0.113.7:54021
  fingerprint: 74318e3b…
Accept and remember this peer? [y/N] y

Genehmigen, wer pushen darf

Wenn ein neuer Peer zum ersten Mal pusht, zeigt dir serve — sofern es in einem Terminal läuft — woher der Push kam und seinen Fingerprint und bittet dich um Genehmigung, genauso wie SSH bei einem unbekannten Host beim ersten Verbinden nachfragt:

Incoming push from 203.0.113.7:54021
  fingerprint: 74318e3b…
Accept and remember this peer? [y/N] y

Peers für nicht-interaktive Setups vorab autorisieren

Hat serve kein Terminal, an dem es nachfragen kann — ein systemd-Dienst, ein Hintergrundprozess, eine Pipe —, kann es nicht fragen und lehnt daher jeden noch nicht erkannten Fingerprint ab. Autorisiere Peers stattdessen im Voraus. Auf der Maschine, die pushen wird, führst du relayium id aus, um ihren Fingerprint auszugeben; auf dem Empfänger trägst du ihn ein, bevor der erste Push eintrifft:

# auf der Maschine, die pushen wird: ihren Fingerprint ausgeben
relayium id

# auf diesem dauerhaft laufenden Empfänger: sie vorab autorisieren
relayium authorize 74318e3b...
  1. Lass den sendenden Rechner seinen Fingerprint ausgeben. Es sind 64 Hex-Zeichen, und sie identifizieren den Rechner, nicht seine Adresse.

    relayium id
  2. Autorisiere ihn auf diesem Empfänger — mit demselben --config-dir, unter dem der Dienst später läuft. Autorisierst du als falscher Benutzer oder im Standardpfad, während die Unit einen anderen nutzt, landet der Fingerprint in einer Datei, die der Dienst nie liest.

    relayium authorize 74318e3b… --config-dir /etc/relayium

Unter systemd betreiben

Für einen Dienst, der Neustarts und Abstürze übersteht, überlässt du serve systemd. Richte --config-dir auf einen festen Pfad, damit Identität und Peer-Allow-Liste des Hosts über Neustarts hinweg erhalten bleiben:

# /etc/systemd/system/relayium-serve.service
[Unit]
Description=Relayium always-on receiver
After=network-online.target

[Service]
ExecStart=/usr/local/bin/relayium serve --dir /srv/drop --port 9031 --config-dir /etc/relayium --allow-delete
Restart=always
User=relayium

[Install]
WantedBy=multi-user.target
  1. Autorisiere jeden Peer, der pushen darf, bevor es den Dienst überhaupt gibt. Er kann nicht nachfragen, also wird alles abgelehnt, dem nicht schon vertraut wird.

  2. Schreib die Unit oben nach /etc/systemd/system/relayium-serve.service, mit --config-dir auf denselben festen Pfad, unter dem du autorisiert hast.

  3. Lade systemd neu und starte den Dienst — mit enable, damit er nach einem Neustart wiederkommt.

    sudo systemctl daemon-reload
    sudo systemctl enable --now relayium-serve
  4. Prüfe, dass er läuft und dass die Warnung, die alles ablehnt, nicht im Log steht. Nur die zweite Prüfung ist für dieses Setup spezifisch.

    systemctl is-active relayium-serve
    journalctl -u relayium-serve -n 20 --no-pager

So sieht ein funktionierender Dienst aus

is-active antwortet active, und die Startwarnung über fehlende autorisierte Peers taucht nicht auf. Diese Warnung ist die eine Zeile, die dir schon vor der ersten Beschwerde eines Senders sagt, dass dieser Dienst jeden Push abweisen wird.

$ systemctl is-active relayium-serve
active
$ journalctl -u relayium-serve -n 20 --no-pager | grep -c 'all pushes will be rejected'
0

Beim Booten unter macOS starten (launchd)

macOS hat kein systemd — sein Dienstmanager ist launchd. Um serve auf einem Mac dauerhaft laufen zu lassen (etwa auf einem Mac mini, der als Ablagepunkt eingeschaltet bleibt), installiere es als LaunchDaemon, damit es beim Booten startet, noch bevor sich jemand anmeldet. Setze UserName, damit er unter deinem Benutzerkonto und nicht als root läuft, und gib --dir und --config-dir absolute Pfade an, damit Identität und Vertrauensdateien in deinem eigenen ~/.config/relayium bleiben:

<!-- /Library/LaunchDaemons/com.relayium.serve.plist  (replace YOU with your macOS username) -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>              <string>com.relayium.serve</string>
  <key>UserName</key>           <string>YOU</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/relayium</string>
    <string>serve</string>
    <string>--dir</string>         <string>/Users/YOU/inbox</string>
    <string>--port</string>        <string>9031</string>
    <string>--config-dir</string>  <string>/Users/YOU/.config/relayium</string>
    <string>--allow-delete</string>
  </array>
  <key>RunAtLoad</key>   <true/>
  <key>KeepAlive</key>   <true/>
  <key>StandardOutPath</key>    <string>/Users/YOU/relayium-serve.log</string>
  <key>StandardErrorPath</key>  <string>/Users/YOU/relayium-serve.log</string>
</dict>
</plist>
# 1) authorize each pusher first — launchd gives serve no terminal to prompt on:
relayium authorize <fingerprint>     # get the fingerprint from the pusher's  relayium id

# 2) save the plist above to that path, then load it (root-owned, starts at boot):
sudo chown root:wheel /Library/LaunchDaemons/com.relayium.serve.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.relayium.serve.plist

# check it's running / follow logs / stop it:
sudo launchctl print system/com.relayium.serve | grep state
tail -f ~/relayium-serve.log
sudo launchctl bootout system/com.relayium.serve

Einem sync --delete-Sender erlauben, Löschungen zu spiegeln

Standardmäßig fügt serve nur Dateien hinzu oder aktualisiert sie — führt ein Sender sync --delete dagegen aus, werden neue und geänderte Dateien trotzdem kopiert, aber angeforderte Löschungen werden übersprungen und auf dem Empfänger als Warnung protokolliert. Starte serve mit --allow-delete, um echtes Spiegeln zu aktivieren, bei dem auf der Senderseite gelöschte Dateien auch hier gelöscht werden:

relayium serve --dir /srv/mirror --allow-delete

Wenn es nicht funktioniert

Bei vier dieser fünf Fehler läuft der Dienst weiter und sieht gesund aus — ein Listener, der alles ablehnt, ist immer noch ein Listener. Zu jedem gibt es eine Zeile zum Lesen oder einen Befehl zum Ausführen, der die Sache entscheidet.

Symptom, Prüfung, Lösung

Der Dienst startet und bleibt oben, aber jeder Push wird abgelehnt.
journalctl -u relayium-serve -n 20 --no-pager
# warning: no authorized peers and no terminal to approve on; all pushes will be rejected.

Ein Dienst hat kein Terminal, kann also die Freigabeabfrage beim ersten Push nie ausführen — und alles, was er sieht, ist ein unbekannter Fingerprint. Autorisiere jeden Sender vorab: relayium id auf dem sendenden Rechner, relayium authorize <Fingerprint> hier, mit demselben --config-dir wie in der Unit. Die Warnung wird beim Start ausgegeben und steht damit ab der ersten Logzeile darin.

Der Dienst startet gar nicht und beklagt unsichere Berechtigungen auf id.key.
stat -c '%a %U %n' /etc/relayium/id.key
# 400 relayium /etc/relayium/id.key

Der Schlüssel muss exakt 0600 haben. Nicht 0644 — und, das ist die Stelle, an der es die meisten erwischt, auch nicht 0400: strenger setzen bricht den Dienst genauso zuverlässig wie lockerer setzen. chmod 600 auf den Schlüssel, und der Eigentümer muss das User= der Unit sein.

Der Sender meldet, die Verbindung sei abgelehnt worden.
relayium push ./build relayium://drop.example.com:9031
# hint: if the peer refused the connection, it may not have authorized this host.

Der Empfänger kennt diesen Sender nicht. Führ relayium id auf dem Sender aus und relayium authorize mit diesem Fingerprint auf dem Empfänger. Wenn du das schon getan hast, prüfe, ob unter dem --config-dir der Unit: die Vertrauensdatei hängt am Verzeichnis, und ein nach ~/.config/relayium autorisierter Fingerprint existiert für einen Dienst, der /etc/relayium liest, schlicht nicht.

Pushes klappen, wenn du serve von Hand startest, aber nicht über den Dienst oder nicht von einem anderen Rechner.
sudo ss -tlnp | grep 9031

Zwei verschiedene Ursachen, eine Prüfung. Lauscht nichts, ist die Unit nicht aktiviert — systemctl is-enabled relayium-serve. Lauscht sie, ist der Port zu: öffne 9031 in der Host-Firewall und in jeder Cloud-Security-Group. Ein abweichendes --port muss zum Port in der relayium://host:N des Senders passen.

Die Löschungen eines sync --delete-Senders passieren auf diesem Rechner nie.
journalctl -u relayium-serve | grep -i delete

Löschen ist eine Opt-in-Entscheidung der Empfängerseite und standardmäßig aus: neue und geänderte Dateien werden weiterhin kopiert, jede übersprungene Löschung landet hier als Warnung im Log. Ergänze --allow-delete im ExecStart der Unit und starte neu. Dass der Sender danach fragt, genügt nicht, und diese Asymmetrie ist Absicht — ein Empfänger verliert keine Dateien wegen eines Flags, das woanders getippt wurde.

Häufige Fragen

Auf welchem Port lauscht serve standardmäßig?

9031. Ändere ihn mit --port sowohl beim Listener (serve --port N) als auch beim Ziel des Senders (relayium://host:N).

Muss ich jeden einzelnen Push von Hand genehmigen?

Nur den ersten Push eines bestimmten Fingerprints, und nur, wenn serve mit angeschlossenem Terminal läuft. Danach wird er sich gemerkt. Läuft serve nicht-interaktiv (systemd, eine Pipe), entfällt die Nachfrage komplett, und unbekannte Peers werden abgelehnt — autorisiere sie stattdessen vorab mit relayium authorize.

Kann ein Sender Dateien auf meinem dauerhaft laufenden Empfänger löschen?

Nur wenn du serve mit --allow-delete gestartet hast und der Sender sync --delete ausführt. Ohne --allow-delete werden Löschungen stillschweigend übersprungen, alles andere wird trotzdem übertragen.

Ist der Betrieb eines dauerhaft laufenden Empfängers kostenlos?

Ja. relayium serve ist Teil der kostenlosen, selbst hostbaren CLI — auf keiner Seite der Verbindung ist ein Konto oder eine kostenpflichtige Stufe nötig.

Wo bewahrt serve Identität und Peer-Liste auf?

Standardmäßig in ~/.config/relayium (id.key/id.crt für die Identität dieses Hosts, authorized_fingerprints für die Allow-Liste). Richte --config-dir für einen systemd-Dienst auf einen festen Ort wie /etc/relayium.

Wie starte ich serve beim Booten unter macOS?

macOS hat kein systemd — verwende launchd. Installiere serve als LaunchDaemon in /Library/LaunchDaemons (startet beim Booten; setze UserName, damit er unter deinem Benutzerkonto läuft) oder als LaunchAgent in ~/Library/LaunchAgents (startet bei der Anmeldung). Diese Anleitung enthält ein fertiges, editierbares plist; einen Homebrew-Dienst gibt es nicht. Autorisiere Absender vorab mit relayium authorize, da launchd serve kein Terminal für Rückfragen gibt.

Mach aus jeder Maschine, die dir gehört, einen kostenlosen, dauerhaft laufenden Empfänger — direkte Pushes über TLS mit Pinning, ganz ohne Relay.

CLI holen

Weiterlesen