Remote-Desktop ohne Drittanbieter: RustDesk-Infrastruktur im Eigenbau
Professioneller Remote-Support - Vorkonfigurierte Windows-Clients mit eigenem Branding erstellen.
Die vollständige Kontrolle über die eigene Support-Infrastruktur ist ein entscheidender Schritt auf dem Weg zur digitalen Souveränität. Durch den Einsatz des quelloffenen Remote-Desktop-Systems RustDesk lässt sich eine leistungsstarke Alternative zu teuren, proprietären Cloud-Diensten etablieren, die sensible Daten vollständig im eigenen Hoheitsbereich belässt. Mit einem selbstgehosteten Server, einem maßgeschneiderten Windows-Client und einer optimal konfigurierten Netzwerkumgebung wird professionelle Fernwartung unabhängig und sicher.
Die Bedeutung der digitalen Souveränität im Support-Alltag
Dank unvorhersehbarer Preisänderungen, restriktiver Lizenzmodelle und plötzlicher Dienstausfälle bei kommerziellen Anbietern gewinnt die digitale Selbstbestimmung im IT-Support massiv an Bedeutung. Wer sensible Kundendaten und geschäftskritische Systeme fernwartet, darf sich nicht blind auf intransparente Drittanbieter-Infrastrukturen verlassen. Ein eigener Support-Server garantiert, dass der gesamte Datenfluss – von der Signalisierung bis zum eigentlichen Bild- und Steuerungsdatenstrom – unter eigener Kontrolle bleibt und den strengen Datenschutzvorgaben entspricht. RustDesk bildet hierfür das perfekte technologische Fundament, da es als Open-Source-Lösung maximale Transparenz bietet und sich nahtlos in bestehende Linux- und Docker-Infrastrukturen integrieren lässt.
Das Fundament – RustDesk Server mit Docker Compose aufbauen
Dieser Server integriert sich perfekt in meine modular aufgebaute Docker-Umgebung, die ich hier bereits beschrieben habe:

Die Installation des eigenen Support-Servers basiert auf zwei zentralen Komponenten: dem ID-Server (hbbs) für die Verbindungsvermittlung und dem Relay-Server (hbbr) für den Fall, dass keine direkte Peer-to-Peer-Verbindung aufgebaut werden kann. Diese Dienste werden als Docker-Container bereitgestellt und in das bestehende virtuelle Netzwerk integriert. Ein tieferer Einblick in diese Netzwerkstrukturen wird im Artikel über Dockers virtuelle Netzwerke gewährt. Die Absicherung der Verbindungen erfolgt über eine forced-key-Verschlüsselung mittels des Parameters -k _. Dabei wird der Schlüssel aus der Datei ./rustdesk/data/id_ed25519.pub später fest in den Windows-Client eingebaut. Ich will auf jeden Fall vermeiden, dass meine Infrastruktur von Fremden genutzt werden kann.
Die folgende Konfiguration wird in die bestehende docker-compose.yml integriert:
rustdesk-hbbr:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbr
command: hbbr -k _
volumes:
- ./rustdesk/data:/root
ports:
- '21117:21117'
- '21119:21119'
networks:
- web
labels:
- "com.centurylinklabs.watchtower.enable=true"
restart: unless-stopped
rustdesk-hbbs:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbs
command: hbbs -r rd.meine-domain.de:21117 -k _
volumes:
- ./rustdesk/data:/root
ports:
- '21115:21115'
- '21116:21116'
- '21116:21116/udp'
- '21118:21118'
networks:
- web
depends_on:
- rustdesk-hbbr
restart: unless-stopped
labels:
- "com.centurylinklabs.watchtower.enable=true"
rustdesk-webclient:
image: pmietlicki/rustdesk-web-client:v1
container_name: rustdesk-webclient
expose:
- 5000
environment:
- CUSTOM_RENDEZVOUS_SERVER=rd.meine-domain.de:21116
- RELAY_SERVER=rd.meine-domain.de:21117
- KEY=UdUBzXUphPV3MJizVDDSZ12J+TOCvRt+da5-1st-all3s-Fak3=
restart: unless-stopped
networks:
- web
labels:
- "com.centurylinklabs.watchtower.enable=true"OPNsense und Nginx Proxy Manager für den Webclient vorbereiten
Während die klassischen Desktop-Clients direkt über die dedizierten Ports (21115 bis 21117) mit dem Host kommunizieren, verlangen moderne Webbrowser für den Betrieb des Webclients zwingend verschlüsselte WebSockets (wss:// über HTTPS-Port 443). Hierfür wird der Nginx Proxy Manager als Reverse Proxy eingesetzt. In der Admin-Oberfläche wird ein neuer Proxy Host für rd.meine-domain.de mit aktiviertem SSL-Zertifikat und erzwungenem HTTPS eingerichtet.


Um die WebSocket-Anfragen an die jeweiligen Container weiterzuleiten und restriktive CORS-Blockaden des Browsers zu umgehen, wird im Reiter Advanced (klick aufs Zahnrad) folgende Konfiguration hinterlegt:
location /ws/id {
proxy_pass http://rustdesk-hbbs:21118;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 120s;
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
}
location /ws/relay {
proxy_pass http://rustdesk-hbbr:21119;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 120s;
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
}
Für den Webclient bereiten wir auch gleich support.meine-domain.de vor. Damit nicht jeder meine Infrastruktur nutzen kann, sehen wir auch hier nur einen eingeschränkten Nutzerkreis vor, den wir in einer Accesslist hinterlegen:

Hier noch die User, denen ich Zugriff auf meine Plattform gebe, um Support leisten zu können:

Und schließlich auch die URL, unter der die Kollegen im Notfall Support liefern können, wie auch schon für Kunden-App:


Auf der OPNsense werden die nötigen Ports noch auf den Server weitergeleitet, auf dem die Docker-Container laufen.

Ein eigener Windows Client mit individuellem Branding
Um Kunden den Verbindungsprozess so einfach wie möglich zu gestalten, wird ein vorkonfigurierter Windows-Client mit eigenem Firmenlogo erstellt. Dies verhindert Fehleingaben bei Serveradressen und Keys. Das Erstellen dieser ausführbaren Datei erfolgt auf meinem Arch-Linux-System über ein automatisiertes Bash-Skript, welches die offizielle Windows-EXE herunterlädt, mein Logo konvertiert und mittels NSIS (Nullsoft Scriptable Install System) verpackt.
#!/usr/bin/env bash
# Autor: M. Meister
# Baut einen gebrandeten und vorkonfigurierten Windows-Support-Client für RustDesk.
set -e
DOMAIN="rd.meine-domain.de"
PUB_KEY="UdUBzgkjhgZZgkgduzgwwggkchkjhgr73Rt+das+ist+alles+fake-gell=" # aus ./rustdesk/data/id_ed25519.pub
APP_NAME="Meister Security Support"
EXE_NAME="Meister-Security-Support"
LOGO_URL="https://blog.meister-security.de/content/images/2024/12/meister-security-logo-150.png"
echo "[*] Erstelle Arbeitsumgebung..."
BUILD_DIR="rustdesk_build_temp"
rm -rf "$BUILD_DIR" && mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR"
echo "[*] Lade Logo herunter und erstelle Windows-Icon..."
wget -q -O "logo.png" "$LOGO_URL"
convert "logo.png" -define icon:auto-resize=16,32,48,64,128,256 "brand.ico"
echo "[*] Lade offiziellen RustDesk-Client..."
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/rustdesk/rustdesk/releases/latest | grep -oP '"browser_download_url": "\K[^"]+x86_64\.exe' | head -n 1)
wget -q --show-progress -O "rustdesk_source.exe" "$DOWNLOAD_URL"
echo "[*] Erstelle NSIS-Konfiguration..."
cat << 'EOF' > setup.nsi
Unicode true
!define APP_NAME "__APP_NAME__"
!define EXE_NAME "__EXE_NAME__"
!define HOST "__DOMAIN__"
!define KEY "__PUB_KEY__"
!define RUSTDESK_BINARY "rustdesk-host=${HOST},key=${KEY},.exe"
Name "${APP_NAME}"
OutFile "${EXE_NAME}.exe"
Icon "brand.ico"
SilentInstall silent
RequestExecutionLevel user
Section "Main"
SetOutPath "$TEMP"
File /oname=${RUSTDESK_BINARY} "rustdesk_source.exe"
ExecWait '"$TEMP\${RUSTDESK_BINARY}"'
Delete "$TEMP\${RUSTDESK_BINARY}"
SectionEnd
EOF
sed -i "s|__APP_NAME__|$APP_NAME|g" setup.nsi
sed -i "s|__EXE_NAME__|$EXE_NAME|g" setup.nsi
sed -i "s|__DOMAIN__|$DOMAIN|g" setup.nsi
sed -i "s|__PUB_KEY__|$PUB_KEY|g" setup.nsi
echo "[*] Kompiliere Windows-Client..."
makensis setup.nsi
mv "${EXE_NAME}.exe" ../
cd .. && rm -rf "$BUILD_DIR"
echo "[+] Vorgang abgeschlossen!"
Dieses Skript nutzt die offizielle, ausgereifte RustDesk-Codebasis und verpackt sie in einen maßgeschneiderten Installer. Optional kann die Datei über osslsigncode digital signiert werden, um unschöne Windows-SmartScreen-Sicherheitswarnungen beim Endanwender zu vermeiden. Aber das habe ich mir kurzerhand erspart.
Das Zusammenspiel – Arch Linux hilft Windows
Der operative Alltag zeigt, wie harmonisch die Komponenten ineinandergreifen. Wenn ein Windows-Benutzer Unterstützung benötigt, startet er die gebrandete Support-Datei.
Auf dem Arch-Linux-System des Helfers wird die Verbindung entweder über die Desktop-App oder bequem über den Webclient initiiert.

Wenn man das Programm startet, beschwert sich Windows, da mein Programm nicht von einer Microsoft vertrauten Zertifizierungsstelle signiert wurde. Sobald man dies jedoch ignoriert hat, sieht man folgendes:

Um Support von mir erhalten zu können, müssen mir sowohl die ID als auch das Einmalpasswort übermittelt werden.
Diese Daten können nun in meinem Linux-Client eingegeben werden:

Sobald auf dem Windowsrechner der Zugriff erlaubt wurde, sieht man schon dessen Bildschirm im Linux-Client:

Falls man mal keinen eigenen Rechner verfügbar hat: Der Web-Client
Auch wenn ich einmal nicht zuhause oder am Arbeitsplatz bin, erreichen mich doch gelegentlich Hilferufe. Um dann reagieren zu können, kann ich von jedem beliebigen Rechner auf meinen Web-Client zugreifen und helfen. Sobald ich dann auf support.meine-domain.de gehe, muss ich mich wie geplant einloggen:

War die Anmeldung erfolgreich, lande ich auch hier direkt in meinem Web-Client:

Dieser ist bereits perfekt vorkonfiguriert, wie wir es im Docker-Compose-File vorgesehen haben. Ein Klick auf die drei Punkte - also die Settings - zeigt das Ergebnis unserer Arbeit:

Und so haben wir uns auch hier erfolgreich ein weiteres Werkzeug geschaffen, das komplett ohne US-Big-Tech auskommt.
Mehr als nur Bildschirmübertragung – Die Werkzeugkiste im Kontextmenü
Ein Klick mit der rechten Maustaste auf einen Client wie meinem Testsystem michael@mmwin11 offenbart, dass die quelloffene Fernwartung weit über das bloße Betrachten des Bildschirms hinausgeht.

Die dort angebotenen Werkzeuge erlauben ein hocheffizientes Arbeiten im Hintergrund, was insbesondere bei langsamen Internetverbindungen oder administrativen Routineaufgaben ein echter Segen ist:
- Datei übertragen: Startet einen dedizierten Zwei-Spalten-Dateimanager. Damit lassen sich Skripte, Updates oder Protokolldateien direkt und verschlüsselt übertragen, ohne dass eine interaktive Bildschirmsitzung die Anwender bei der täglichen Arbeit stören muss.
- Kamera anzeigen: Ermöglicht den direkten Zugriff auf die angeschlossene Webcam des Zielsystems. Dies ist besonders praktisch, wenn vor Ort physische Hardware-Verkabelungen oder Status-LEDs geprüft werden müssen und der Kunde das Notebook kurzerhand als mobile Kamera nutzt.
- Terminal & Terminal (als Administrator ausführen) (beta): Das absolute Highlight für Kommandozeilen-Liebhaber. Es öffnet eine direkte, native Shell (unter Windows die Eingabeaufforderung oder PowerShell, unter Linux die Bash) auf dem Zielgerät. Befehle und administrative Skripte lassen sich so in Echtzeit ausführen, ohne dass ressourcenintensive Bilddaten übertragen werden müssen – die ultimative Bandbreitenbremse für langsame Mobilfunkverbindungen, wenn die Netzabdeckung mal wieder zu wünschen übrig lässt. So ist es auch möglich, die lokale KI Probleme beheben zu lassen.
- TCP-Tunnelung: Die diskrete Geheimwaffe für Netzwerktechniker. Mit dieser Funktion lassen sich lokale Ports über die bestehende RustDesk-Verbindung tunneln. So kann beispielsweise eine RDP-Sitzung (Port 3389) oder eine SSH-Verbindung (Port 22) sicher durch den RustDesk-Kanal geschleust werden, ohne dass auf der Firewall des Kunden Ports geöffnet oder ein separates VPN eingerichtet werden muss. Details dazu finden sich in der offiziellen RustDesk-Dokumentation zur TCP-Tunnelung.
- Immer über Relay-Server verbinden: Erzwingt, dass die Verbindung zwingend über den eigenen, selbstgehosteten hbbr-Container läuft, anstatt eine direkte Peer-to-Peer-Verbindung (per UDP-Hole-Punching) aufzubauen. Dies ist besonders in hochgradig restriktiven Netzwerken nützlich, falls die lokale Firewall mal wieder Paranoia schiebt und direkte P2P-Verbindungen blockiert oder instabil macht.
Die administrativen Optionen wie Umbenennen, Zu Favoriten hinzufügen und Löschen runden die Verwaltung ab und sorgen dafür, dass die eigene Support-Liste auch bei einer großen Anzahl an betreuten Systemen stets übersichtlich und strukturiert bleibt.
Fazit
Die Bereitstellung einer eigenen, lokal gehosteten Support-Infrastruktur vereint professionelles Auftreten mit kompromissloser Datensicherheit. Durch die geschickte Kombination aus Docker-Containern, granularer Portweiterleitung und einem maßgeschneiderten Client behält man die absolute Kontrolle über die verschlüsselten Datenströme. So wird digitale Souveränität im IT-Support zur gelebten Praxis und benötigt keinerlei fremde Infrastruktur.
