webentwicklung-frage-antwort-db.com.de

Warum wird meine Verbindung mit wss: // (WebSockets über SSL/TLS) sofort getrennt, ohne dass Fehler auftreten?

Dies für alle anderen veröffentlichen, die das gleiche Problem haben.

Ich arbeitete an einem Browser-Client, der stanza.io verwendete, um sich mit einem XMPP-Server (in meinem Fall Prosody) zu verbinden. Ich habe standardmäßig eine wss: // Verbindung verwendet. Zu irgendeinem Zeitpunkt während der Entwicklung konnte mein Client überhaupt keine Verbindung herstellen - er würde sofort die Verbindung trennen, ohne irgendwelche nützlichen Fehlerinformationen anzugeben.

Es gab keine Fehlerprotokolle, keine Fehlercodes, keine Bestätigungsdialogfelder oder Balken, keine Hinweise auf mögliche Fehler.

18
Sven Slootweg

Nach stundenlangem Debugging fand ich schließlich das Problem. Während ich mich mit der Konfiguration meines XMPP-Servers herumplünderte, hatte ich die SSL-Zertifikate für das XMPPd neu generiert. Da ich selbstsignierte Zertifikate verwendet habe, würde dies einen SSL-Fehler verursachen. Da ich dieselbe URI bereits zuvor über HTTPS besucht hatte, hatte ich das alte selbstsignierte Zertifikat bereits manuell genehmigt. Die Genehmigung war jedoch nach dem erneuten Generieren des SSL-Zertifikats nicht mehr gültig.

Der Schlüssel zum Problem ist folgender: Wenn Ihr SSL-Zertifikat eine Warnung jeglicher Art auslöst, schlagen wss:// WebSocket-Verbindungen sofort fehl und es gibt keine kanonische Möglichkeit, dies zu erkennen.

Wie oben erwähnt, scheint es keine standardisierte Methode zu geben, um überhaupt zu erkennen, dass dieses Problem auftritt, geschweige denn lösen. Die beste Lösung für dieses Problem, die ich finden konnte, lautet wie folgt:

  1. Wenn das WebSocket die Verbindung trennt, bevor eine Anmeldebestätigung (XMPP-spezifisch) empfangen wurde, versuchen Sie, eine Klartextverbindung ws:// ( ohne SSL ) mit dem Nicht-SSL-Port herzustellen.
  2. Wenn die Klartextverbindung erfolgreich ist, bedeutet dies, dass der Server in Betrieb ist - das Problem liegt also beim SSL-Zertifikat. (Wenn auch die Klartextverbindung fehlschlägt, ist der Server einfach nicht verfügbar.)
  3. Zeigen Sie dem Benutzer einen Fehler an, der darauf hinweist, dass ein SSL-Problem aufgetreten ist und dass das Zertifikat überprüft werden sollte. Anweisungen dazu, wie Sie es manuell genehmigen können.
  4. Stellen Sie einen target="_blank"-Link zur wss://-URL bereit, ersetzen Sie jedoch das Protokoll durch https://. Möglicherweise handelt es sich dabei um ein spezifisches Verfahren, aber beim Aufrufen dieser URL wird die SSL-Warnseite angezeigt. Prosody zeigt einen Text an, der mit "It works!" Beginnt. Nachdem Sie das Zertifikat genehmigt haben - Wenn es sich bei der Serverseite um eine benutzerdefinierte Anwendung handelt, sollten Sie die folgende Meldung anzeigen: "Das Problem wurde behoben, Sie können diese Registerkarte jetzt schließen.".
  5. Versuchen Sie im Hintergrund, in der Hauptanwendung, die Verbindung über wss: // alle paar Sekunden erneut herzustellen. Wenn eine Verbindung hergestellt wurde, bedeutet dies, dass der Benutzer das Zertifikat genehmigt hat. Den Fehler ausblenden/entfernen und den normalen Verbindungs-/Anmeldeprozess fortsetzen.

Es ist alles andere als ein reibungsloser Prozess, aber es ist der glatteste Ansatz, den ich gefunden habe. Es ist nicht möglich, die Fehlerseite zu formatieren (dies war eine meiner ersten Ideen) - Chrome lehnt das Laden ab, Firefox versteckt die Schaltfläche "Ausnahme hinzufügen", und ich denke, andere Browser weisen ein ähnliches Verhalten auf.

31
Sven Slootweg

Denken Sie daran, dass moderne Browser keine selbstsignierten Zertifikate mögen. Wenn Ihre sichere WebSocket-Verbindung vor dem Beenden des Handshakes unterbrochen wird, kann dies bedeuten, dass das Zertifikat nicht akzeptiert wurde. Um das Problem zu lösen, können Sie:

  • ein von einer zentralen Behörde unterzeichnetes Zertifikat erwerben 
  • Öffnen Sie einfach in einem neuenTab oder Fenster den Link Ihrer WebSocket-URI und teilen Sie dem Browser mit, dass die Verbindung hergestellt werden soll. Gehen Sie zu Ihrem WebSocket zurück und es sollte funktionieren.
2
giuseppe
0
SadSeven