Вопрос: Как найти отключенные сеансы xrdp?


У меня есть сервер Xubuntu 14.04 здесь, который запускает xrdp, чтобы подключить к нему пару пользователей.
Теперь есть одна проблема: пользователи, которые обращаются к этому серверу через RDP из тонких клиентов Windows, часто используют «X» для закрытия сеанса RDP (поэтому отключите, но не выйдите из системы).

Я знаю, что есть некоторые варианты в sesman.ini, чтобы справиться с таким поведением, но, как говорится в manpage, эти параметры в настоящее время игнорируются (и были в течение многих лет).
Варианты решения моих проблем:
KillDisconnected
DisconnectedTimeLimit
IdleTimeLimit

Теперь мне нужно взломать что-то, что связано с отключенными сеансами. Моя первая мысль заключалась в том, чтобы просто убить всех удаленных пользователей, которые отключены, но я не знаю, как получить эту информацию, какие сеансы отключены.

Итак ... как мне найти отключенные сеансы?
Или: существует ли какой-либо предпочтительный способ борьбы с отключенными сеансами?


5
2017-10-06 13:32


Источник




Ответы:


Ниже приведен способ получения списка отключенных сеансов xrdp. Он опирается на тот факт, что xrdp сервер, в обычном использовании диспетчера сеансов X, единственный клиент, который устанавливает TCP-соединение с Xvnc X Window System. Когда сеанс xrdp активен, соответствующий сервер отображения Xvnc имеет два соединения TCP: один в состоянии ESTABLISHED, а другой в состоянии LISTEN. Это выглядит примерно так, используя Lsof (1) программа.

$ 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)

Если пользователь удаленного сеанса отказывается от него, закрывая RDP-соединение (или, в случае сеанса Apache Guacamole RDP, закрывая окно браузера), он выглядит примерно так:

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 отсутствует соединение ESTABLISHED. Таким образом, любой процесс Xvnc, который только прослушивает, является отключенным сеансом.

Вот сценарий оболочки (называемый lsdisconnected), который отображает PID и USER для каждого отключенного удаленного сеанса. Оно использует Lsof (1) а также поглазеть (1) для реализации логики подключения.

#!/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];
              }
          }};
     '

Это удобный способ найти отключенные сеансы удаленного рабочего стола; он работает сразу после отключения, без использования простоя.

Для тех, кто не знаком с Lsof (1) вот объяснение параметров командной строки в этом примере.

  • -b -w избегает lsof ядра. Они здесь не нужны.
  • -n избегает поиска DNS для имен хостов.
  • -c /^Xvnc$/b ищет процессы с точным именем команды Xvnc, используя регулярное выражение.
  • -a говорит lsof использовать AND, а не OR, при фильтрации.
  • -iTCP:5900-5999 фильтры по TCP-портам с номерами 5900-5999, которые используются для соединений X-дисплея.)

4
2017-07-20 15:22





Наконец я нашел решение.
Прежде всего, мне пришлось установить небольшую программу под названием xprintidle:

sudo apt-get install xprintidle

После этого я написал небольшой скрипт bash, который сначала извлекает все отображения, используемые Xvnc и xrdp, а затем проверяет эти сеансы отображения, если они простаивают более нескольких минут:

#!/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"

3
2018-03-31 15:59



Я сделал следующий шаг, чтобы автоматически убивать сеансы, которые простаивали дольше 30 минут: gist.github.com/mnebuerquo/e825530cf2bfd363b6c3cd82fe697d94 - Mnebuerquo


Спасибо за lsof-FU! Обнаружение "мертвых" Xvnc сессий была давняя проблема с Xrdp, Я включил код О. Джонса в сценарий оболочки, который можно загрузить при загрузке и запустить с экрана для очистки мертвых Xvnc процессы остаются позади, когда пользователь закрывает свое окно RDP, или соединение падает по какой-либо причине. Я никогда не встречал Xrdp чтобы справиться с этим, чтобы это lsof код совершенен.

#!/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

0
2018-05-03 18:08