XRDP und der schwarze Bildschirm

Die Leser von RemoteDesktop mit XRDP & XFreeRDP haben vielleicht noch im Kopf, daß RDP mit Linux mit Cinnamon einen schwarzen Bildschirm produziert hat, weil Cinnamon scheinbar viel mit Hardwarebeschleunigung arbeitet. Darum geht es heute nicht 😀

XRDP und der schwarze Bildschirm

Ein Phänomen beim Ausprobieren von RDP mit Linux war, daß auf einem Linuxrechner die Desktopsession nicht zwangsläufig weiter lief, wenn die Verbindung vom Clienten gekappt wurde. Wenn man mit RDP arbeitet, gibt es vier Gründe wieso eine Sitzung getrennt wird:

Netzwerkausfall: Verbindung unterbrochen
Sitzungsende: Benutzer loggt aus
Updates: Windows rebootet
WTF!: Der Benutzer fährt den RemotePC runter, statt sich abzumelden.

In den Fällen, wo die Verbindung gekappt wird, kann man normal weiter arbeiten, wenn man die Verbindung durch einen Reconnect wieder herstellt. Bei Windows klappt das bis lang ohne Probleme, weswegen sich viele einfach gar nicht „abmelden“ sondern einfach den RDP Clienten beenden, ohne sich auszuloggen.

Jetzt versucht das Kunststück mal bei einem XRDP Server 🙂 Das kann funktionieren, habe ich heute erst erlebt, aber meistens geht es nicht. Man sieht nur einen schwarzen Bildschirm, wenn es überhaupt funktioniert mit der erneuten Verbindung.

Nicht Remote, Nicht Lokal

Jetzt haben wir die kuriose Situation, daß wir per Remote nicht mehr in den PC kommen, und sich am Bildschirm einloggen als der Benutzer geht auch nicht. Zumindest ich habe keinen gleichzeitig lokalen wie remote Login geschafft, wenn man von SSH absieht.

Was macht man jetzt?

Es bleibt leider nur eins zu tun: per SSH einloggen und alles terminieren, was nicht im Screen läuft. Letzteres werde ich bei den jetzt folgenden Anweisungen nicht beachten, weil das ein von Euch selbst verursachter Spezialfall ist 😉

Erstmal sondieren:

{benutzername}“ bitte als ganzes mit Euren Benutzernamen austauschen, die {} gehören zum Platzhalter.

sudo ps auxf | grep ^{benutzername} | awk ‚{print „kill -9 „$2“;# „$0;}‘

Das sieht erst einmal wüst aus, ist aber nur die normale Ausgabe aller Prozesse die vom Benutzer gestartet wurden. Das Kill vorne ist schon für die nächste Aktion vorbereitet und Ihr sollt eigentlich nur kurz prüfen, ob da a) auch immer eine PID steht (Prozess-ID) b) was alles gekillt würde.

kill kann einem Prozess sagen, daß er sich selbst beenden soll, daß er sich neustarten sollen oder wenn der Prozess unreaktiv aka. tod ist, diesen hart beenden (-9 Option).

Wenn Ihr das geprüft habt, dann könnt Ihr loslegen:

sudo ps auxf | grep ^{benutzername} | awk ‚{print „kill -9 „$2;}‘| bash

Ihr dürft natürlich gern darauf vertrauen, daß es schon alles richtig ist und es gleich beenden, aber wenn was schief geht, nicht im Kommentarblock ausheulen 😉

Bitte beachten:

Wenn man per SSH als der besagte Benutzer eingeloggt ist um sich seine Desktopsession zu terminieren, die Befehle oben betreffen auch die SSH Session! d.h. Ihr kickt Euch selbst dabei raus. Nicht wundern, das ist völlig normal. Daher ggf. noch mal einloggen und prüfen, ob auch wirklich alles weg ist, was weg sein sollte.

Das Problem läßt sich elegant durch einen ROOT Login vermeiden, weil wenn der das macht, trifft es ihn nicht. Aber da root auch Prozesse von sich selbst wegkillen könnte, müßt Ihr gerade bei so brutalen Kommandos die in der Shell zusammengestrickt sind extrem sorgsam sein.

Die Erklär-Sektion

farblich nochmal genau aufgeschlüsselt, was da gemacht wird:

sudo ps auxf | grep ^{benutzername} | awk{print „kill -9 „$2;}‚| bash

sudo                  führt ps als Root aus, was Begrenzungen aller Art bei der Ausgabe verhindert.
                      Kann aber weg gelassen werden.
ps                    "Prozesslist"
auxf                  listet alle Prozesse mit PID Username und Kommando auf.
grep                  filter die Ausgabe von ps nach...
^benutzername         allen Zeilen die mit dem Benutzernamen beginnen, das ^ ist wichtig dabei.
awk                   zerlegt die gefilterten Ausgaben in einzelne Spalten und ordnet die neu an.
{print "kill -9 "$2;} die neue Anordnung des Inhalts von Spalte 2 ( der PID )
bash                  führt die mit print zusammengebaute neue Anweisung "kill -9 PID" aus, 
                      wobei PID dann der Inhalt von Spalte 2 der Prozessliste ist.

Man erwischt so alle laufenden Prozesse des Users, egal wann, egal wieviele es sind.

RemoteDesktop mit XRDP & XFreeRDP

Von Remotearbeitsplatzlösungen hat bestimmt sicher jeder schon mal etwas gehört. Die Technik dafür ist in der Regel auf VNC aufgebaut und trägt viele Namen: AnyDesk, Teamviewer, RDP oder auch direkt VNC.

RemoteDesktopProtocol

Wenn es bei VNC eher um die rudimentären Funktionen der Bildübertragung geht, so daß auf zwei Monitoren das Gleiche zu sehen ist, kann man sich mit RDP, Teamviewer und Anydesk auch als ein Benutzer auf einem anderen PC anmelden.

Ein GNOME Remotearbeitsplatz mit laufendem VideoUnter Windows nutzt man dazu das RemoteDesktopProtocol ( RDP ) und genau das kann man auch mit Linux nutzen. RDP ist in der Lage die Verbindung mit TLS zu verschlüsseln, was einen großen Vorteil hat, wenn man das quer durchs Internet benutzt. Es ist allerdings eine schlechte Idee, den RDP Port frei ins Netz zu stellen. Die Windows RDP Serverversion ist in der Vergangenheit mehrfach erfolgreich Ziel von Angreifern geworden, daher empfehle ich für Linux ohnehin, daß man den Port über SSH tunnelt.

Das geht ganz leicht:

ssh -C -L 127.0.0.1:3389:RDPSERVERIP:3389 username@sshgateway

Der Linux Client – XFreeRDP

Die Verbindung zu einem RDP Server aufzubauen ist ganz leicht, wenn man XFreeRDP benutzt. Analog zu dem SSH Tunnel oben, hier die dafür nötige Syntax:

xfreerdp /v:127.0.0.1 /u:username /p:Passwort /size:1920×1020

Die erste Frage wird jetzt wohl sein, wieso 1920×1020. Das ist leicht, weil das als Fensterversion genau in einen FullHD Monitor mit Cinnamon paßt 😉 Wer aber die volle Erfahrung haben will, der kann auch einen Parameter für Fullscreen angeben:

xfreerdp /v:127.0.0.1 /u:username /p:Passwort /size:1920×1080 /f

Wer darüber Videos ansehen und/oder Skypen will, der muß zwei Dinge haben: einen Server der das anbietet und folgende Parameter:

xfreerdp /v:127.0.0.1 /u:username /p:Passwort /size:1920×1080 /f  /microphone:sys:alsa /sound:sys:alsa /compression-level:2

Aber erwartet da jetzt nicht zu viel. Bei Tests gab es da leichte Bandbreitenprobleme über DSL.

Die nächste Frage dürfte sein, wieso man das in die Konsole hacken soll. Sagen wir es mal so, die meisten getesteten DesktopUIs waren nicht wirklich brauchbar. Ich empfehle Euch ohnehin für eine zügige Verbindung ein Desktopfile pro Verbindung:

[Desktop Entry]
Version=1.0
Name=Arbeitsplatz2
GenericName=RemoteTool
Comment=FreeRPD Client
Exec=xfreerdp /v:127.0.0.1 /u:username /p:Passwort /size:1920×1080 /f  /microphone:sys:alsa /sound:sys:alsa /compression-level:2
Icon=/home/username/.local/share/icons/freerdp.svg
Terminal=false
Type=Application
StartupNotify=false
Categories=Network;
Keywords=Arbeitsplatz;rdp;freerdp;internet;
X-Desktop-File-Install-Version=0.21
Name[de_DE]=Arbeitsplatz2

Wenn es noch ein automatischer Tunnel sein soll, müßt Ihr ein Shellscript schreiben und das aufrufen. Ab hier könnt Ihr auf einen beliebigen Windows oder Linux RDP Server zugreifen.

XRDP – Der RDP Server

Kommen wir zum schwierigen Teil der Aktion: Der eigene Server.

Eigentlich es ziemlich einfach, nur die Details sind ein Problem. XRDP ist glücklicherweise bei Fedora dabei. Installiert bekommt man es also einfach mit :

sudo dnf install xrdp

zum Starten ist auch nicht viel nötig:

sudo systemctl start xrdp

Aber Ton versucht man vergebens zu aktivieren, denn die nötigen Pulseaudiomodule liegen dem Programm bei Fedora seit einiger Zeit nicht mehr bei. Ich habe versucht die für Fedora 30 zu kompilieren, keine Chance.

Bei Fedora 31 sieht die Sache ein klein bisschen anders aus. Hier ist bereits PulseAudio 13 im Einsatz, wo Fedora 30 noch 12 benutzt. Der F30 Build von PulseAudio 13 wurde aus einem unerklärlichen Grund in die Mülltonne verschoben, ich tippe mal darauf, daß nicht alle anderen Pakete mitziehen wollten oder konnten.

Da es auch Für PulseAudio 13 keine Fedora Module für XRDP gibt, müssen wir hier kreativ werden 🙂 Wir leihen es uns bei einer anderen Distribution aus:

wget http://ftp.altlinux.org/pub/distributions/ALTLinux/Sisyphus/x86_64/RPMS.classic/pulseaudio-module-xrdp-0.4-alt1.x86_64.rpm
rpm -i ./pulseaudio-module-xrdp-0.4-alt1.x86_64.rpm

Jetzt kann Euer Fedora 31 auch den Sound liefern.

Die richtige Desktopwahl

So, Ihr habt Euren Server laufen und jetzt verbindet Ihr Euch mit XFreeRDP dahin. Ihr werdet jetzt abhängig von dem Desktopspin den Ihr installiert habt, entweder einen Erfolg vermelden können (GNOME) oder einen schwarzen Bildschirm sehen und nicht mehr ausloggen können (Cinnamon). Die anderen Desktops habe ich nicht ausprobiert, aber Gerüchten zufolge, sollen die durchweg „gehen“.

Um sicher zugehen, daß Ihr eine Umgebung bekommt, die auch läuft, legt Ihr im HOME vom Benutzer den Ihr einloggen wollt eine Datei namens .Xclients an, die „gnome-session“ als Inhalt und u+x als Dateiattribute hat:

echo „gnome-session“ > ~/.Xclients
chmod u+x ~/.Xclients

Voraussetzung ist, daß Gnome auch installiert ist. Falls das nicht der Fall ist, könnte das helfen:

dnf install gnome-desktop3

Da sollte der ganze Rattenschwanz an Abhängigkeiten kommen. Alternativ schreibt Ihr Euren Desktop in die Datei rein. Eine Liste mit passenden Anweisungen finden Ihr im Netz.

Wieso empfehle ich dann Gnome?

Weil das nicht über die fehlende Hardwarebeschleunigung meckert, wie andere Desktops das tun ( und dann nicht richtig funktionieren ). Außerdem ist die schlichte Deko des Desktops sehr hilfreich um Bandbreite einzusparen, was die Sache reaktiver macht. Im eigenen LAN ist das natürlich komplett egal.

Ich rate bei DSL Verbindungen dazu die Animationen des Desktops zu deaktivieren. Man kann das auch im XFreeRDP als Schalter mitteilen, aber direkt im Gnome ist es vermutlich „nachvollziehbarer“ für den Desktop.

Jetzt könnt Ihr loslegen.

Ein kleiner Sicherheitshinweis noch: Paßt bitte auf, daß Ihr nicht aus Versehen den Server runterfahrt, statt die Usersession zu beenden, daß kann sehr schmerzhaft werden 🙂 Gerade bei Gnome liegen die Funktionen dicht beisammen und aus Gewohnheit verklickt man sich da schnell. Also Obacht!

Android

Oh ja, es gibt auch eine Android XFreeRDP Clienten Version und je nach Eurem Android, kann die ggf. nur gebrochene Krypto. Wenn das der Fall ist, laßt es lieber, weil Eurer Tablet dann auch leistungsmäßig nicht ausreicht um das brauchbar zu benutzen. Falls Ihr diese lieb gemeinte Warnung ignorieren wollt, xrdp.ini ist Eure Anlaufstelle:

/etc/xrdp/xrdp.ini :

ssl_protocols=TLSv1, TLSv1.1, TLSv1.2, TLSv1.3v; set TLS cipher suites

Es dürfte klar sein, daß das im != Privaten Umfeld nicht eingesetzt werden darf, da Artikel 32 DSGVO das verbietet.

Dann wünsche ich jetzt allen Karnevalsfreunden unter Euch, die morgen zum Shoduvel nach Braunschweig kommen: Alles Gute in der Regenschlacht und verabschiede mich für heute 🙂

Linux Praxis: Remote Desktop Protokoll

Da ich kürzlich Gelegenheit bekam per Fernwartung in einer Firma mit Windowsclienten zu arbeiten, möchte ich Euch viel unnötiges Gesuche darüber ersparen, was geht und was nicht geht.

Windows 10 und RDP

Zunächst einmal, es geht um Windows 10 und dessen RDP Service. Das man den nicht einfach ins Netz exponieren kann, weil der PC sonst binnen Sekunden gehackt wird, sollte jedem spätestens seit BlueKeep und dessen Nachfolger, der sich gleich wurmartig fortpflanzen konnte, klar sein.

Wie macht man das jetzt, wenn man keine teure Firewalllösung einkaufen möchte, die dann vielleicht selbst zur ungepatchten Schwachstelle wird ( so wie die F5 ) oder nicht schnell genug die Signaturen aktualisiert?

Linux ist die Rettung

Man nehme ein gescheites Linux (Centos LTS mit Autoupdate würde reichen), und stellt es ins Intranet. Der SSH Port wird über DSL-Router nach außen exponiert, idealerweise nicht Port 22, was die Anzahl der Scans reduziert, und fail2ban-ed dann noch gleich die BruteForceangriffe weg 😉 . Das man den Zugriff nur per >=4K-SSH-Schlüssel und nicht mehr per PAM ( Passwort ) zulässt dürfte selbstverständlich sein, oder muß ich das extra erwähnen? 🙂

Wenn man Linux auch als Desktop hat, ist es jetzt ganz leicht den RDP Port des Windowszielrechners im Intranet auf 127.0.0.1 zu forwarden:

ssh -C -L 3389:192.168.178.33:3389 root@externe.dsl.ip

Kleiner Pro Tip: „-C“ nicht vergessen, dann komprimiert SSH die Daten zusätzlich noch, was gerade bei langsamen Verbindungen von Vorteil sein wird. Durch SSH wird die Verbindung über das Netz komplett verschlüsselt.

Wie verbindet man sich jetzt zu seinem mit TLS gesicherten RDP Service?

Jetzt kommen wir zum eigentlichen Problem mit Linux als RDP Clienten: kaum ein RDP Client taugt was.

Die kurze Liste der RDP Clienten unter Fedora lautet: RDesktop, gnome-rdp aka Vinagre und freerdp

RDesktop und Vinagre kann man gleich löschen. Der RDP Client der Wahl ist FreeRDP! Das ist nämlich der einzige, der überhaupt funktioniert. Vinagre baut zwar eine Verbindung auf, liefert aber nur ein Schwarzbild ab => fail. RDesktop war nicht mal dazu in der Lage.

FreeRDP hat neue Optionen

Im Netz findet man z.b. im Ubuntu-Forum Hinweise wie man FreeRDP erzählt, wo es hin soll und wie groß der Bildschirm sein. Leider muß man das angeben, sonst gibt es die Defaultwindowssession mit 1280×1024 😀 Das hatten wir dann auf dem 3k Display vom meinem Surface Pro als kleines Icon irgendwo in der Ecke vom Bildschirm liegen 😉 Ok,ok, Icongröße hatte es nicht ganz, aber da FreeRDP nicht DPI-Scaleaware ist, mußte man halt eine Lupe benutzen.

FreeRDP scheint seine CLI-Optionen umstrukturiert zu haben und man muß statt mit „-“ mit „/“ arbeiten. Beispiel: /size:WxH. Ob die sich an die Windows-DOSshell anwanzen wollten, wer weiß …

Windows failed beim DPI-Scaling

Es bliebt einem nichts anderes übrig als FreeRDP zu sagen, wie groß das Fenster denn sein soll, damit man dann einen größeren Font im Windows einstellen kann. Ab da wird es dann peinlich für M$, denn das DPI-Scaling funktioniert nur bei realen Bildschirmen, nicht bei Remote-Zugriffen per RDP 😀 Allen Versuchen zum Trotz blieb das Fenster ohne DPI-Scaling, auch als Windows behauptet hat, es würde 500%! skalieren 😉 Lustigerweise warnt einen Windows, daß es kein Vergnügen sein wird, ein 500% skaliertes Windows zu benutzen. Ich wäre schon froh über 200% gewesen 😀

Wenn man auf dem Windowsystem jetzt mit Browsern arbeiten muß, ist die Lösung denkbar einfach: das Browserfenster zoomen. Bei richtigen Anwendungen geht das natürlich nicht, was das Arbeiten auf einem 3k-4K Display nicht gerade vergnüglich macht. Da hilft es nur einen kleineren Bildschirm zu benutzen. Für ein FullHD Display könnte die Anweisung an FreeRDP so lauten:

xfreerdp /u:username /v:127.0.0.1 /size:1920×1020

Damit ist das Fenster brauchbar in Cinnamon eingefasst. Da wir glücklicherweise zwei HighSpeed-DSL Anschlüsse nutzen, ist die Latenz der Pakete sehr niedrig und das Arbeiten ist (bislang) angenehm.

Windows ist in dem Szenario leider nicht das einzige Programm, das failed. FreeRDP müßte das Scaling eigentlich auch automatisch beachten. FreeRDP bietet als Optionen jetzt einen Scalingparameter an, leider funktioniert auch das nicht sofort.

xfreerdp /u:username /v:hostname /size:1920×1080 /scale:140 /scale-desktop:200

Obiges bringt dann die Lösung. Damit läßt sich der Desktop uns seine Anwendungen auch auf 3k/4K besser lesen. Offensichtlich muß man Windows erst von außen sagen, das es skalieren soll, interne Einstellungen zählen halt nicht.

Für FreeRDP gibt es übrigens noch die Rocket-GUI, so muß man nicht alles in der Bash machen. Allerdings ist das Programm recht simple und wird nicht allen Anforderungen an unser spezielles Problem gerecht.