Alle Seiten
Auf dieser Seite

Das Zugriffstoken und wer das Relay erreicht

Ein Relay hat einen Besitzer und ein Zugriffstoken. Wer das Token hat, hat die volle Kontrolle über das Relay und, über dessen Agents, über das Benutzerkonto, unter dem das Relay läuft. Es gibt keine Benutzerkonten, Rollen oder Keys pro Gerät. Diese Seite erklärt, woher das Token kommt, wie ein Browser oder ein Skript es vorlegt, wer sich überhaupt verbinden kann, was ohne Token erreichbar ist und was zu tun ist, wenn es durchsickert.

Das Token #

oar setup erzeugt das Token (für eine neue Config ein zufälliges, 43 Zeichen aus zufälligen Buchstaben, Ziffern, - und _) und schreibt es nach authToken in die Config-Datei, config.json im Zustandsordner von OAR. Außerhalb von Windows hält das Relay diese Datei nur für dich lesbar. Siehe config.json und Wo Geheimnisse liegen.

Ohne authToken in der Config erzeugt das Relay bei jedem Start ein zufälliges Token, schreibt es in sein Log und speichert es nicht. Startest du das Relay mit --token <value>, gilt dieses Token nur für diesen Lauf; es wird nie gespeichert und steht in der Befehlszeile. Deine Agents lesen das Token aus config.json (siehe Agents und das Token). Wenn Agents funktionieren sollen, nimm also ein Token, das dort gespeichert ist.

oar url gibt die Adresse mit dem aktuellen Token aus, zum Beispiel http://localhost:3333/?token=<your token>. Behandle diese Adresse wie ein Passwort.

Wege, es vorzulegen #

Weg Genutzt von
Der Teil ?token= der Seitenadresse Einem Browser, beim ersten Mal. Die Seite nimmt das Token aus der Adressleiste und schickt es in einem Header an das Relay; das Relay antwortet mit dem Anmelde-Cookie unten. Neu in 0.9.11 Das funktioniert nur bei der Seitenadresse: API-, Datei- und Asset-Adressen nehmen kein ?token= an
Das Anmeldefeld, Enter your access token to connect (Gib dein Zugriffstoken ein, um dich zu verbinden), dann Connect (Verbinden) Einem Browser ohne Cookie. Ein falsches Token zeigt Invalid token (Ungültiges Token); ein leeres Feld zeigt Please enter a token (Bitte gib ein Token ein)
Ein Header Authorization: Bearer <token> Skripten und API-Aufrufen
Das Anmelde-Cookie Einem Browser, der sich schon einmal angemeldet hat

Das Token wird nie aus dem Body einer Anfrage gelesen und seit 0.9.11 auch nicht aus ihrer Query. Trägt eine Anfrage sowohl einen Header als auch das Cookie, nimmt das Relay den Header. Ein falscher Wert wird nicht übersprungen: Ein falscher Header wird abgelehnt, auch wenn das Cookie stimmt. Die Live-Verbindung (Socket.IO) liest das Token aus dem Feld auth.token der Verbindung oder aus dem Cookie, nicht aus einem Header und nicht aus ihrer Query.

Ein Token in der Adresse

Die erste Anfrage nach der Seite, /?token=..., trägt das Token in ihrer Adresse. Das Token kann also im Verlauf des Browsers landen, in den Logs eines Reverse Proxys oder Tunnels vor dem Relay und überall, wohin du die Adresse kopierst. Die Seite entfernt es nach dem Laden aus der Adressleiste und meldet sich mit einem Header an, und keine andere Anfrage nimmt das Token aus der Adresse. Nimm wo möglich lieber das Anmeldefeld oder einen Header.

Skripte, die ?token= nutzten

Bis 0.9.10 nahm das Relay ?token= bei jeder Anfrage an. Ein Skript, das damit API-, Datei- oder Asset-Adressen abruft, bekommt jetzt 401: Schick stattdessen Authorization: Bearer <token>. Ein Socket.IO-Client übergibt das Token als auth.token. Siehe Upgrade-Hinweise.

Nach einem gültigen Token setzt das Relay ein Cookie namens copilot_auth, das 30 Tage gilt. Das passiert auch bei einem Skript, das das Token in einem Header schickt. Es ist HttpOnly, Skripte der Seite können es also nicht lesen, und SameSite=Lax. Es wird als Secure markiert, wenn das Relay über HTTPS erreicht wird. Kommt eine Anfrage mit einem Cookie, das nicht mehr zum Token passt, antwortet das Relay mit 401 und löscht das Cookie, und der Browser zeigt das Anmeldefeld. Das Cookie enthält das Token selbst.

Abmelden und ein Gerät sperren #

Die App hat keinen Abmelde-Button für das Relay, und das Relay führt keine Liste angemeldeter Geräte. Weil das Cookie das Token selbst enthält, lässt sich ein einzelnes Gerät nicht für sich sperren. In deinem eigenen Browser löschst du das Cookie in den Website-Einstellungen des Browsers. Um jedes Gerät auszusperren, auch eines, das du verloren hast, änderst du das Token (nächster Abschnitt).

Das Token rotieren #

oar setup --new-token

Das schreibt ein neues Token und startet das Relay neu (im Terminal fragt es vorher; siehe oar setup). Was passiert:

  • Angemeldete Browser. Das alte Token funktioniert nicht mehr, sobald das Relay neu gestartet ist. Der Neustart trennt die Live-Verbindung, und die nächste Anfrage jedes Browsers schlägt fehl: Das Relay löscht sein Cookie, und der Browser zeigt das Anmeldefeld. Melde dich mit der Adresse aus oar url oder dem neuen Token erneut an.
  • Bis zum Neustart. Lehnst du den Neustart ab, nimmt das laufende Relay das alte Token weiter an, bis oar restart läuft.
  • Gekoppelte Relays. Ein Relay, das dein Token gespeichert hat, weil du die beiden gekoppelt hast, bekommt Token not accepted (Token nicht akzeptiert). Füge das Relay dort mit dem neuen Token erneut hinzu; siehe Remote-Relays. Eine Kopplung auf diesem Relay zu entfernen widerruft kein Token, das die andere Seite schon hat; durch das Rotieren sperrst du dieses Relay aus.
  • relay-previous.json. Solange ein geänderter Port oder ein geändertes Token auf den Neustart wartet, behält oar setup den alten Port und das alte Token in dieser Datei im Datenordner (Klartext, nur für dich lesbar), damit oar status, oar stop und oar restart das laufende Relay noch finden. Es ist keine Schonfrist: Die Datei ändert nichts daran, was das Relay annimmt, und die oar-Befehle löschen sie, sobald das Relay mit den neuen Einstellungen antwortet. Das alte Token funktioniert erst nicht mehr, wenn das Relay neu startet.
  • Geteilte Links und Preview-Links haben eigene Tokens und sind nicht betroffen.

Wenn du authToken in der Datei von Hand änderst, funktioniert das genauso; oar restart übernimmt es.

Wer sich überhaupt verbinden kann #

localhostOnly in der Config entscheidet, wo das Relay lauscht:

localhostOnly Setup-Option Das Relay lauscht auf Erreichbar von
true (Standard) oar setup --local oder Antwort 1 127.0.0.1 Nur diesem Rechner
alles andere oar setup --lan oder Antwort 2 0.0.0.0 (alle Schnittstellen) Jedem Gerät, das die Adresse und den Port des Rechners erreicht

Nur der Boolean true und der Text "true" (beliebige Groß- und Kleinschreibung) zählen als lokal. false, null, 1, "yes" und jeder andere Wert öffnen das Relay für das Netzwerk; der Standard gilt nur, wenn der Key fehlt. oar setup schreibt den Key als true oder false. Eine Änderung braucht oar restart.

oar setup, oar url und oar status lesen den Key anders: Für sie zählt nur der Boolean false als LAN-Zugriff, und oar doctor zeigt localhostOnly: no nur bei false. Mit einem Wert wie null oder "no" lauscht das Relay auf allen Schnittstellen, während diese Befehle this machine only (nur dieser Rechner) melden. Setz den Key nur auf true oder false. Siehe config.json.

Im LAN ist das Token die einzige Schranke: Das Relay prüft nicht, woher eine Anfrage kommt. Mit dem Zugriff this machine only kann sich ein Handy erst verbinden, wenn du den LAN-Zugriff einschaltest oder einen Tunnel nutzt. localhostOnly wirkt sich nicht auf die verwalteten Tunnel aus, die vom Rechner nach außen verbinden.

Ein Relay hinter einem Proxy oder Tunnel auf demselben Rechner kann this machine only bleiben. Welchen Proxys das Relay die X-Forwarded-*-Header glaubt, legt trustProxy fest (Standard loopback); davon hängt ab, ob es eine Verbindung als HTTPS behandelt und das Cookie als Secure markiert.

Was das Token braucht #

Alles, was deine Konversationen, Dateien, Einstellungen oder Agents liest oder ändert, braucht das Token. Das hier sind die Ausnahmen, und zwar alle.

Pfad Braucht das Token? Was es liefert
/ und /index.html Nein Die Web-App und ihr Anmeldefeld
Die Skript-, Style- und Icon-Dateien der Web-App, /sw.js, /socket.io/socket.io.js Nein Die App selbst, die keine deiner Daten enthält
/manifest.webmanifest Nein Das Installationsmanifest. Es trägt den App-Namen, den du in Settings (Einstellungen) setzt
/shared/<link token> Nein Die Seite einer geteilten Konversation
/api/shared/<link token> und seine Routen für Anwesenheit, Uploads und generierte Bilder Nein, aber ein gültiges, nicht widerrufenes Link-Token Nur-Lese-Zugriff auf genau diese Konversation. Siehe Teilen
Preview-Links auf dem Preview-Host Nein, aber ein gültiges Preview-Token Nur die App in der Preview; der Preview-Host liefert das Relay nicht aus. Siehe Previews
/api/... (alle anderen Routen) Ja Konversationen, Einstellungen, Dateien, Status, Previews, Kopplung
Die Live-Verbindung (Socket.IO) Ja, und Neu in 0.9.11 ein Browser muss sie von der eigenen Adresse des Relays aus öffnen Die Live-Updates der App. Siehe allowedOrigins für einen Proxy, der den Host umschreibt
Die Verbindung der Worker zum Relay Ja Wird von den eigenen Prozessen deiner Agents auf diesem Rechner genutzt
Dateien von deinen Laufwerken und aus dem Workspace, Uploads und generierte Bilder unter ihrer eigenen Adresse Ja Ein Betrachter eines geteilten Links kann sie so nicht laden; die geteilten Routen oben liefern die, die diese Konversation nutzt. Siehe Medien und Dateien

Es gibt keinen Health- oder Versions-Endpunkt ohne Authentifizierung: /api/status, das oar status aufruft, braucht das Token.

Geteilte Links und Preview-Links sind absichtlich öffentlich. Das zufällige Token des Links ist ihr einziger Schutz, also schließ oder widerrufe sie, wenn du fertig bist. Dateien, die das Relay ausliefert, werden mit einer Sandbox-Policy gesendet, sodass eine ausgelieferte HTML- oder SVG-Datei kein Skript auf dem Origin des Relays ausführen kann.

Die Verbindung der Worker beantwortet nur Anfragen vom eigenen Rechner des Relays, die kein Proxy und kein Tunnel weitergeleitet hat; alles andere wird mit 403 abgelehnt, bevor das Token geprüft wird. Geteilte Links über einen Tunnel sind nicht betroffen. Siehe Der Pfadschutz des Session-Workers.

Schutz bei der Anmeldung #

  • Bei der Anmeldung und für die Live-Verbindung vergleicht das Relay Tokens in konstanter Zeit.
  • Neu in 0.9.11 Zehn falsche Tokens sperren eine Adresse für eine Minute. Zehn falsche Tokens von einer Client-Adresse innerhalb einer Minute, ob im Header, im Cookie, im Anmeldefeld oder beim Handshake einer Live-Verbindung, bringen das Relay dazu, dieser Adresse mit 429 und Retry-After zu antworten, bis die Minute um ist, auch beim richtigen Token. Das Anmeldefeld zeigt Too many failed sign-in attempts. Try again in 42 seconds. (Zu viele fehlgeschlagene Anmeldeversuche. Versuch es in 42 Sekunden erneut.) Derselbe falsche Wert zählt bei Wiederholung nur einmal, ein Tab mit einem alten Cookie sperrt dich also nicht aus. Das Relay schreibt eine Logzeile, die mit [auth] beginnt, wenn es eine Adresse abweist.
  • Anfragen vom eigenen Rechner des Relays, die kein Proxy und kein Tunnel weitergeleitet hat, werden nie gezählt und nie gesperrt, sodass die Worker des Relays und die Tools der Agents weiter funktionieren.
  • Die Client-Adresse ist die, der das Relay vertraut. Hinter einem Proxy auf einem anderen Rechner, dem das Relay nicht vertraut, hat jeder Client die Adresse des Proxys, und die falschen Tokens eines Clients sperren alle aus.
  • Die Sperre bremst das Raten; sie ersetzt kein gutes Token. Halte das Token lang und zufällig: oar setup erzeugt eins; ersetze es nicht durch ein kurzes Wort.
  • Das einzige Rate-Limit auf Routen ohne Token gilt für die Anwesenheits-Pings geteilter Konversationen: 24 pro 10 Sekunden für jeden geteilten Link und jede Client-Adresse. Neu in 0.9.11 Die Client-Adresse folgt trustProxy, wie bei der Sperre, sodass ein Client sich nicht durch Senden von X-Forwarded-For seine eigene aussuchen kann.
  • Das Token wird nicht ins Log geschrieben, außer wenn die Config keins hat und das Relay beim Start ein vorübergehendes erzeugt. oar start und oar url geben es in deinem Terminal aus.

Agents und das Token #

Deine Agents laufen als Prozesse des Benutzers, unter dem das Relay läuft, auf dem Rechner des Relays. Sie bekommen keine eigenen Zugangsdaten: Um mit dem Relay zu sprechen, lesen sie das Token des Relays aus config.json und schicken es, wie es der Besitzer täte. Das Relay legt das Token weder in die Umgebung noch in den Prompt eines Agents, aber ein Agent läuft als derselbe Betriebssystembenutzer und kann daher die Datei und damit das Token lesen. Dasselbe gilt für alles, was ein Agent ausführt. Geh davon aus, dass jeder Agent, den du laufen lässt, das Token kennt, und lass Agents nur unter einem Benutzer laufen, dem du das Relay anvertraust.

Das Relay verrät Agents nicht das Token eines gekoppelten Relays: Agents erreichen ein gekoppeltes Relay über dieses Relay, das das gespeicherte Token hinzufügt (Remote-Relays). Ein Agent handelt außerdem mit den Rechten des Benutzers, unter dem das Relay läuft: Alles, was der Besitzer des Relays auf dem Rechner tun kann, kann man auch einen Agent tun lassen.

Einfaches HTTP im LAN #

Mit LAN-Zugriff und einer http://-Adresse gehen das Token und das Cookie unverschlüsselt durchs Netzwerk. Wer diesen Verkehr mitlesen kann, kann das Token lesen. Nutze das in einem Netzwerk, dem du vertraust, oder stell HTTPS davor. Bei einfachem HTTP wird das Cookie nicht als Secure markiert.

Die Installation von OAR als App und Push-Benachrichtigungen brauchen HTTPS oder localhost; beides funktioniert also nicht unter einer einfachen LAN-Adresse: siehe Als App installieren und Benachrichtigungen.

Wenn du glaubst, das Token ist durchgesickert #

  1. Führ oar setup --new-token aus und lass es das Relay neu starten. Jeder Browser wird abgemeldet. Lehnst du den Neustart ab, führ oar restart aus: Bis dahin funktioniert das alte Token noch.
  2. Melde dich mit der Adresse aus oar url erneut an.
  3. Füge dieses Relay auf jedem Relay, das du damit gekoppelt hast, mit dem neuen Token erneut hinzu (Remote-Relays).
  4. Prüf, wo das Token gespeichert war: Skripte, Shell-Verlauf, die Adresse, die du in einen Chat eingefügt hast, und Kopien oder Backups von config.json.
  5. Beende oder erneuere geteilte Links unter Settings → Sharing (Einstellungen → Teilen) (Deine geteilten Links) und schließ Previews, die du nicht kennst. Die haben eigene Tokens.
  6. Wenn jemand das Relay nutzen konnte, während es offen lag, sieh nach, was seine Agents getan haben. Wer das Token hat, kann Agents starten, die Befehle als Benutzer des Relays ausführen.