Digitaler Samba Blog Deutsch

SRTP-Authentifizierungsfehler beim RTP-Forwarding in Janus beheben

Geschrieben von Nina Benkotic | Februar 27, 2026

 Beim Aufbau einer WebRTC-Infrastruktur im grossen Massstab entstehen die meisten Probleme im Produktivbetrieb nicht durch fehlerhafte Verschlüsselung oder fehlgeschlagene Aushandlungen.
Sie entstehen durch subtile Zustandsabweichungen zwischen Komponenten, die für sich genommen korrekt funktionieren, aber mit der Zeit nicht mehr sauber aufeinander abgestimmt sind. 

Ein solcher Fall, den wir kürzlich untersucht haben, betraf sporadisch auftretende SRTP-Auth-Fail-Fehler beim RTP-Forwarding in Janus. Auf den ersten Blick sah es nach einem kryptografischen Problem aus. Tatsächlich handelte es sich jedoch um eine Desynchronisation des Rollover Counters, ausgelöst durch die Wiederverwendung der SSRC im Browser – und das Problem zeigte sich erst nach mehreren Minuten kontinuierlicher Medienübertragung.

In diesem Artikel erfährst du, was genau passiert ist, warum es dazu kommt und wie du das Problem in produktiven Systemen zuverlässig behebst.

 Inhaltsverzeichnis 

  1. Das Szenario

  2. SRTP und die 16-Bit-Sequenznummer

  3. Warum das Problem erst nach mehreren Minuten auftritt

  4. Warum RTP-Forwarding besonders anfällig ist

  5. Fehleranalyse

  6. Die praktische Lösung: Eine neue SSRC erzwingen

  7. Warum nicht versuchen, den ROC neu zu synchronisieren?

  8. Betriebliche Überlegungen

  9. Erkenntnisse für deine WebRTC-Infrastruktur

  10. Abschliessende Gedanken

Das Szenario

In einer typischen Deployment-Umgebung fungiert Janus als Selective Forwarding Unit (SFU). Dabei empfängt Janus verschlüsselte Medienströme von den Teilnehmenden und leitet sie entweder an andere Teilnehmende, externe Systeme, Recording-Pipelines oder Broadcast-Endpunkte weiter.

Im Normalbetrieb funktioniert die Medienpipeline stabil und vorhersehbar. Verschlüsselte Audio- und Videoströme werden sicher über SRTP übertragen, das RTP-Forwarding wird mit einer klar definierten SSRC eingerichtet, und eingehende Pakete werden ohne Probleme authentifiziert und entschlüsselt. Solange der Transportzustand auf beiden Seiten konsistent bleibt, gewährleistet das System Integrität, Vertraulichkeit und eine stabile Medienübertragung während der gesamten Sitzung.

Unter bestimmten Umständen begann das Forwarding jedoch plötzlich zu scheitern – mit Fehlermeldungen wie:
SRTP unprotect error: srtp_err_status_auth_fail

Interessanterweise trat das Problem nicht unmittelbar nach dem Beitritt eines Teilnehmenden auf. Es zeigte sich auch nicht in jeder Sitzung. Der Fehler erschien erst, nachdem:

  • eine Person Kamera oder Mikrofon mehrere Minuten lang aktiviert hatte

  • die Medienübertragung deaktiviert und später wieder aktiviert wurde

  • das RTP-Forwarding weiterhin die ursprüngliche SSRC verwendete

Der Schlüssel zum Verständnis dieses Problems liegt darin, wie SRTP die Paketintegrität nachverfolgt.

SRTP und die 16-Bit-Sequenznummer

SRTP schützt RTP-Streams vor Replay-Angriffen, indem es einen Paketindex verwendet, der sich aus zwei Komponenten zusammensetzt:

  • der 16-Bit-RTP-Sequenznummer
  • einem Rollover Counter (ROC)

Der RTP-Header enthält eine 16-Bit-Sequenznummer, die sich mit jedem gesendeten Paket um eins erhöht. Dadurch kann die empfangende Seite Paketverluste erkennen, eingehende Pakete korrekt sortieren und Duplikate identifizieren. Da dieses Feld jedoch auf 16 Bit begrenzt ist, springt es nach 65.536 Paketen wieder auf null zurück. Bei längeren Mediensitzungen ist deshalb ein zusätzliches Rollover-Tracking notwendig.

Hier kommt der Rollover Counter ins Spiel. Der ROC erhöht sich jedes Mal, wenn die 16-Bit-Sequenznummer einen Wrap durchläuft. Dadurch wird der effektive Paketindex erweitert, den SRTP für Authentifizierung und Replay-Schutz verwendet. Sender und Empfänger müssen dabei exakt denselben ROC-Status führen. Weichen ihre Annahmen voneinander ab, schlägt die Paket-Authentifizierung fehl, weil unterschiedliche Rollover-Stände zugrunde gelegt werden.

Die Sequenznummer im RTP ist also nur 16 Bit lang. Nach 65.536 Paketen erfolgt ein Wrap, und der ROC wird inkrementiert. Zusammen bilden Sequenznummer und ROC einen 48-Bit-Paketindex, der für die Authentifizierung genutzt wird.

Dieses Design funktioniert zuverlässig, bringt aber Zustandsabhängigkeit mit sich. Sender und Empfänger müssen nicht nur denselben aktuellen Sequenzfortschritt kennen, sondern auch wissen, wie oft die Sequenznummer bereits übergelaufen ist. Sobald es hier eine Abweichung beim ROC gibt, scheitert die Authentifizierung.

Entscheidend ist zudem: Durch die 16-Bit-Begrenzung tritt der erste Wrap – und damit die erste ROC-Erhöhung – nicht sofort ein. Bei üblichen Videopaket-Raten dauert es mehrere Minuten kontinuierlicher Übertragung, bis der Zähler überläuft.

Genau dieses zeitliche Verhalten machte das Problem besonders subtil.

Warum das Problem erst nach mehreren Minuten auftritt

In der Anfangsphase einer Sitzung erhöht sich die Sequenznummer zwar kontinuierlich, erreicht jedoch noch keinen Wrap. Der ROC bleibt bei null. Wenn eine Person in dieser Phase ihre Kamera deaktiviert und später wieder aktiviert, kann sich das Sequenzverhalten zwar ändern oder neu beginnen, doch die ROC-Ausrichtung bleibt häufig noch konsistent, da sich beide Seiten effektiv noch im ersten 16-Bit-Fenster befinden.

Sobald jedoch genügend Pakete übertragen wurden und die Sequenznummer einen Wrap durchläuft, ändert sich die Situation grundlegend. Der Sender erhöht seinen Rollover Counter, sobald die 16-Bit-Sequenznummer nach Erreichen ihres Maximalwerts wieder bei null beginnt. Der Empfänger aktualisiert seinen ROC ebenfalls, sobald er erkennt, dass die eingehende Sequenznummer übergelaufen ist. Ab diesem Zeitpunkt sind beide Seiten darauf angewiesen, exakt denselben Rollover-Status zu führen, da die SRTP-Authentifizierung nur funktioniert, wenn der Paketindex auf identischen ROC-Werten basiert.

Wird die Medienübertragung im Browser später neu gestartet und dabei der interne SRTP-Zustand zurückgesetzt, während gleichzeitig dieselbe SSRC weiterverwendet wird, springt der ROC auf Senderseite wieder auf null zurück. Janus hingegen kann beim Forwarding weiterhin vom zuvor gültigen ROC ausgehen. Ab diesem Moment schlägt die Paket-Authentifizierung fehl.

Das Problem tritt also nicht sofort auf. Es setzt voraus, dass die Medienübertragung lange genug aktiv war, um mindestens einen 16-Bit-Wrap auszulösen, dass der Browser die Medienübertragung neu startet, dass die SSRC unverändert bleibt und dass das Forwarding weiterhin den bestehenden SRTP-Kontext verwendet. Erst wenn all diese Bedingungen zusammenkommen, wird die Diskrepanz sichtbar.

Browser-Verhalten: Wiederverwendung der SSRC

Moderne Browser versuchen, Sitzungen möglichst konsistent erscheinen zu lassen. Wenn eine Person ihre Kamera oder ihr Mikrofon deaktiviert und später wieder aktiviert, behält der WebRTC-Stack häufig dieselbe SSRC bei, um die Stream-Identität aufrechtzuerhalten. Gleichzeitig kann intern die Paket-Sequenzierung neu gestartet und der SRTP-Zustand so initialisiert werden, als beginne der Medienfluss von vorne. Aus Sicht des Browsers ist dieses Verhalten vollkommen legitim: Die Identität des Streams bleibt bestehen, eine erneute Signalisierung der SSRC ist nicht zwingend erforderlich, und nachgelagerte Komponenten können den Stream weiterhin als denselben behandeln.

SRTP-Replay-Schutz ist jedoch zustandsbehaftet. Wenn Janus beim Forwarding den bestehenden SRTP-Kontext verwendet, der an diese SSRC gebunden ist, behält es den alten ROC-Wert bei und erwartet eine Sequenzfortschreibung, die zu den zuvor empfangenen Paketen passt. Eingehende Pakete, die auf einem zurückgesetzten internen Zustand des Browsers basieren, werden dann als nicht authentifiziert verworfen.

Das Ergebnis ist der Fehler: srtp_err_status_auth_fail.

Warum RTP-Forwarding besonders anfällig ist

Innerhalb eines Raums verwaltet Janus Peer-Streams dynamisch. Es kann flexibler auf Renegotiation-Events reagieren und interne Zustandsänderungen besser nachverfolgen.

RTP-Forwarding hingegen wird in der Praxis meist einmal zu Beginn einer Sitzung eingerichtet und anschliessend als stabile, langfristige Pipeline behandelt. In der Regel wird davon ausgegangen, dass die SSRC konstant bleibt, der zugehörige SRTP-Kontext während der gesamten Lebensdauer des Streams bestehen bleibt und das Rollover-Tracking ohne Unterbrechung weiterläuft. Unter gleichbleibenden Bedingungen funktioniert dieses Modell zuverlässig, solange die Medienübertragung kontinuierlich erfolgt und kein interner Zustand während der Sitzung zurückgesetzt wird.

Problematisch wird es, wenn der Browser die Medienübertragung neu startet, dabei aber dieselbe SSRC beibehält. Die Forwarding-Schicht hält weiterhin am bisherigen Replay-Schutz-Zustand fest, ohne zu erkennen, dass der Sender seine internen Zähler zurückgesetzt hat. Aus Sicht des Senders beginnt der Stream faktisch neu, während der Forwarding-Kontext davon ausgeht, dass es sich um einen ununterbrochenen Paketfluss handelt. Dadurch driften die berechneten Paketindizes auseinander, und die SRTP-Authentifizierung schlägt fehl, weil die Rollover-Annahmen auf beiden Seiten nicht mehr übereinstimmen.

Fehleranalyse

In Produktivumgebungen kann dieses Verhalten besonders verwirrend sein. Der Fehler tritt erst nach mehreren Minuten kontinuierlicher Medienübertragung auf, hängt von einer ganz bestimmten Nutzerinteraktion ab – nämlich dem Deaktivieren und erneuten Aktivieren von Kamera oder Mikrofon – und wirkt dadurch oft sporadisch. Zusätzlich lässt sich das Problem beheben, indem das Forwarding auf einen anderen Janus-Streaming-Plugin-Kontext beziehungsweise Port neu gestartet wird.

Ein entscheidender Hinweis bei der Analyse ist das zeitliche Muster. Wenn die Fehler ausschliesslich nach längerer Medienaktivität auftreten und nicht bei kurzen Sitzungen, sollte ein Sequenznummern-Überlauf sofort als mögliche Ursache in Betracht gezogen werden.

Ein weiteres starkes Indiz ist, dass ein Neustart des Forwardings das Problem löst, ohne dass Verschlüsselungsschlüssel neu ausgehandelt werden müssen. Das deutet klar auf eine Zustandsdesynchronisation hin – nicht auf ein Problem mit den kryptografischen Parametern selbst.

Die praktische Lösung: Eine neue SSRC erzwingen

Die robusteste und betrieblich sicherste Lösung ist vergleichsweise einfach: Wenn die Medienübertragung neu gestartet wird, solltest du das RTP-Forwarding stoppen und es mit einer neuen SSRC neu initialisieren.

Durch das Zuweisen einer neuen SSRC beim Neustart entsteht eine saubere Trennlinie für den Stream. Es wird ein frischer SRTP-Kontext aufgebaut, der Rollover Counter beginnt wieder im Ausgangszustand, und Sender wie Empfänger berechnen ihren Paketindex erneut auf einer gemeinsamen Basis. Mit dieser Neuausrichtung funktioniert die SRTP-Authentifizierung wieder zuverlässig, da es keine unterschiedlichen Annahmen mehr über Rollover-Historie oder Paketnummerierung gibt.

In der Praxis bedeutet das, dass du Veränderungen im Media-Lifecycle erkennen musst, etwa beim Austausch eines Tracks, beim erneuten Aktivieren von Kamera oder Mikrofon oder bei einer Renegotiation des Publishers. Tritt ein solcher Zustand ein, sollte die bestehende RTP-Forwarding-Session beendet und eine neue mit explizit gesetzter SSRC gestartet werden. So verhinderst du, dass veralteter Replay-Schutz-Zustand weiterverwendet wird, und stellst sicher, dass die Verschlüsselungskontexte über alle beteiligten Komponenten hinweg synchron bleiben.

Warum nicht versuchen, den ROC neu zu synchronisieren?

Theoretisch könnte man versuchen, eine Abweichung beim Rollover Counter zu erkennen und ihn dynamisch neu zu synchronisieren. In der Praxis ist dieser Ansatz jedoch komplex und riskant.

Der SRTP-Replay-Schutz wurde gezielt entwickelt, um Paket-Injektionen und Replay-Angriffe zu verhindern. Wenn du Validierungsregeln aufweichst, um mit einem unsicheren Rollover-Zustand umzugehen, untergräbst du genau diese Sicherheitsgarantien.

Zudem ist es alles andere als trivial, den korrekten ROC-Wert mitten im laufenden Stream zuverlässig zu rekonstruieren. Die Erkennung eines Rollover-Ereignisses basiert auf einer präzisen Annahme über Sequenzfortschritt und Timing, die nach einem Media-Neustart möglicherweise nicht mehr gilt. Um diesen Zustand nachträglich korrekt abzuleiten, müsstest du den Paketfluss sehr genau analysieren, ohne dabei Mehrdeutigkeiten zu erzeugen.

Fehler in dieser Logik können entweder dazu führen, dass gültige Pakete fälschlicherweise verworfen werden, oder – im schlimmsten Fall – dass wiederholte Pakete akzeptiert werden. Beides ist in produktiven Systemen problematisch, in denen Stabilität und Sicherheit gleichermassen gewährleistet sein müssen.

Hinzu kommt, dass sich das Verhalten je nach Browser und WebRTC-Implementierung leicht unterscheidet. Verschiedene Stacks gehen unterschiedlich mit SSRC-Wiederverwendung und SRTP-Neuinitialisierung um. Diese Inkonsistenzen erschweren es, eine generische, zuverlässig funktionierende Recovery-Logik für heterogene Client-Umgebungen zu implementieren.

Für produktive Systeme ist eine deterministische Neuinitialisierung daher deutlich sicherer als eine heuristische Reparatur des Zustands.

Betriebliche Überlegungen

In grossen WebRTC-Deployments sind Media-Neustarts kein Sonderfall, sondern Teil des normalen Betriebs. Nutzer schalten ihre Kamera oder ihr Mikrofon regelmässig ein und aus, Netzwerkschwankungen können Renegotiation-Events auslösen, und Hardware wie Webcams oder Headsets wird während laufender Sitzungen ab- und wieder angesteckt. Diese alltäglichen Abläufe führen zu häufigen Lifecycle-Übergängen, die deine Infrastruktur sauber verarbeiten muss, ohne von einer durchgehend stabilen Medienkontinuität auszugehen.

Vor diesem Hintergrund solltest du Forwarding-Pipelines so gestalten, dass sie Media-Neustarts als klare Identitätsgrenzen behandeln. Selbst wenn die SSRC stromaufwärts unverändert bleibt, darf der Forwarding-Kontext nach einer Geräte- oder Track-Neukonfiguration nicht automatisch von Kontinuität ausgehen.

Praktisch bedeutet das: Du solltest Track-Level-Änderungen überwachen, den Sequenzfortschritt für Diagnosezwecke protokollieren und bei Neustart-Events konsequent eine SSRC-Rotation erzwingen. So stellst du sicher, dass dein Forwarding auch bei unvorhersehbarem Client-Verhalten stabil und robust bleibt.

Erkenntnisse für deine WebRTC-Infrastruktur

Dieser Fall verdeutlicht mehrere grundlegende Prinzipien moderner Systemarchitektur:

1. Historische Feldgrössen sind weiterhin relevant

Die 16-Bit-Sequenznummer im RTP ist eine Designentscheidung aus einer anderen Ära. Ihre Begrenzung wird in heutigen High-Bitrate-Video-Szenarien sichtbar, in denen ein Wrap relativ schnell erreicht wird. Selbst kleine Header-Felder können unerwartetes Verhalten verursachen, wenn Zustände über Neustarts hinweg bestehen bleiben.

2. Zustandsbehaftete Systeme erfordern Lifecycle-Disziplin

Verschlüsselungskontexte sind keine stateless Wrapper. Sie bauen implizite Annahmen über Paketreihenfolge und Rollover auf. Wenn sich der Lifecycle eines Streams ändert, musst du auch den kryptografischen Zustand neu bewerten – selbst dann, wenn die Signalisierung oberflächlich stabil wirkt.

3. Kontinuität ist nicht auf allen Ebenen gleichbedeutend

Browser optimieren auf Anwendungsebene für wahrgenommene Kontinuität. Media-Server priorisieren Transportintegrität. Forwarding-Pipelines gehen oft von stabiler Stream-Identität aus. Diese Perspektiven sind nicht automatisch deckungsgleich. Erst durch explizites Lifecycle-Management stellst du sicher, dass alle Ebenen konsistent zusammenspielen.

Abschliessende Gedanken

SRTP-Authentifizierungsfehler werden oft als kryptografische Anomalien interpretiert. In der Praxis handelt es sich jedoch häufig um Zustandsprobleme, die durch vollkommen gültiges Verhalten auf einer anderen Ebene ausgelöst werden.

In diesem Fall führte die Kombination aus einem 16-Bit-Paketzähler, einem ROC-Inkrement nach mehreren Minuten, der Wiederverwendung der SSRC im Browser und persistenten Forwarding-Kontexten zu einer engen, aber reproduzierbaren Fehlersituation.

Die Lösung bestand nicht darin, die Verschlüsselung anzupassen oder den Replay-Schutz abzuschwächen. Entscheidend war vielmehr, den Media-Neustart als klare Grenze zu behandeln und die SSRC konsequent zu rotieren.

In produktiven WebRTC-Systemen entsteht Stabilität oft dadurch, dass du erkennst, wann sich Identität ändern muss – selbst wenn stromaufwärts alles nach Kontinuität aussieht.

Ein tiefes Verständnis dieser subtilen Protokoll-Interaktionen ist essenziell, wenn du Selective Forwarding Units im grossen Massstab betreibst. Manchmal ist die sicherste Lösung kein komplexer Algorithmus, sondern ein sauberer Reset zum richtigen Zeitpunkt.

Bei Digital Samba entwickeln wir unsere Media-Infrastruktur kontinuierlich weiter, um skalierbare, zuverlässige und sichere Videokommunikation zu gewährleisten. Herausforderungen wie diese zeigen, dass Echtzeitsysteme sowohl fundiertes Protokollwissen als auch sorgfältiges Lifecycle-Design erfordern.