У меня есть сервер Xubuntu 14.04, который запускает xrdp, чтобы к нему подключилась пара пользователей.
Теперь есть одна проблема: пользователи, которые получают доступ к этому серверу через RDP из тонких клиентов Windows, часто используют «X», чтобы закрыть сеанс RDP (следовательно, отключиться, но не выйти из системы).
Я знаю, что в sesman.ini есть несколько параметров, позволяющих справиться с таким поведением, но, как сказано на странице руководства, эти параметры в настоящее время игнорируются (и были в течение многих лет).
Возможные варианты решения моих проблем:
KillDisconnected
DisconnectedTimeLimit
IdleTimeLimit
Теперь мне нужно взломать что-то, что касается отключенных сеансов. Моей первой мыслью было просто убить всех отключенных удаленных пользователей, но я не знаю, как получить эту информацию о том, какие сеансы отключены.
Итак ... как мне найти отключенные сеансы?
Или: есть ли какой-либо предпочтительный способ работы с отключенными сеансами?
Вот способ получить список отключенных сеансов xrdp. Он основан на том, что xrdp при обычном использовании диспетчера сеансов X сервер является единственным клиентом, который устанавливает TCP-соединение с Xvnc Сервер отображения системы X Window. Когда сеанс xrdp активен, связанный сервер отображения Xvnc имеет два TCP-соединения, одно в состоянии ESTABLISHED, а другое в состоянии LISTEN. Это выглядит примерно так, используя лсоф (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 для каждого отключенного удаленного сеанса. Оно использует лсоф (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];
}
}};
'
Это удобный способ найти отключенные сеансы удаленного рабочего стола; он работает сразу после отключения, без необходимости использовать время простоя.
Для тех, кто не знаком с лсоф (1) вот объяснение параметров командной строки в этом примере.
-b -w
избегает ожидания ядра lsof. Они здесь не нужны. -n
избегает DNS-поиска имен хостов. -c /^Xvnc$/b
ищет процессы с точным именем команды Xvnc, используя регулярное выражение. -a
указывает lsof использовать И, а не ИЛИ при фильтрации. -iTCP:5900-5999
фильтрует по портам TCP с номерами 5900 - 5999, используемым для соединений X display.)Я наконец нашел решение этого.
Прежде всего, мне пришлось установить небольшую программу под названием 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"
Старый пост, но у меня та же проблема: параметры KillDisconnected / DisconnectedTimeLimit / IdleTimeLimit в sesman.ini неактивны с Xvnc.
Простое решение - добавить эти параметры в файл sesman.ini в параграфе [Xvnc]:
paramX=-MaxDisconnectionTime
paramX=3600
(с X зависит от того, сколько параметров уже определено)
При этом отключенные сеансы автоматически завершаются через 1 час.
Спасибо за lsof
-фу! Обнаружение мертвых 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