Как найти отключенные сеансы xrdp?
У меня есть сервер Xubuntu 14.04, который запускает xrdp, чтобы к нему подключилось несколько пользователей.
Теперь есть одна проблема: пользователи, которые получают доступ к этому серверу через RDP из тонких клиентов Windows, часто используют "X", чтобы закрыть сеанс RDP (поэтому отключите, но не выйдите из системы).
Я знаю, что в sesman.ini есть несколько опций, чтобы справиться с таким поведением, но, как говорится на man-странице, эти опции в настоящее время игнорируются (и были в течение многих лет).
Варианты, которые решат мои проблемы:
KillDisconnected
DisconnectedTimeLimit
IdleTimeLimit
Теперь мне нужно взломать то, что связано с отключенными сессиями. Моей первой мыслью было просто убить всех удаленных пользователей, которые отключены - но я не знаю, как получить эту информацию о том, какие сеансы отключены.
Итак... как мне найти отключенные сеансы?
Или: есть ли какой-либо предпочтительный способ работы с отключенными сеансами?
3 ответа
Я наконец нашел решение для этого.
Прежде всего, мне нужно было установить небольшую программу под названием 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"
Вот способ получить список отключенных сеансов xrdp. Он основан на том факте, что при обычном использовании диспетчера сеансов X сервер xrdp является единственным клиентом, который устанавливает 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 нет УСТАНОВЛЕННОГО соединения. Таким образом, любой процесс Xvnc, который только слушает, является отключенным сеансом.
Вот сценарий оболочки (названный lsdisconnected
), который отображает PID и USER для каждого отключенного удаленного сеанса. Он использует lsof(1) и gawk(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 kernel. Они здесь не нужны.-n
избегает поиска DNS для имен хостов.-c /^Xvnc$/b
ищет процессы с точным именем команды Xvnc, используя регулярное выражение.-a
говорит lsof использовать AND, а не OR при фильтрации.-iTCP:5900-5999
фильтры по портам TCP с номерами 5900 - 5999, используемые для подключений к дисплею X.)
Старый пост, но у меня та же проблема: параметры KillDisconnected/DisconnectedTimeLimit/IdleTimeLimit в sesman.ini неактивны с Xvnc.
Простое решение - добавить эти параметры в sesman.ini в абзаце [Xvnc]:
paramX=-MaxDisconnectionTime
paramX=3600
(с X зависит от того, сколько параметров уже определено)
При этом отключенные сеансы автоматически завершаются через 1 час.
Спасибо за 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