Ticketing
Dokumentation

Auth-Handshake

Ein gemeinsamer Schritt, der byte-genau identisch vom Client-Port und dem Raft-Port des Clusters verwendet wird. Sobald die Verbindung steht (nach Abschluss des TLS-Handshakes, falls TLS verwendet wird), spricht der Server zuerst und sendet eine Challenge. Es ist ein zweizeiliger, durch Zeilenumbruch (\n) getrennter Textaustausch, der einmal pro Verbindung durchgeführt wird.

Das Einzige, was sich je Port unterscheidet, ist welcher Token-Satz zur Verifikation verwendet wird — der Client-Port verifiziert gegen client_tokens, der Raft-Port gegen cluster_tokens. Die Raft-port-spezifischen Token-Regeln (welches Token gesendet wird und wie man Tokens ohne Ausfallzeit rotiert) findest du unter Verbindung & Auth (Cluster).

Ablauf

Verbindender (Client · Peer)
Server
TCP-Verbindungsaufbau · (TLS-Handshake)
Challenge: SHA-256 ␣ Nonce
digest = SHA-256(token ∥ nonce) · 43 Zeichen
Vergleich in konstanter Zeit mit der gesamten Token-Liste
Erfolg → keine Antwort, das eigentliche Protokoll startet sofort
erste Anfrage sofort gesendet (z. B. A · acquire)
falls fehlgeschlagen
E · auth_failed → Verbindung geschlossen
AnfrageAntwort

1. Challenge (Server → Verbindender)

Strukturrefresh
<hash> <nonce>\n            z. B. SHA-256 aB3dEf_g\n
FeldInhalt
hashName des Digest-Algorithmus. Derzeit immer SHA-256, und der Server akzeptiert nichts anderes
nonceEin 8 Zeichen langer base64url-Zufallswert. Die Rahmung ist durch Zeilenumbruch getrennt, daher kann seine Länge später wachsen — der Verbindende muss alles nach dem ersten Leerzeichen als Nonce behandeln

2. Antwort (Verbindender → Server)

Strukturrefresh
<digest>\n

digest = base64url_nopad( SHA-256( token_bytes ∥ nonce_bytes ) )

( ist Byte-Verkettung — die ASCII-Bytes der Nonce-Zeichenkette werden direkt an die rohen Bytes des Tokens angehängt)

  • base64url ist das ungepaddete, URL-sichere Alphabet (A–Z a–z 0–9 - _). Ein SHA-256-Digest hat immer 43 Zeichen.
  • Der Server verifiziert mit einem Vergleich in konstanter Zeit gegen die gesamte konfigurierte Token-Liste — welches Token übereinstimmte oder wie weit ein Vergleich kam, sickert niemals über das Timing durch.
  • Ein Server ohne konfigurierte Tokens akzeptiert ein einzelnes leeres Token "". In diesem Fall besteht das Senden von digest = base64url(SHA-256(nonce)) die Prüfung. Der Handshake selbst kann niemals übersprungen werden.
  • Die vom Server gelesene Antwortzeile ist auf 256 Byte begrenzt.

3. Ergebnis

  • Erfolg: Der Server sendet nichts und wechselt direkt in das Hauptprotokoll — das binäre Frame-Sperrprotokoll auf dem Client-Port, oder längen-präfixierte RPC auf dem Raft-Port. Sende die erste Anfrage sofort.
  • Fehlschlag: Der Server sendet E auth_failed und schließt die Verbindung. Bricht die Verbindung mitten im Handshake ab oder ist eine Zeile fehlerhaft, kann er auch einfach still schließen, ohne einen Fehler-Frame zu senden.

Begriffe

  • Challenge-Response — ein Authentifizierungsschema, bei dem der Server, statt das Geheimnis (Token) direkt zu senden, eine einmalige Challenge stellt und der Verbindende beweist, dass er das Geheimnis kennt, indem er nur die Antwort zurücksendet.
  • Nonce — eine nur einmal verwendete Zahl (number used once). Sie ändert sich bei jeder Verbindung, sodass eine gestohlene Antwort nicht in einem Replay-Angriff wiederverwendet werden kann.
  • Vergleich in konstanter Zeit (constant-time compare) — ein Vergleich, der unabhängig davon, wie weit er übereinstimmte, immer gleich lange dauert und so Timing-Angriffe ausschließt, die sonst das Geheimnis preisgeben würden.
  • base64url — eine base64-Variante, die nur ein URL-sicheres Alphabet (A–Z a–z 0–9 - _) verwendet. Hier ohne Padding (=) genutzt.