Ubuntu 18.04 LTS x11vnc 不再起作用

Ubuntu 18.04 LTS x11vnc 不再起作用

我最近从 Ubuntu 16.04 LTS 更改为 18.04 LTS,因为我需要更新版本的 kvm/qemu。

使用 16.04,我可以按照“社区帮助 Wiki”中的说明轻松运行 x11vnc 服务(守护进程):https://help.ubuntu.com/community/VNC/Servers

这有一个设置 x11vnc 守护进程服务所需的脚本,它允许您远程登录计算机,而无需先在本地登录。我需要这个,因为我的机器作为服务器运行,位于地下室,我总是通过 VNC 访问它,而不是本地访问。

最初,我对干净的 18.04 安装没有做任何事,只是systemctl完全按照“社区帮助 Wiki”的说明添加脚本:“让 x11vnc 在任何环境中通过 systemd 自动启动(Vivid+)”。

当发现这不再起作用时,我根据一些搜索做了以下事情:

  1. /etc/gdm3/custom.conf通过编辑和设置WaylandEnable=false此脚本来禁用“Wayland”显示管理器:

    [daemon]
    # Uncoment the line below to force the login screen to use Xorg
    #WaylandEnable=false
    WaylandEnable=false  <--- HERE
    
  2. 将命令更改/lib/systemd/system/x11vnc.service ExecStart为使用不同的xauth指令,因为在 18.04 中似乎没有$HOME/.Xauthority可以通过指令找到的自动生成的文件-xauth guest

    从:

    ExecStart=/usr/bin/x11vnc -auth guess -forever -loop -noxdamage -repeat -rfbauth /home/USERNAME/.vnc/passwd -rfbport 5900 -shared
    

    到:

     ExecStart=/usr/bin/x11vnc -auth /run/user/120/gdm/Xauthority -forever -loop -noxdamage -repeat -rfbauth /home/USERNAME/.vnc/passwd -rfbport 5920 -shared
    

我根据对 Xauthority 的一些阅读和测试做到了这一点,这表明.Xauthority令牌的位置现在是通过$XAUTHORITY环境变量给出的。

为了找到这个值,我运行以下“ find”命令来查找哪些进程XAUTHORITY定义了环境变量。

注意:这使用 linux/proc/<procid>/environ文件结构来搜索进程环境变量,

cd /proc
sudo find . -maxdepth 1 -type d -exec sh -c "(test -f '{}'/environ && cat '{}'/environ | tr '\0' '\n' | grep XAUTHORITY= )" \;

这返回了两个不同的结果:

  • XAUTHORITY=/run/user/120/gdm/Xauthority
  • XAUTHORITY=/run/user/1000/gdm/Xauthority

然后我使用下面的方法找到相应的进程 ID:

sudo find . -maxdepth 1 -type d -exec sh -c "(test -f '{}'/environ && grep -aH XAUTHORITY= '{}'/environ )" \;

这些相应的过程是:

240 tty1     Sl+    0:00 /usr/lib/gnome-session/gnome-session-binary --autostart /usr/share/gdm/greeter/autostart
14923 tty2     Sl+    0:00 /usr/lib/gnome-session/gnome-session-binary --session=ubuntu

其中第一个似乎与登录欢迎屏幕相关,而第二个是用户桌面。

进一步检查环境变量发现一个有USER=gdm,另一个有USER=<ME>

问题是,如果我使用“greeter”身份验证位置,系统会提示我输入密码,然后屏幕变黑/空白。如果我使用用户身份验证位置,则根本无法获得任何客户端连接,因为状态返回无法打开显示的错误:

13/05/2018 16:19:14 *** XOpenDisplay failed.

因此,看起来您被 xauth 机制的改变所困扰了。

有人可以对此提供一些指导吗?

答案1

Ubuntu 18.04 x11vnc 用户。

这是一个“黑客答案”,它允许您无需登录即可获得 VNC 访问权限。

我之所以说是 hack,是因为它涉及运行 2 个 x11vnc 服务。

第一个是允许通过登录DISPLAY=:0,第二个是使用 VNC 通过以下方式访问桌面DISPLAY=:1

为了实现这一点,我使用了以下两个守护进程脚本:

第一个是:x11vnc-login.service仅用于登录问候

[Unit]
Description=Start x11vnc-login at startup.
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -auth /run/user/120/gdm/Xauthority -forever -loop -noxdamage -repeat -rfbauth /home/<ID>/.vnc/password -rfbport 5922 -shared -display :0
[Install]
WantedBy=multi-user.target

第二个是x11vnc.service for desktop::

[Unit]
Description=Start x11vnc at startup.
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -auth /run/user/1000/gdm/Xauthority -forever -loop -noxdamage -repeat -rfbauth /home/<ID>/.vnc/password -rfbport 5920 -shared -display :0
[Install]
WantedBy=multi-user.target

脚本的安装和启用按照社区帮助网站上的文档

这是一个可怕的黑客攻击,但让我暂时运行,直到找到适当的解决方案。

在使用时,我首先打开 VNC 会话到端口 5922 并登录。登录后,您会看到黑屏。然后,您在端口 5920 上打开 VNC 会话,瞧,您的桌面就出现了。对我来说,这比去服务器机器运行的地方要容易得多……

显然,需要一些脚本对正在运行的进程进行初步搜索,以查看用户是否已登录,如果是,则只需使用现有用户部分中的 XAUTHORITY/DISPLAY 信息(从 /proc/PROCID/environ 中提取,否则使用欢迎程序 XAUTHORITY/DISPLAY 将套接字连接到欢迎程序屏幕,然后以某种方式使用用户桌面 XAUTHOURITY/DISPLAY 值将套接字连接移动到另一个 x11vnc 会话。

我怀疑有一点复杂的 fork/socket/文件描述符编程。

另一种可能性是弄清楚是否有某种方法可以让 18.04 显示管理器按照之前的 16.04 运行。

答案2

我遇到了同样的问题,在对 x11vnc 和 gdm 进行一些调整之后,我决定切换回 lightdm:

apt install lightdm

这应该会调出显示管理器配置。如果没有,请运行:

dpkg-reconfigure lightdm

我现在通过主管运行我的 x11vnc 服务器,配置如下:

$ cat /etc/supervisor/conf.d/x11vnc.conf
[program:x11vnc]
command=/usr/bin/x11vnc -xkb -safer -nopw -once -geometry 1024x768 -auth /var/run/lightdm/root/\:0 -display :0
user=root
autorestart=true

此外,我在上面运行 noVNC(也通过主管),这样我就可以通过浏览器远程访问我的桌面。如果您感兴趣,配置文件如下所示:

$ cat /etc/supervisor/conf.d/novnc.conf
[program:noVNC]
command=/opt/noVNC/utils/launch.sh --vnc localhost:5900
user=root

$ cat /etc/nginx/sites-enabled/novnc
upstream vnc_proxy {
    server 127.0.0.1:6080;
}

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;
    include snippets/snakeoil.conf;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name _;

    location / {
            auth_pam               "Secure Zone";
            auth_pam_service_name  "nginx";
            proxy_pass http://vnc_proxy/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            keepalive_requests 10000;

            proxy_read_timeout 61s;

            proxy_buffering off;
    }
}

您可能需要为其添加一些额外的安全措施。

答案3

使其重新运行的最简单方法是从 GDM3 切换回 LightDM。

顺便说一句,这绝不是任何形式的降级/倒退。

ubuntu 18.04 通过 VNC 连接到登录屏幕

答案4

这是另一种解决方法,使用 tmux 使其在 gdm3 上运行而无需切换到 lightdm。在大多数情况下,您可以通过端口 5900 登录。

#!/bin/bash


if [ -z "$1" ]; then echo "Please pass the password you would like to use as an argument to this script"; exit 1 ; else echo "Good start.going ahead."; fi

apt update && apt install tmux -y
password=$1
passwordfile='/etc/x11vnc.pass'
servicefile='/etc/systemd/system/x11vnc.service'
timerfile='/etc/systemd/system/x11vnc.timer'
script='/usr/bin/startxvnc'
apt-get update
apt-get install x11vnc net-tools -y
x11vnc -storepasswd $password $passwordfile



cat >$servicefile <<'EOT'
[Unit]
Description="x11vnc"
Requires=display-manager.service

[Service]
Type=simple
#Environment=XAUTHORITY=$(ps aux | grep -o -E "(-auth)(.*)(Xauth)[a-zA-Z]+")
#ExecStartPre=tmux new -s x11vnc -d
ExecStart=bash -c /usr/bin/startxvnc
#ExecStop=tmux kill-session -t x11vnc
Restart=on-failure
RestartSec=2

[Install]
WantedBy=graphical.target
WantedBy=multi-user.target


EOT


cat >$timerfile <<'EOT'
Unit]
Description=Wait for some time before running X11VNC

[Timer]
OnBootSec=5sec

[Install]
WantedBy=timers.target

EOT




cat >$script <<'EOT'
#!/bin/bash

getxauths()
{
xauths=()

ps aux | grep -o -E "(-auth)(.*)(Xauth)[a-zA-Z]+" | (while IFS= read -r xauth
do
xauths+=("$xauth")
done
printf "%s\n" "${xauths[@]}" | sort -u
) }


getpname()
{
#psp=$(ps -p $(lsof -t -i:5900) -o command)
psp=$(cat /proc/$(lsof -t -i:$1)/cmdline)
echo $psp
}

killproc()
{
pkill -9 $(lsof -t -i:$1)
echo "Killed by port $1"
}


starttmux()
{
xauth=$1
        tmux new -s $xauth -d
        tmux send-keys -t $xauth:0 "for (( ; ; )) ; do sleep 3s; ((disp ^= 1)) ; /usr/bin/x11vnc -display :\$disp -auth $xauth -rfbauth /etc/x11vnc.pass -shared -forever ; done" Enter

}

#echo $(getpname)
start() {
for (( ; ; )) ; do

#echo $psp
xauths=$(getxauths)
for xauth in $xauths ; do
xauth="$xauth" | xargs
if [[ ${xauth} != *"-auth"* ]];then
            unset tsessions
            tsessions=($(tmux list-sessions -F '#{session_name}'))

echo "tessions is " ${tsessions[@]} 

echo "xauth is " ${xauth}
        if [[ ! " ${tsessions[@]} " =~ " ${xauth} " ]]; then
starttmux $xauth


psp=$(getpname 5900)
echo $psp | grep -E -o "(-auth)(.*)(Xauth)[a-zA-Z]+" | (while IFS= read -r xold
do
sessionname=$(echo ${xold#"-auth"} | xargs)
#tmux kill-session -t "$sessionname"
        if [[ ! " ${tsessions[@]} " =~ " ${xauth} " ]]; then
            if [[ $psp == *"user/125"*  ]] ; then killproc 5900 ; tmux kill-session -t "$sessionname"  ; echo "session name is $sessionname" ;
             fi ; else starttmux $xauth ; sleep 30s ; fi
done)

        fi

fi


done

sleep 3s
done
}
start
EOT

chmod u+x $script
sed -i -e 's/WaylandEnable=true/WaylandEnable=false/g' /etc/gdm3/custom.conf 
sed -i -e 's/#WaylandEnable=false/WaylandEnable=false/g' /etc/gdm3/custom.conf 

systemctl daemon-reload
systemctl enable x11vnc.timer
systemctl stop x11vnc.service
systemctl disable x11vnc.service
systemctl restart x11vnc.timer

相关内容