Headless X11
2015-03-17
4 minutes read

updated 2015-12-16: added section on how to start x11vnc in Systemd.

In many situations it is quite handy to have a working graphical environment for testing out websites, or doing other sorts of things in which a GUI is more suitable than the command line. When running in a headless situation, accessing the GUI on a remote host is relatively easy: you can forward X11 (given that bandwidth is not a real issue) or you can use remote-desktop like functionality, like VNC. One of the main issues with the latter is that you need to be logged in prior to opening the connection, quite unhandy if your remote host is actually a virtualised machine on a box somewhere where you cannot easily reach it (let aside being able to connect it to a real display). Instead, I’d like to be able to connect to a remote host and login as I would do normally in a non-virtualised world with a real display. This post walks you through the necessary steps to set up such an environment. I use Debian as my preferred distribution, but it should be trivial to convert the steps to the distribution of your choice.

The basic idea behind running a headless X11 instance this way is that you install a dummy video driver for X11 and let X11VNC use this dummy driver instead. In order to complete the setup we start the X11VNC server once the X11 server is up and running.

Installation

Install the additional prerequisites:

$ sudo apt-get install xserver-xorg-video-dummy x11vnc
...

Once installed, we need to modify the X11 configuration in order to make use of the dummy video driver. If your machine does not yet have a X11 configuration, you can create one by invoking sudo X -configure and move the /root/xorg.conf.new file to /etc/X11/xorg.conf. Edit the file /etc/X11/xorg.conf:

  • change the Device option in the default screen section from Card0 to Dummy;
  • add a new dummy device section:
Section "Device"
    Identifier "Dummy"
    Driver "dummy"
    Option "IgnoreEDID" "true"
    Option "NoDDC" "true"
EndSection

If you do not have a graphics card at all, you can use the following template as a starter, which should give you resolutions up to 1280×1024:

Section "Device"
    Identifier  "Dummy"
    Driver      "dummy"
    VideoRam    256000
    Option      "IgnoreEDID"    "true"
    Option      "NoDDC" "true"
EndSection

Section "Monitor"
    Identifier  "Monitor"
    HorizSync   15.0-100.0
    VertRefresh 15.0-200.0
EndSection

Section "Screen"
    Identifier  "Screen"
    Monitor     "Monitor"
    Device      "Dummy"
    DefaultDepth    24
    SubSection  "Display"
        Depth   24
        Modes   "1920x1080" "1280x1024"
    EndSubSection
EndSection

Next, we need to ensure that x11vnc is properly configured: we need to create a password file in order to get in:

$ sudo mkdir /etc/x11vnc
$ sudo x11vnc -storepasswd /etc/x11vnc/passwd
Enter VNC password: (enter a password)

Now, depending on the exact version of Debian you’re running, you need to start x11vnc once the X11 server is started.

Systemd

If your distribution happens to use Systemd (the recent versions of Debian and Ubuntu do), you can create the following unit file in /etc/systemd/system/x11vnc.service:

[Unit]
Description=VNC server for X11
Requires=display-manager.service
After=display-manager.service

[Service]
Type=forking
ExecStart=/usr/bin/x11vnc -forever -bg -o /var/log/x11vnc.log -auth guess -rfbauth /etc/x11vnc/passwd -rfbport 5900 -xkb -noxrecord -noxfixes -noxdamage -shared -norc

[Install]
WantedBy=multi-user.target

Be aware that the ExecStart line should be a single line!

After creating the unit file, you need to reload your Systemd daemon, enable and start the new service:

$ sudo systemctl daemon-reload
$ sudo systemctl enable x11vnc.service
$ sudo systemctl start x11vnc.service

GDM3

For GDM3-based distributions, like Debian Wheezy, you need to edit /etc/gdm3/Init/Default and add the following line right before the last line stating exit 0:

/usr/bin/x11vnc -forever -bg \
  -o /var/log/x11vnc.log \
  -auth guess \
  -rfbauth /etc/x11vnc/passwd \
  -rfbport 5900 \
  -xkb -noxrecord -noxfixes -noxdamage

Note that x11vnc is smart enough to “guess” which form of authentication it should use to connect to X11, making it unnecessary to specify the exact path to the authority file (which is highly dependent on the used display manager).

Upstart

If your distribution is using upstart, like Ubuntu, you need to create a file /etc/init/x11vnc.conf with the following contents:

start on login-session-start
script
/usr/bin/x11vnc -forever -bg \
  -o /var/log/x11vnc.log \
  -auth guess \
  -rfbauth /etc/x11vnc/passwd \
  -rfbport 5900 \
  -xkb -noxrecord -noxfixes -noxdamage
end script

When done, you can reboot your machine and if all is well, you should be able to use your favourite VNC client (e.g. ⌘+K on OSX) to connect to this machine and be presented with a login screen. The VNC client will ask for a password, which is the same one as you defined earlier when creating /etc/x11vnc/passwd.

If you are running Ubuntu, chances are that you are running light-locker instead of Xscreensaver. In this case, it might occur that once the screen is locked, you no longer can unlock it through your VNC connection. It appears that this is due to the fact that light-locker does some magic with the DISPLAY environment variable thereby confusing x11vnc. A workaround for this is to replace light-locker with Xscreensaver:

$ sudo apt-get purge light-locker && sudo apt-get install xscreensaver

Back to posts