Websockets reverse-proxy in IIS 8
Ich bin versucht, eine Verbindung zu einer websockets-server (websockify) durch einen reverse-proxy auf IIS. Der IIS und websockets server befinden sich auf demselben physischen server (Windows Server 2012 R2, IIS 8.5, ARR 3, Websockets aktiviert ist). Ich habe gesehen, ein paar Fragen zu diesem, und es ist vorgeschlagen, dieser sollte mit IIS 8 und ARR 3, aber keine tatsächlichen Lösungen noch. Ich habe einige Erfahrung mit http/https-reverse-Proxys im IIS, aber dies ist mein Erster Versuch der Arbeit mit websockets.
Beispiel:
Den original-url:
ws://10.2.1.10/websockify
Den reverse-proxy-Anforderungen zu übersetzen, diese zu:
ws://10.2.1.10:5901/websockify
Allzu Allgemeinen Beispiel-Regel im web.config:
<rewrite>
<rules>
<rule name="WS reverse proxy" stopProcessing="true">
<match url="(.*)" />
<conditions> <add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<action type="Rewrite" url="{C:1}://10.2.1.10:5901/websockify"/>
</rule>
</rules>
</rewrite>
Pro die Fehlgeschlagene Anforderung Spur, die url scheint übersetzt zu werden, aber für einige Grund es nicht erreichen das websocket-server auf 10.2.1.10:5901.
Dem Ziel, sich zu integrieren noVNC/websockify zu bieten browser-basierte client-Zugriff auf verschiedene VNC-Server auf dem Netzwerk. Jede Hilfe, die verstehen, wie-reverse-proxy die websockets geschätzt wird.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hatte ich schon versucht zu erreichen, die gleiche Sache auf IIS 8.5 mit ARR 3.0, und fand endlich das problem. Laut Microsoft ist Erez Benari, dies ist möglich:
Als test habe ich ein Node.js server für WebSocket:
Zusammen mit einem einfachen test Seite:
Dann, ich habe eine ARR reverse-proxy auf meiner lokalen Maschine, mit dem folgenden in einem web.config-Datei von einem "wstest" - Verzeichnis auf localhost:
Diese weiterleiten soll der ganze Verkehr für
//localhost/wstest
zu einem Node.js server auf port 3011. Die Node-server funktioniert, wenn ich direkt verbinden, um es überws://localhost:3011
. Wenn ich versuche die Verbindung über den proxy überws://localhost/wstest
, der Antrag macht es durch die Node.js server, die Aktualisierung Auftritt, und die Verbindung ist hergestellt.Chrome sendet:
Den Node.js server empfängt:
Den Node.js server antwortet mit:
Und schließlich Chrome erhält:
So, jetzt sind Sie verbunden. Dies alles sieht gut aus, der einzige auffällige Unterschied ist, dass die Sec-WebSocket-Key und Sec-WebSocket-Accept " wird geändert in beide Richtungen, indem Sie entweder IIS oder den ARR-proxy.
Aber... keine WebSocket-frames jemals machen es durch den proxy! Wenn Chrome erhält positives feedback auf Ihre upgrade-Anfrage, sendet er seine WebSocket-message-frame, und es ist dann sitzen und warten auf Nachrichten vom server. Die Node.js der server sendet seine frames, und es tritt kein Fehler auf, aber Sie erhielt nie von Chrome. Die Nachricht, dass Chrome gesendet wird nie eingegangen Node.js. Es scheint, dass ARR/IIS fallen die WebSocket-frames in beide Richtungen.
Bemerken, wie Chrome ist, dem server mitzuteilen, dass es unterstützt die permessage-entlüften-Erweiterung, die eine WebSocket-Erweiterung für pro-Nachricht-Komprimierung. Der server antwortet, dass es unterstützt auch permessage-entlüften, so dass, wenn Sie browser und server senden sich gegenseitig Nachrichten, benutzen Sie diese Kompressions-Erweiterung. JEDOCH, der Mann in der Mitte, ARR scheinbar NICHT unterstützen diese Komprimierung! Durch ausschalten der Unterstützung für permessage-deflate auf dem server, die eigentliche WebSocket-frames können nun über den proxy einwandfrei:
Ich denke, das Problem ist, dass ARR 3.0 nicht unterstützt
Sec-Websocket-Extensions
header, also es ist so dass der Kopf einfach Durchlaufen. Aber dass diese header werden ausgehandelt zwischen dem client und dem server ist falsch, denn die ARR ist nicht eingebunden in die Verhandlungen und hat keine Möglichkeit zu sagen, die beiden Parteien, die es nicht unterstützen die Weitergabe von komprimierten Nachrichten. Hoffentlich eines Tages, ARR wird in der Lage sein, ordnungsgemäß zu behandeln Erweiterungen durch Verhandlung zwischen sich selbst und den client, und dann tut eine separate Verhandlung zwischen sich und dem server. Wie es jetzt steht, es hat einfach den client und-server verhandeln mit jedem anderen, die Ergebnisse in diesen Fehler.Wie bereits von @jowo, IIS8/8.5 scheinen nicht zu unterstützen Sec-Websocket-Erweiterungen. , Die being said, ist die Problemumgehung ich angewendet ist, einfach schreiben Sie die server-variable in Frage. Fügen Sie zunächst HTTP_SEC_WEBSOCKET_EXTENSIONS der erlaubten server-variable Liste, dann fügen Sie es zu Ihrer Regel:
<serverVariables><set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" /></serverVariables>
So, das Ziel wird nicht erhalten die lästige permessage-entlüften 🙂