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.