Wow, did that ever bring out my Alpha Geek! This just needs to be recorded as a HOWTO. Too bad my style is so narrative. :-O

All I wanted was to remotely start an X server that my kids couldn't get to. I'm running Debian unstable, and I routinely use an ssh tunnel to connect to my home computer from anywhere: work, travel, friends' houses... I use x11vnc to export a real X display, providing all the comforts of home.

This time, the kids were already running a desktop of their own. I could've reconfigured gdm to start multiple displays, but when I restarted, I'd probably kill their desktop. I needed a way to start a new X server -- preferably using my standard X session, restoring my accustomed desktop -- on a display other than :0. And hey, while we're at it, let's start it on something the kids can't get to with CTRL+ALT+(<F6> through <F12>) , like :10.

Thus began my descent into the Xwrapper.config, startx, and xauth...

Note: This information is out of date. I do some pretty silly things trying to reach my objective. The first comment, below, gives a much easier way to start a display your kids can't see. It even works without any modifications on my Debian system.

A Solution

First, the background. We are talking about a Debian Lenny/Unstable system. It's behind a firewall running Debian Etch/Stable/4.0. From a remote site, I can ssh -L 5900:lenny:5900 etch.dynip.org, setting up a tunnel for VNC between the remote computer and the desktop, and providing a command line on the firewall. From there I ssh to lenny to run my commands. The Quest: start my X desktop on a display that can't be reached with the standard shortcut keys, then connect to it using VNC on the remote computer. (Whew!)

Of course, every good quest begins with a Google search. This revealed multiple possibilities; I chose to try manually starting the X display with startx. The expected invocation was:

startx -- :10

This failed for me right away, with:

X: user not authorized to run the X server, aborting.

More Googling, and I realize I need to change my Xwrapper.config, so instead of "allowed_users=console", it says "allowed_users=anybody". Why? Aren't I logged in to a console via ssh? Yes, but with "screen" running, the X server can't really tell that I'm on a console, and I can't find anything on Google to fix that. The Debian Way to fix this is with the following magic spell:

dpkg-reconfigure x11-common

(not xserver-common, as some sites led me to believe). That requires root privileges, so either su or sudo, however your system is configured. (Note to other geeks: you may think you can skip this and just sudo startx. And you can, but then there's no way to connect to the resulting display that I can discover.)

That allowed me to call X. But then came problem number two:

xauth: error in locking authority file /home/lenny/.Xauthority

Followed by several repetitions of:

AUDIT: Thu Aug 2 13:52:50 2007: 4862 X: client 1 rejected from local host (uid 1000)
Xlib: connection to ":10.0" refused by server
Xlib: No protocol specified

This requires an additional ssh session to find and kill, since startx appears impervious to CTRL+C. More Googling, with no exact answers. I learn lots about X, though. The Google results suggest that the xinit scripts are trying to start a client, but they're not authorized to connect. The startx script is supposed to generate magic cookies and other authority files. Looking there, I find what looks like a problem. The XAUTHORITY variable, indicating which file the clients are supposed to find their magic cookie in, is set to $HOME/.Xauthority:

if [ x"$XAUTHORITY" = x ]; then XAUTHORITY=$HOME/.Xauthority export XAUTHORITY fi

...whereas the server is pointed at $HOME/.serverauth.>ID<:

xserverauthfile=$HOME/.serverauth.$$ serverargs=${serverargs}" -auth "${xserverauthfile}

So, I change the XAUTHORITY variable to $HOME/.serverauth.$$, and my error messages go away!

Of course, the terminal is... occupied. Nothing CTRL+Z followed quickly by bg doesn't fix. Then I try to start x11vnc, to export my new display. Enter problem number 3, buried in what looks like reams of output:

Xlib: connection to ":10.0" refused by server
Xlib: No protocol specified


02/08/2007 06:23:42 ***************************************
02/08/2007 06:23:42 \*\*\* XOpenDisplay failed (:10)

\*\*\* x11vnc was unable to open the X DISPLAY: ":10", it cannot continue.
\*\*\* There may be "Xlib:" error messages above with details about the failure.

This is obviously another authority problem, I figure. Looking at the startx script, I realize that its clients all have the XAUTHORITY set, but anything outside the script (like the original shell I'm using) don't. I change my incantation slightly, setting the variable beforehand:

XAUTHORITY=/home/lenny/.serverauth.10073 x11vnc -display :10 -rfbport 5900

You may wonder what all that hand-waving means. First, I set the XAUTHORITY variable to point at the correct file. Then, I call x11vnc, to export my display. I tell it which display to use with -display :10. This would make it broadcast on port 5910, but since I haven't tunneled that port, I tell it to use 5900 instead with -rfbport 5900.

Finally, on my remote machine, I start my VNC viewer, point it at localhost:5900, and start using my new, stealthy desktop. Bwaaaaah-hahahahaha!


A Better Solution

But wait! I haven't filed a bug report on the startx script yet! That's certainly my duty, as a beta-tester. It's the easiest way to contribute to the community that provided me with all these Free tools.

That's a big step. I may call myself the Alpha Geek, but the people who put these things together are WAY smarter than me. They're the Omega Geeks. If I'm having problems, maybe it's not their code; maybe it's my limited understanding.

I examine the code again, read some more Google, and after suitable meditation, I reach enlightenment: the code checks my default authority file and uses the cookie there if it's available! All I need to do create an .Xauthority in my home directory, with a cookie for each display I may need to use. There are even tools to do it!

I return the startx script to normal. Besides this benefit, I won't have to specify an XAUTHORITY for x11vnc, meaning I can automate things later on.

One-Time Steps

There are scripts online that can simplify this, but I like doing things interactively to learn. I start by generating a nice random-number cookie with:

dd if=/dev/urandom count=1 | md5sum

Then I add a cookie for my display to my default authentication file:

xauth add :10 . <my cookie>

(I had an error about being unable to lock the .Xauthority, but I just deleted it and tried again.)

If you didn't reconfigure the Xwrapper.config the first time around, do it now. If it's not set to allowed_users="anybody", you won't be able to start X unless you're root, which causes other problems.

Standard Launch Sequence

Whenever I want to start my stealth display, I log in to my firewall and create the tunnel:

ssh -l etch -L 5900:lenny:5900 etch.dynip.org

From my firewall, I log on to my home computer:

ssh -l lenny lenny

On my home computer, I run startx, specifying a display that's in my $HOME/.Xauthority:

startx -- :10 &

The little '&' in there makes it run in the background, so I can continue to use the terminal. (Otherwise I'd have to ssh in from a new window.) After it quiets down, and I've decided it's started everything it needs, I start x11vnc. This time, the cookie for the display is already in the default location, so I don't have to specify it:

x11vnc -display :10 -rfbport 5900

Finally, from my remote computer, I start my VNC viewer. I tell it to open

localhost:5900

and I get a display of my home computer desktop. (Some people may have to actually specify 127.0.0.1:5900.)


Now, if anybody knows how to avoid allowing anybody to open an X display, let me know. I'd like to make this bulletproof.