8

I have recently changed from Ubuntu 16.04 LTS to 18.04 LTS, as I needed a newer version of kvm/qemu.

With 16.04 I was able to easily get the x11vnc service (daemon) running by following the instructions from "Community Help Wiki" : https://help.ubuntu.com/community/VNC/Servers

This has a script required to set up the x11vnc daemon service, which lets you log into a machine remotely without having to first be logged in locally. I require this as I have my machine running as server and located in the basement and I always access it via VNC, not locally.

Initially I did nothing with my clean 18.04 install other than adding the systemctl script exactly as per "Community Help Wiki" instructions: "Have x11vnc start automatically via systemd in any environment (Vivid+)".

On finding that this no longer worked I then did the following based on some searching:

  1. Disabled "Wayland" display manager by editing /etc/gdm3/custom.conf and setting WaylandEnable=false in this script:

    [daemon]
    # Uncoment the line below to force the login screen to use Xorg
    #WaylandEnable=false
    WaylandEnable=false  <--- HERE
    
  2. Changed the /lib/systemd/system/x11vnc.service ExecStart command to use a different xauth directive as in 18.04 it appears that there is no automatically generated $HOME/.Xauthority file which can be found via the -xauth guest directive:

    From:

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

    To:

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

I did this based on some reading and testing on Xauthority, which indicated that the location of the .Xauthority token is now given via $XAUTHORITY environment variable.

To find the value of this I run the following "find" command to find which processes has an XAUTHORITY environment variable defined.

NOTE: this uses the linux /proc/<procid>/environ file structure to search through the process environment variables,

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

This returned two different results:

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

I then used the following to find the corresponding process ids:

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

The corresponding processes for these are:

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

The first of these appears to be associated with the login greeter screen, while the second is the user desktop.

A further check of the environment variables shows that one has USER=gdm and the other has USER=<ME>

The problems is that if I use the "greeter" auth location, then I get prompted to provide a password which is then followed by black/blank screen. If I use the user auth location, then I do not get any client connection at all as the status returns an error that it is unable to open the Display:

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

So it seems that you get caught by the change in xauth mechanism.

Can someone please provide some guidance on this?

4
  • I have done some further testing on this and am providing this as useful input to help try to get definitive resolution. – zebity May 14 '18 at 8:39
  • More tests, note reason for "-rfbport 5920" is kvm/qemu is running with 10 VMs with "slice" vnc listening on 5900-5910 ports. Stopped VMs and logged into host machine. Checking env: "$XAUTHORITY=run/user/1000/gdm/Xauthority" and "$DISPLAY=:1" (not 0). Modified script to: "ExecStart=/usr/bin/x11vnc -auth /run/user/120/gdm/Xauthority -forever -loop -noxdamage -repeat -rfbauth /home/USERNAME/.vnc/passwd -rfbport 5920 -shared - display :1" . x11vnc now connected, so have temp fix. Requires you to be logged in. Need way to get -auth and -display flags based on id.... any idea? Try via inetd? – zebity May 14 '18 at 9:17
  • As problem seemed to be related to changing DISPLAY/XAUTHORITY values across login/desktop access, I tired to see if I could get around this with multiple vnc connections. pending find better solution. see result in answer section. – zebity May 15 '18 at 12:29
  • Any hint in this thread? forums.debian.net/viewtopic.php?t=55327 It mentions gdm3 and x11vnc... – user836482 Jun 1 '18 at 22:18
9

Ubuntu 18.04 x11vnc users.

Here is a "hack answer" which allows you to get VNC access without being logged in.

I say hack as it involves having 2 x11vnc services running.

The first is to allow login via DISPLAY=:0 and the second is to use VNC to get access to desktop via DISPLAY=:1

To achieve this I used the following 2 daemon scripts:

The first is: x11vnc-login.service just for login greeting

[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

The second is: 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

The installation and enablement of scripts is as per documentation on community help site.

This is a horrible hack but gets me running for the time being until a proper solution is found.

In use I first open up VNC session to port 5922 and do login. Once logged in you end up with a black screen. So you then open up VNC session on port 5920 and voila, there is your desktop. Still easier for me than having to go to where the server machine is running...

Obviously what is needed to have some script which does a preliminary search of running processes to see if a user is logged in and if so then just use the XAUTHORITY/DISPLAY info from the existing user section (as extracted from /proc/PROCID/environ, otherwise connect socket up to greeter screen with greeter XAUTHORITY/DISPLAY and then somehow move socket connection over to another x11vnc session using users desktop XAUTHOURITY/DISPLAY values.

A bit of complex fork/socket/file descriptor programming I suspect.

Other possibility is to figure out whether there is some way to get 18.04 display manager to behave as per prior 16.04 one.

3
  • I hypothesised that it should be possible run a single login by using the -env FD_XDM=1 -auth guess arguments. However x11vnc's -findauth mechanism dosn't seem to be able to resolve the XAUTHORITY on gdm3. Do you know if this a limitation gdm3, it is just not supported by x11vnc or am I just plain wrong. Calling x11vnc -env FD_XDM=1 -findauth returns nothing. – McShaman Mar 26 '20 at 21:34
  • It's working! Thank you! a slice correction: in the second service x11vnc.service script, the last parameter in line ExecStart shoud be :1 – RobinHood May 22 '20 at 3:09
  • We came to the same conclusion... I found this while looking for a way to automatically switch. However, systemd now supports starting based on socket calls, and more importantly... it supports variable daemon generation... theoretically we could have ports 5900-5999 auto mapped and started based on calls to the port, by naming the service something like vncserver@.service. unix.stackexchange.com/questions/323914/… Of course, this only makes sense if we render new Xsessions... – Ray Foss Apr 16 at 17:43
6

I had the same issue and after some mucking around with x11vnc and gdm, I decided to simply switch back to lightdm:

apt install lightdm

That should bring up the display manager configuration. If not run:

dpkg-reconfigure lightdm

I now run my x11vnc server via supervisor with the following config:

$ 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

In addition, I run noVNC (also via supervisor) on top so I can access my desktop remotely just via a browser. Just in case you're interested, the configuration files look like this:

$ 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;
    }
}

You may want to wrap some additional security around it.

1
  • 1
    Switching back to lightdm using dpkg-reconfigure worked for me, though I also rebooted my computer in order to start it. – user503821 Jul 16 '18 at 19:52
1

The simplest way to get this working again is switching back from GDM3 to LightDM.

Which, by the way, is absolutely no downgrade/step back in any way.

ubuntu 18.04 connect to login screen over VNC

0

I'll make this short and sweet.

https://x2go.org

0

Another workaround... This one stays locked on port 5900... so you can connect again with the same client config. This works really well for me... if I ever get multiple users I may figure a way to find more displays.

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

[Service]
Type=simple
ExecStart=/bin/sh -c "/usr/bin/x11vnc -display :0 -auth /run/user/126/gdm/Xauthority -forever \
  -noxdamage -repeat -rfbauth /etc/x11vnc.pass -rfbport 5900 -shared \
  -ncache 10 -ncache_cr || \
/usr/bin/x11vnc -display :1 -auth /run/user/1000/gdm/Xauthority -forever \
  -noxdamage -repeat -rfbauth /etc/x11vnc.pass -rfbport 5900 -shared \
  -ncache 10 -ncache_cr"
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target

Don't forget to reload the server. That said on raspberry pi's logs can be a mess as the clock gets set late into boot. sudo nano /etc/systemd/system/vncserver.service && sudo systemctl daemon-reload && sudo systemctl restart vncserver && sudo journalctl -fu vncserver

0

Here's another workaround using tmux to get it work on gdm3 without switching to lightdm. In most cases, you can login through port 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.