This is (supposed to be) a guide how to do remote X applications. The focus is on security issues. I have written this document for several reasons.
use xhost
+hostname
or even xhost +
to
allow X connections. This is ridiculously insecure,
and there are better methods.This document has been written with unix-like systems in mind. If either your local or remote operating system are of another flavour, you may find here how things work. However, you will have to translate examples yourself to apply to your own system(s).
A related document on WWW is What to do
when Tk says that your display is insecure
<http://ce-toolkit.crd.ge.com/tkxauth/>. It was written by Kevin Kenny.
It suggests a similar solution to X authentication to that in this
document (xauth). However, Kevin aims more at using xdm to steer xauth
for you.
The X System Window System Vol. 8 X Window System Administrator's
Guide
by O'Reilly and Associates
has also been brought to my attention as a good source of information.
Unfortunately, I've not been able to check it out.
Yet another document much like this, titled
Securing X Windows
, is available at <http://ciac.llnl.gov/ciac/documents/ciac2316.html>.
This is version 0.2.4. No guarantees, only good intentions. I'm open to suggestions, ideas, additions, useful pointers, (typo) corrections, etc... I want this to remain a simple readable document, though, in the best-meant HOWTO style. Flames to /dev/null.
The most recent version of this document is always available on WWW at <http://www.xs4all.nl/~zweije/xauth.html>. This document is posted irregularly to comp.windows.x. It is also available as the Linux Remote X Apps mini-HOWTO at <http://sunsite.unc.edu/LDP/HOWTO/mini/Remote-X-Apps>. Linux (mini-)HOWTOs are available by http or ftp from sunsite.unc.edu.
Contents last updated on 5 August 1997 by Vincent Zweije.You're using two computers. You're using the X window system of the first to type to and look at. You're using the second to do some important graphical work. You want the second to show its output on the display of the first. The X window system makes this possible.
Of course, you need a network connection for this. Preferably a fast one; the X protocol is a network hog. But with a little patience and suitable protocol compression, you can even run applications over a modem. For X protocol compression, you might want to check out dxpc <http://ccwf.cc.utexas.edu/~zvonler/dxpc/> or lbx <http://sunsite.unc.edu/LDP/HOWTO/mini/LBX>.
The magic word is DISPLAY
. In the X window system,
a display consists (simplified) of a keyboard, a mouse and a screen.
A display is managed by a server program, known as an X server.
The server serves displaying
capabilities to other programs that
connect to it.
A display is indicated with a name, for instance:
DISPLAY=light.uni.verse:0
DISPLAY=localhost:4
DISPLAY=:0
The display consists of a hostname (such as
light.uni.verse
and localhost
), a colon
(:
), and a sequence number (such as 0
and
4
). The hostname of the display is the name of the computer
where the X server runs. An omitted hostname means the local host.
The sequence number is usually 0
-- it can be varied if
there are multiple displays connected to one computer.
If you ever come across a display indication with an extra
.n
attached to it, that's the screen number. A
display can actually have multiple screens. Usually there's only one
screen though, with number n=0
.
Other forms of DISPLAY
exist, but the above will do for
our purposes.
The client program (for instance, your graphics application)
knows which display to connect to by inspecting the DISPLAY
environment variable. This setting can be overridden, though, by
giving the client the command line argument -display
hostname:0
when it's started. Some examples
may clarify things.
Our computer is known to the outside as light
, and we're
in domain uni.verse
. If we're running a normal X server,
the display is known as light.uni.verse:0
. We want to
run the drawing program xfig
on a remote computer, called
dark.matt.er
, and display its output here on light.
If you have csh running on the remote computer:
Or alternatively:dark% setenv DISPLAY light.uni.verse:0
dark% xfig &
If you have sh running on the remote computer:dark% xfig -display light.uni.verse:0 &
Or alternatively:dark$ DISPLAY=light.uni.verse:0
dark$ export DISPLAY
dark$ xfig &
Or, of course, also:dark$ DISPLAY=light.uni.verse:0 xfig &
dark$ xfig -display light.uni.verse:0 &
The server will not accept connections from just anywhere. You don't want everyone to be able to display windows on your screen. Or read what you type -- remember that your keyboard is part of your display!
Too few people seem to realise that allowing access to your display poses a security risk. Someone with access to your display can read and write your screens, read your keystrokes, and read your mouse actions.
Most servers know two ways of authenticating connections to it: the host list mechanism (xhost) and the magic cookie mechanism (xauth). Then there is ssh, the secure shell, that can forward X connections.
Xhost allows access based on hostnames. The server maintains a list of hosts which are allowed to connect to it. It can also disable host checking entirely. Beware: this means no checks are done, so every host may connect!
You can control the server's host list with the xhost
program.
To use this mechanism in the previous example, do:
This allows all connections from hostlight$ xhost +dark.matt.er
dark.matt.er
.
As soon as your X client has made its connection and displays a window,
for safety, revoke permissions for more connections with:
You can disable host checking with:light$ xhost -dark.matt.er
This disables host access checking and thus allows everyone to connect. You should never do this on a network on which you don't trust all users (such as Internet). You can re-enable host checking with:light$ xhost +
light$ xhost -
xhost -
by itself does not
remove all hosts from the access list (that would be quite useless -
you wouldn't be able to connect from anywhere, not even your local
host).
Xhost is a very insecure mechanism. It does not distinguish between different users on the remote host. Also, hostnames (addresses actually) can be spoofed. This is bad if you're on an untrusted network (for instance already with dialup PPP access to Internet).
Xauth allows access to anyone who knows the right secret
. Such a
secret is called an authorization record, or a magic cookie. The cookies
for different displays are stored together in ~/.Xauthority
.
Your ~/.Xauthority
must be inaccessible for group/other
users.
Xauth has a clear security advantage over xhost. You can limit access to specific users on specific computers. It does not suffer from spoofed addresses as xhost does. And if you want to, you can still use xhost next to it to allow connections.
If you want to use xauth, you must start the X server with the
-auth authfile
argument. If you use the startx
script, that's the right place to do it. Create the authorization
record as below in your startx script. If you don't have urandom, use
some other means of generating random data. ps -axl
will
probably do.
Excerpt from /usr/X11R6/bin/startx:
dd if=/dev/urandom count=1|md5sum|sed -e 's/^/add :0 . /'|xauth -q
xinit -- -auth "$HOME/.Xauthority"
This is a stripped down version of my startx. See startx(1x), xinit(1x), xauth(1x), md5sum(1) to customise your startx script.
-
) to the checksum to
indicate that it was computed over its standard input. If you can't
convince md5sum to forget about the dash, you can strip it with sed.
Change the argument to the sed command as below. In fact, this
ought to work with non-dash-appending md5sums as well, but it's less
understandable. (Thanks Jeffrey)
... 's/^\([0-9a-f]*\).*$/add :0 . \1/' ...
If you can't edit the startx script (because you aren't root), get your system adminstrator to set up startx properly, or let him set up xdm instead. If he can't or won't, you can make a ~/.xserverrc script. If you have this script, it is run by xinit instead of the real X server. Then you can start the real X server from this script with the proper arguments. To do so, have your ~/.xserverrc use the magic cookie line above to create a cookie and then exec the real X server:
#!/bin/sh
dd if=/dev/urandom count=1|md5sum|sed -e 's/^/add :0 . /'|xauth -q
exec /usr/X11R6/bin/X "$@" -auth "$HOME/.Xauthority"
If you use xdm to manage your X sessions, you can use xauth
easily. Define the DisplayManager.authDir
resource in
/etc/X11/xdm/xdm-config
. Xdm will pass the -auth argument
to the X server when it starts, and all will be well. See xdm(1) for
more information. For instance, my /etc/X11/xdm/xdm-config
has the following line in it:
DisplayManager.authDir: /var/lib/xdm
Now that you have started your X session on the server
host light.uni.verse
and have your cookie in
~/.Xauthority
, you will have to transfer the cookie to the
client host, dark.matt.er
.
The easiest is when your home directories on light
and
dark
are shared. The ~/.Xauthority
files are
the same, so the cookie is transported instantaneously.
If not, you can transport the cookie by means of rsh
,
the remote shell:
light$ xauth nlist :0 | rsh dark.matt.er xauth nmerge -
~/.Xauthority
(xauth nlist :0
).dark.matt.er
(| rsh
dark.matt.er
).~/.Xauthority
there (xauth nmerge
-
).It's possible that rsh
doesn't work for you. Besides
that, rsh
also has a security drawback (spoofed host names
again, if I remember correctly). If you can't or don't want to use
rsh
, you can also transfer the cookie manually, like:
light$ echo $DISPLAY
:0
light$ xauth list $DISPLAY
light/unix:0 MIT-MAGIC-COOKIE-1 076aaecfd370fd2af6bb9f5550b26926
light$ rlogin dark.matt.er
Password:
dark% setenv DISPLAY light.uni.verse:0
dark% xauth add $DISPLAY . 076aaecfd370fd2af6bb9f5550b26926
dark% xfig &
[15332]
dark% logout
light$
See also rsh(1) and xauth(1x) for more information.
An X application on dark.matt.er
, such
as xfig
above, will automatically look in
~/.Xauthority
there for the cookie to authenticate itself
with.
<PLUG CLASS="shameless">
Authority records are transmitted with no encryption. If you're
even worried someone might snoop on your connections, use ssh, the secure
shell. It will do X forwarding over encrypted connections. And besides,
it's great in other ways too. It's a good structural improvement
to your system. Just visit <http://www.cs.hut.fi/ssh/>, the ssh home page.
</PLUG>