Универсальный вариант, работающий и с gdm, и с lightdm - запускаем отдельный скрипт, который сам найдет, какая виртуальная консоль активна, кто в ней сидит, и какие параметры вызова необходимы. Причем запускаем только тогда, когда будет обращение на порт. В норме - задраенный отовсюду, кроме локального адреса, соединение поверх ssh.
Вспомогательный скрипт, который будет отключать локальную консоль при подключении извне и включать ее обратно после отсоединения:
/usr/local/bin/switch_console
#!/bin/sh
case $1 in
1|on)
desired=1
;;
0|off)
desired=0
;;
*)
echo "USAGE: $0 0|1|on|off"
exit 1
;;
esac
export DISPLAY=:0
export XAUTHORITY=/var/run/lightdm/root/:0
keyboards=`xinput | grep -v "XTEST" | grep "slave keyboard" | sed -re 's/^.*\sid=([0-9]+)\s.*$/\1/'`
mouses=`xinput | grep -v "XTEST" | grep "slave pointer" | sed -re 's/^.*\sid=([0-9]+)\s.*$/\1/'`
monitors=`xrandr | grep " connected" | sed -re 's/^(.+) connected.*$/\1/'`
for device in $mouses
do
xinput --set-prop $device "Device Enabled" $desired
done
for device in $keyboards
do
xinput --set-prop $device "Device Enabled" $desired
done
for device in $monitors
do
xrandr --output $device --brightness $desired
done
Юнит-файлы для запуска скрипта при обращении к порту:
/etc/systemd/system/xvnc.socket
[Unit]
Description=XVNC Server
[Socket]
ListenStream=127.0.0.1:5900
Accept=yes
[Install]
WantedBy=sockets.target
/etc/systemd/system/xvnc@.service
[Unit]
Description=XVNC Per-Connection Daemon
[Service]
ExecStart=/usr/local/bin/startx11vnc
ExecStartPost=/usr/local/bin/switch_console 0
StandardInput=socket
StandardError=syslog
И основной скрипт:
/usr/local/bin/startx11vnc
#!/bin/sh
pidtree() {
echo -n $1 " "
for _child in $(ps -o pid --no-headers --ppid $1); do
echo -n $_child `pidtree $_child` " "
done
}
CONSOLE=`fgconsole`
for SESSION in `loginctl list-sessions | awk '$4 ~ /seat/ {$1=$1; print $1;}'`
do
SESSCON=`loginctl show-session $SESSION | grep VTNr= | cut -d "=" -f 2`
STATE=`loginctl show-session $SESSION | grep State= | cut -d "=" -f 2`
if [ "$CONSOLE" -eq "$SESSCON" ] && [ "$STATE" = "active" ]; then
break
fi
done
PS=`loginctl show-session $SESSION | grep Leader= | cut -d "=" -f 2`
AUTH=""
for SPS in `pidtree $PS | sort | uniq`
do
AUTH=`strings /proc/$SPS/environ | grep XAUTHORITY= | cut -d "=" -f 2`
DISPLAY=`strings /proc/$SPS/environ | grep DISPLAY= | cut -d "=" -f 2`
if [ "$AUTH" != "" ]; then
break
fi
done
/usr/bin/x11vnc -inetd -xkb -skip_keycodes 187,188 -display $DISPLAY -auth $AUTH -noxrecord -noxfixes -noxdamage -unixpw -o /var/log/x11vnc.log -enc none
sleep 2
for i in `loginctl list-sessions | awk '$4 ~ /seat/ { print $1; }'`; do loginctl lock-session $i; done
/usr/local/bin/switch_console 1
Разрешаем выполнение скрипта и запуск процесса.
$ sudo chmod a+x /usr/local/bin/startx11vnc
$ sudo chmod a+x /usr/local/bin/switch_console
$ sudo systemctl daemon-reload
$ sudo systemctl enable xvnc.socket
$ sudo systemctl start xvnc.socket