Wie finde ich getrennte XRDP-Sitzungen?

Wie finde ich getrennte XRDP-Sitzungen?

Ich habe hier einen Xubuntu 14.04-Server, auf dem xrdp läuft, damit sich mehrere Benutzer damit verbinden können.
Jetzt gibt es ein Problem: Benutzer, die über RDP von Windows-Thin-Clients auf diesen Server zugreifen, verwenden häufig das „X“, um die RDP-Sitzung zu schließen (also die Verbindung zu trennen, sich aber nicht abzumelden).

Ich weiß, dass es in sesman.ini einige Optionen gibt, um mit diesem Verhalten umzugehen, aber wie die Manpage sagt, werden diese Optionen derzeit (und schon seit Jahren) ignoriert.
Die Optionen, die meine Probleme lösen würden, sind:
KillDisconnected
DisconnectedTimeLimit
IdleTimeLimit

Jetzt muss ich etwas hacken, das mit getrennten Sitzungen umgeht. Mein erster Gedanke war, einfach alle Remote-Benutzer zu beenden, deren Verbindung getrennt ist – aber ich weiß nicht, wie ich an die Informationen komme, welche Sitzungen getrennt sind.

Also... wie finde ich getrennte Sitzungen?
Oder: Gibt es bereits eine bevorzugte Methode zum Umgang mit getrennten Sitzungen?

Antwort1

Hier ist eine Möglichkeit, eine Liste der getrennten xrdp-Sitzungen zu erhalten. Sie basiert auf der Tatsache, dass diexrdpDer Server ist bei normaler Verwendung des X-Session-Managers der einzige Client, der eine TCP-Verbindung zumXvncX Window System-Anzeigeserver. Wenn eine xrdp-Sitzung aktiv ist, hat der zugehörige Xvnc-Anzeigeserver zwei TCP-Verbindungen, eine im Status ESTABLISHED und die andere im Status LISTEN. Das sieht ungefähr so ​​aus, wenn man denlsof(1)Programm.

$ sudo lsof  -b -w -n -c /^Xvnc$/b -a -iTCP:5900-5999 
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
Xvnc    1625 guest    1u  IPv4 252910      0t0  TCP 127.0.0.1:5910 (LISTEN)
Xvnc    1625 guest    9u  IPv4 261226      0t0  TCP 127.0.0.1:5910->127.0.0.1:35242 (ESTABLISHED)

Wenn der Benutzer der Remotesitzung diese durch Schließen der RDP-Verbindung (oder im Fall einer Apache Guacamole RDP-Sitzung durch Schließen des Browserfensters) verlässt, sieht das ungefähr so ​​aus:

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
Xvnc    1625 guest    1u  IPv4 252910      0t0  TCP 127.0.0.1:5910 (LISTEN)

Beachten Sie, dass bei diesem getrennten Xvnc-Displayserverprozess keine HERGESTELLTE Verbindung besteht. Jeder Xvnc-Prozess, der nur zuhört, ist also eine getrennte Sitzung.

Hier ist ein Shell-Skript (mit dem Namen lsdisconnected), das die PID und den USER für jede getrennte Remote-Sitzung anzeigt. Es verwendetlsof(1)Undgaffen(1)um die Verbindungslogik zu implementieren.

#!/bin/bash
sudo lsof -FRgpLT -b -w -n -c /^Xvnc$/b -a -iTCP:5900-5999  |
gawk '
      match($0,/^p([0-9]+)/,       p) {pid = p[1]; pids[pid]=0; } ;
      match($0,/^L([A-Za-z0-9]+)/, p) {user[pid] = p[1]; } ;
      /TST=LISTEN/ {pids[pid] = pids[pid] - 1 ;};
      /TST=ESTABLISHED/{pids[pid] = pids[pid] + 1};
      END {
          for (pid in pids){
              if (pids[pid] < 0) {
                  print pid, user[pid];
              }
          }};
     '

Dies ist eine praktische Möglichkeit, getrennte Remote-Desktop-Sitzungen zu finden. Es funktioniert sofort nach der Trennung, ohne dass eine Leerlaufzeit benötigt wird.

Für diejenigen, die vielleicht nicht vertraut sind mitlsof(1)Hier finden Sie eine Erklärung der Befehlszeilenparameter in diesem Beispiel.

  • -b -wvermeidet lsof-Kernelwartezeiten. Sie werden hier nicht benötigt.
  • -nvermeidet DNS-Lookups für Hostnamen.
  • -c /^Xvnc$/bsucht unter Verwendung eines regulären Ausdrucks nach Prozessen mit dem exakten Befehlsnamen Xvnc.
  • -aweist lsof an, beim Filtern „AND“ und nicht „OR“ zu verwenden.
  • -iTCP:5900-5999filtert nach den TCP-Ports mit den Nummern 5900 - 5999, die für X-Display-Verbindungen verwendet werden.)

Antwort2

Ich habe endlich eine Lösung dafür gefunden.
Zuerst musste ich ein kleines Programm namens installieren xprintidle:

sudo apt-get install xprintidle

Danach habe ich ein kleines Bash-Skript geschrieben, das zuerst alle von Xvnc und xrdp verwendeten Displays abruft und dann diese Displaysitzungen überprüft, wenn sie länger als einige Minuten inaktiv waren:

#!/bin/bash

displays=`ps aux | grep Xvnc | grep -v 'grep\|sed' | sed -r 's|.*(Xvnc :[0-9]*).*|\1|' | cut -d' ' -f 2`
limit=180


date
echo "Checking for inactive sessions!"
while read -r d; do
    export DISPLAY=$d
    idle=`xprintidle`
    idleMins=$(($idle/1000/60))
    if [[ $idleMins -gt $limit ]]; then
        echo "WARN Display $d is logged in for longer than ${limit}min (${idleMins}m)"
    else
        echo "INFO Display $d is still ok (${idleMins}m)"
    fi  
done <<< "$displays"

Antwort3

Alter Beitrag, aber ich habe dasselbe Problem: Die Parameter KillDisconnected/DisconnectedTimeLimit/IdleTimeLimit in sesman.ini sind mit Xvnc inaktiv.

Eine einfache Lösung besteht darin, diese Parameter zum sesman.ini im Absatz [Xvnc] hinzuzufügen:

paramX=-MaxDisconnectionTime
paramX=3600

(bei X abhängig davon wie viele Parameter bereits definiert sind)

Dabei werden getrennte Sitzungen nach 1 Stunde automatisch beendet.

Antwort4

Danke für das lsof-fu! Das Erkennen von „toten“ XvncSitzungen ist seit langem ein Problem mit Xrdp. Ich habe den Code von O. Jones in ein Shell-Skript integriert, das beim Booten geladen und vom Bildschirm aus ausgeführt werden kann, um tote XvncProzesse zu bereinigen, die zurückbleiben, wenn ein Benutzer sein RDP-Fenster schließt oder die Verbindung aus irgendeinem Grund abbricht. Ich habe nie eine Möglichkeit gefunden, damit Xrdpumzugehen, also lsofist dieser Code perfekt.

#!/bin/bash

#
# this could be launched from rc.local via screen
#   echo '/usr/bin/screen -dmS xrdp_cleanup /root/bin/xrdp_cleanup_discod_sessions' | at now
#
while [ 1 ]; do
   # loop through all listening Xvnc processes and make sure there's an established connection
   for pid in `lsof -b -w -n -c /^Xvnc$/b -a -iTCP:5900-5999 | grep L[I]STEN | awk '{print $2};'`; do

      # new sessions may take a second or two on busy systems. 
      # wait for new LISTEN sessions to be become established. this also acts as a throttle for the loop
      sleep 2

      # get user for the established session
      euser=`lsof -b -w -n -c /^Xvnc$/b -a -iTCP:5900-5999 | grep L[I]STEN | grep "$pid" | awk '{print $3};'`
      esta=`lsof -b -w -n -c /^Xvnc$/b -a -iTCP:5900-5999 | grep E[S]TABLISHED | grep "$pid" | awk '{print $2};'`

      test -z "$euser" && echo "Unable to find user in lsof output!"

      if [ -n "$esta" ]; then
         # regular status update
         echo "user $euser has an established sesson on pid $pid"
      else
         isrunning="yes"

         # make sure the process is killed. keep trying.
         while [ -n "$isrunning" ]; do
            echo "Established session for user $euser is gone. killing pid $pid.."
            kill $pid
            sleep 1
            isrunning=`ps -ef | grep $pid | grep -v grep`
            test -z "$isrunning" && echo "$pid killed OK"
         done
      fi
   done
done

verwandte Informationen