grdpwasm – Webbasierter RDP-Client
(github.com/nakagami)- Ein webbasierter RDP-Client, mit dem sich allein im Browser auf Windows-Remotedesktops zugreifen lässt, und der ohne Plugin funktioniert
- Trennt Go WebAssembly im Browser von einem serverseitigen WebSocket-zu-TCP-Proxy, der die RDP-TCP-Verbindung übernimmt, die der Browser nicht direkt öffnen kann
- Die Verbindung folgt dem Ablauf
Browser -> WebSocket -> proxy -> TCP -> RDP Server; nach dem Verbindungsaufbau wird der Remote-Bildschirm auf einem canvas angezeigt und Tastatur- sowie Mauseingaben werden übertragen - Als Eingabegeräte werden eine auf RDP scan codes basierende Tastatur sowie eine Maus mit Bewegung, Klicks und Mausrad unterstützt; Remote-Audio wird über RDPSND empfangen und per Web Audio API wiedergegeben
- Da die Proxy-Struktur Verbindungen von allen Origins zulässt, sollte sie nur in vertrauenswürdigen Netzwerken betrieben oder vor externer Freigabe mit HTTPS/WSS und einer Authentifizierungsschicht abgesichert werden
Projektüberblick
- Funktioniert als webbasierter RDP-Client, der den Zugriff auf Windows-Remotedesktops im Browser ohne Plugin ermöglicht
- Die Implementierung basiert auf einer Kombination aus Go WebAssembly und grdp und hat eine getrennte Struktur aus Browser-Laufzeitteil und Proxy-Vermittlungsteil
- Da der Browser keine Raw-TCP-Sockets direkt öffnen kann, wird zusätzlich ein leichtgewichtiger Go-Proxy benötigt, der die WebSocket-Verbindung zum TCP-Port des RDP-Servers weiterleitet
Architektur und Funktionsweise
- Der gesamte Pfad verläuft in der Reihenfolge
Browser (WASM) -> WebSocket -> proxy (Go) -> TCP -> RDP Server - Im Browser läuft das WASM-Binary, während der Proxy sowohl als WebSocket-zu-TCP-Bridge als auch als statischer Dateiserver dient
- Die Ergebnisse von
make allsind instatic/main.wasmfür die Browser-Ausführung,static/wasm_exec.jsals Go-Runtime-Hilfsdatei undproxy/proxyals Proxy-Server aufgeteilt - Dank dieser Struktur verarbeitet die Browser-Seite die Verbindung mit Standard-Webtechnologien, während der Proxy die eigentliche TCP-Kommunikation mit dem RDP-Server übernimmt
Nutzungsablauf und Benutzeroberfläche
- Öffnet man im Browser
http://localhost:8080und gibt im Verbindungsformular Host, Port, Domain, User, Password, Width, Height ein und klickt anschließend auf Connect, startet die Sitzung - Der Standardwert für Port ist
3389; Domain kann leer bleiben, wenn ein lokales Konto verwendet wird - Sobald die Verbindung hergestellt ist, wird der Remote-Desktop auf einem canvas angezeigt; um Tastatureingaben zu senden, muss auf das canvas geklickt werden
- Mit Disconnect wird die Sitzung beendet
Eingabegeräte und Audio-Unterstützung
- Sämtliche Standard-Tastatureingaben werden über RDP scan codes an den Remote-Desktop übertragen
- Die Maus unterstützt Bewegungen, Mausklicks und das Scrollrad
- Die Browser-Registerkarte muss den Fokus haben, damit Tastaturereignisse übertragen werden; wenn keine Tasteneingaben mehr ankommen, muss der canvas-Bereich erneut angeklickt werden
- Remote-Audio wird über RDPSND gestreamt und im Browser per Web Audio API wiedergegeben
- Das Audioformat ist als PCM 44100 Hz, stereo, 16-bit signed little-endian angegeben
Betriebsbedingungen und Sicherheitshinweise
- Voraussetzungen sind Go 1.24 oder höher sowie ein erreichbarer RDP-Server; der Zielserver kann Windows oder ein RDP-kompatibler Host sein
- Der Proxy erlaubt Verbindungen von allen Origins und sollte daher nur in vertrauenswürdigen Netzwerken betrieben oder vor einer Freigabe ins Internet um eine Authentifizierungsschicht ergänzt werden
- Zugangsdaten werden im Browser per WebSocket an den Proxy übertragen; in nicht vertrauenswürdigen Netzwerken ist daher die Nutzung von HTTPS/WSS erforderlich
- Das README erwähnt auch die Möglichkeit eines TLS-terminierenden Reverse Proxy mit nginx oder Caddy
Ausführung und zusätzliche Informationen
- Der Start ist mit
make serveoder in der Form./proxy/proxy -listen :8080 -static staticmöglich - Mit der Proxy-Option
-listenwerden Empfangsadresse und Port festgelegt, mit-staticdas Verzeichnis für statische Dateien - Die Entwicklungsziele sind aufgeteilt in
make wasmzum erneuten Bauen nur des WASM,make proxyzum erneuten Bauen nur des Proxy,make wasm_execzum Aktualisieren vonwasm_exec.jssowiemake cleanzum Löschen der Build-Artefakte - Die Lizenz ist GPLv3; zusätzlich ist ein Verweis auf die grdp LICENSE enthalten
2 Kommentare
Ich sehe ehrlich gesagt den wirklichen Vorteil nicht.
Es ist letztlich nur ein Client, daher kann man serverseitig auch keine bestimmten Anforderungen erzwingen,
und rein über den Browser ist der Zugriff ebenfalls nicht möglich.
Hacker-News-Kommentare
Sieht ziemlich cool aus. Wenn noch Sitzungsaufzeichnung und SSO-Authentifizierung dazukämen, könnte man das direkt als RDP-Jumphost verwenden.
Ich habe etwas Ähnliches mit Azure Bastion genutzt: Man meldet sich im Azure-Portal mit der für den Tenant konfigurierten Authentifizierung an, verbindet sich dann im Browser per RDP mit der VM und meldet sich auf der VM mit einem lokalen Konto an. Datei- und Zwischenablagenutzung funktionieren ziemlich gut, und auch eine Konsolensitzung im Browser wird unterstützt.
Ich weiß nicht, ob das auf Windows/RDP-Seite genauso gut funktioniert, aber Browser-SSH von GCP war von allem, was ich bisher gesehen habe, eines der am besten gemachten.
Auch unter Linux hatte ich manchmal das Gefühl, dass xrdp besser ist als andere Alternativen.
Einer der großen Vorteile, die das hier löst, ist die Trennung der Verwaltungsoberfläche von VM/Server. Allein schon dafür zu sorgen, dass der Verwaltungsdienst eines Webservers nicht auf derselben IP/Domain/Schnittstelle wie der HTTP-Dienst liegt, verbessert die Sicherheit erheblich.
Die Zwischenablage ist bei Browser-RDP ein unterschätzter Albtraum. Die Aushandlung des Wire-Protokolls funktioniert an sich gut, aber die Clipboard API im Browser ist an Berechtigungen und Anforderungen an Benutzerinteraktionen gebunden.
Beim Lesen verlangen die meisten Browser fast jedes Mal eine Bestätigung vom Benutzer. Deshalb legt man entweder einen separaten Zwischenablagepuffer innerhalb der Seite an, oder das Einfügen in die RDP-Sitzung funktioniert zwar reibungslos, aber beim Kopieren aus der RDP-Sitzung nach draußen muss man jedes Mal extra klicken.
Beides entspricht nicht wirklich dem Verhalten, das Leute von einem Web-RDP-Client erwarten. Bevor man sagt, das sei auf dem Niveau von nativem mstsc, sollte man unbedingt prüfen, wie unterschiedlich sich Chrome und Firefox dabei verhalten.
Nachdem HP Anyware / Teradici / PCoIP eingestellt hat, suchen ziemlich viele nach Alternativen. Besonders gefragt sind Lösungen mit hochauflösendem Multi-Monitor, 60fps, Wiedergabe mit hoher Bittiefe, Unterstützung für Wacom-Tablets und Support für alle drei Betriebssysteme.
Im kostenpflichtigen Bereich gibt es Parsec und DCV, und Open-Source-Versuche sind sehr willkommen. Mit Projekten wie rustdesk, kyber und teraguchi scheint die Community dringend eine leistungsfähige Open-Source-Option zu brauchen.
https://github.com/rustdesk/rustdesk
https://github.com/thedepartmentofexternalservices/teraguchi
https://kyber.tech/
Sieht interessant aus, aber überraschend ist, dass die wichtigste Funktion gar nicht erwähnt wird. Ich würde gern wissen, wie gut gemeinsame Zwischenablage in der Praxis funktioniert.
Gemeinsame Zwischenablage sowie Upload/Download über freigegebene Laufwerke lassen sich relativ direkt über FreeRDP nutzen.
Und Sitzungsaufzeichnung ist in einer PAM-Umgebung nicht verhandelbar.
[1] https://adaptive.live
Desktop-Skalierung, Multi-Monitor-Unterstützung, Dateiübertragung, Laufwerksumleitung und Peripherie-Umleitung sind ebenfalls alle wichtig.
Ich frage mich, ob das auch funktioniert, wenn man die von CyberArk PAM erhaltene RDP-Datei öffnet.
Ich frage mich auch, ob der RDP-Client Alt-Tab innerhalb eines Browser-Tabs abfangen kann.
Das war früher das größte Problem bei Browser-RDP in Guacamole.
Technisch interessant, aber ich verstehe nicht ganz, warum man das braucht, da es auf fast allen Plattformen bereits native RDP-Clients gibt.
https://guacamole.apache.org/