Der Ente ist ein Fluss.

As I did a lot of work with thin clients in my previous job, I am still interested in remote-controlling computers. In my opinion, thin clients are a nice thing in theory, because it should be easier to bundle all the computing power in a central server cluster than in many heavy computers, but on the other hand, when I see the Raspberry Pi and the plenty of pretty small and energy-saving desktop computers, I do not think that thin clients will have a bright future anymore.

On the other hand, one may want to provide one's workers or students a way to log into their accounts from outside, and use some graphical applications. Or one does not have a license or simply does not want to run some proprietary software on all users' computers. Or one just wants to assist somebody else configuring his computer.

There are plenty of protocols. Sufficiently expensive versions of Windows come with an integrated RDP server, Max OS X comes (or at least came when I used it) with an integrated VNC server, and some proprietary Apple Talk stuff, if I remember correctly. Linux has X11. The oldest of these protocols. With its twenty years of experience, it is the king of them!

As if! Under Windows, I could run multiple sessions at once. Lock them locally, so nobody can access it on the screen, and reattach them remotely, and vice versa, seamlessly. With X.org, I have not found a possibility to do so yet. The problem is that xscreensaver is an X client itself. I always hoped that using chvt(1) to remotely switch to another tty and grab the keyboard there to forbit using Ctrl-Alt-F7 to switch back, until the password is entered, would be a solution, but I never found the time to actually configure this. And I guess that with the rise of Wayland, at least at the moment it is not really worthwile investing time in X11 for a setup that might be obsolete soon.

However, X-Forwarding through SSH is too slow. So here are some personal notes on how to run a vnc server under Ubuntu, to remotely start sessions. Please do not copypaste them, read the documentation and think about what you do before doing it. These are personal notes I share with the world in the hope that it will make it easier for them to use these tools.

Firstly, make sure that the packages x11vnc, xdm and xvfb are installed - besides, of course, your usual desktop environment. Also, tmux or screen is useful for remote configuration. You will be asked whether xdm should become the default display manager during the installation, be careful not to accidentally change the setting you had before.

For me, xdm is not the default display manager, and I want to keep it that way for now. If xdm is your default display manager, adapt the following steps appropriately!

The file /etc/X11/xdm/Xservers configures which X-Servers are started automatically by xdm. I commented out the default line containing ":0", as my default display manager already uses this display - if you are running xdm as default display manager, you probably want to leave it there.

I added the following line:

:1 local /usr/bin/Xvfb :1 +extension DPMS +extension DAMAGE +extension MIT-SHM -extension RANDR +extension XTEST -nolisten tcp -screen 0 1000x700x24

I deactivated the RANDR extension, as x11vnc cannot handle it properly. I set the screen size to 1000x700, as this fits to my laptop screen, and 24 bit colors, as I get strange errors with some parts of texts "blackened out" for the default 8 bit depth, and Xvfb refuses to use 32 bit depth. The DAMAGE extension seems to be useful, at least according to x11vnc(1). And XTEST is something one just wants to have.

Now the problem is that the initscript will not start xdm, if it is not the default window manager. However, as I mainly use this for accessing my own computer remotely, I have root access, and I prefer not to overcomplicate things and start it manually in a tmux session whenever I need it. So I run

# xdm -nodaemon

to keep it in the foreground. If everything works, now one can start x11vnc. Firstly, we need to know xdm's auth file.

# ls /var/lib/xdm/authdir/authfiles/

should reveal its name, for me, this time it is /var/lib/xdm/authdir/authfiles/A\:1-oWmG8O. VNC itself does have some encryption methods, but still the easiest way to encrypt the traffic is probably an SSH tunnel, and many VNC viewers natively support SSH tunneling. We will therefore use the -localhost option, and tunnel the traffic. I furthermore set the port to 5901, because I prefer this. However, if multiple users have accounts on your machine, you should use password authentification. I often use pwgen to generate random passwords. For this time, my password is xPexeG2b0JeYTC1ZvzSh (I usually use one-time-passwords and generate them every time, and just copypaste them). x11vnc can read password files, so we just create one and set the apropriate rights using

# echo "xPexeG2b0JeYTC1ZvzSh" > mypwd
# chmod 0400 mypwd

Now I can start x11vnc:

# x11vnc -passwdfile mypwd -localhost -rfbport 5901 -ncache 20 -flashcmap -display :1 -auth /var/lib/xdm/authdir/authfiles/A\:1-oWmG8O

The -ncache option makes x11vnc use a larger virtual frame buffer inside the vnc viewer, as an image cache. If this gets on your nerves, you can deactivate it.

Now using the -L localhost:5901:localhost:5901 option for ssh, we can tunnel our connection, and access it on the client with our favourite vnc viewer, which ever that is. I have no clear favourite, but currently I mostly use TightVNC. The problem is that this viewer (and maybe other viewers?) recognizes the local connection and optimizes for quality rather than bandwidth. To prevent this, one can do

$ xtightvncviewer localhost:1 -encodings "copyrect tight hextile zlib corre rre raw"

The number :1 must be replaced by your rfb-port minus 5900. If I find the time, I will maybe try to write some code to automate the process of starting and connecting.

As always, suggestions on alternatives and simplifications are appreciated!