Monthly Columns
 

Remote X

Copyright © 1999 Glenn Ramalho

The X Window System uses a network protocol to implement its internal communication mechanism, making remote connections occur transparently to the user. In the December 97 issue of Daemon News I wrote an article titled An Introduction to X which explained overall how this system works. Now in this article I will talk about how to use this feature.

There is exactly one X server for each set of a keyboard, a mouse and a display (a combination of one or more monitors). This X server is responsible for controlling the hardware assigned to it. Any X clients (e.g: xclock, xterm, xlock) must go through this server to communicate with its hardware. The details of how this communication takes place goes beyond the scope of this article. For now it is enough to say that each server is assigned a unique address that the X clients use to specify which one will be contacted. The X Window System then internally processes this address to find out where the server is and how to communicate with it.

Most computers can not run more than one X server because they do not allow more than one display, keyboard and mouse combination connected at once. Usually when you see two or more monitors on one system, they are all treated by X as different parts of the same display. In this case X referrers to each of these monitors as "screens". Exactly how the user interacts with these two screens depends on the window manager being used. Some window managers make the screens operate together like one big continuous monitor, while others keep the different desktops on each screen with little interaction between them. For more information on window managers, I have a section on them in the December 97 article I mentioned above.

The syntax of the server address consists of the hostname of the computer it is on followed by the number of the X server to use:

hostname:server
  • hostname: the name or IP address of the system on which the X server is running. If it is omitted it defaults to "localhost".
  • server: the number of the X server on a system. Unless you use SSH with X, this number will usually be 0 as most systems have at most one display, keyboard and mouse. SSH is a special case and I will talk about it later in the X Security section.

Note: For systems with multiple screens (also referred to as multi-headed systems), each screen gets assigned a number, with 0 being the primary screen. You can append this number to the end of the X server ID to identify which screen the program is supposed to access. The ID string syntax becomes hostname:server.screen. If it is omitted, it defaults to 0.

This address is usually passed to the X clients by the -display option or by using the environment variable DISPLAY. Here are some examples to illustrate how to use the addresses. My home computer is named salador, so to run an xclock on my screen I would type:

xclock -display salador:0.0

or

xclock -display salador:0

as I just have one monitor. This address above can be used from salador or landreth, another computer in my apartment. The X internals will worry about whether a remote connection is necessary or not to reach the requested server. The hostname can also be specified as an IP address:

xclock -display 10.0.0.2:0.0

If I run the command straight from salador, I do not need to specify the name of the computer in the X server address:

xclock -display :0.0

or

xclock -display :0

On these cases, I omitted the host name so commands default to localhost. I could also have entered localhost as the name of the host and I would get the same results. If this computer had two monitors, the screen field would specify which screen to use:

xclock -display salador:0.1

for remote connections. For local connections we can use

xclock -display :0.1

Notice that in the examples above, I am still using the same X server: salador:0.

The address can also be set by the DISPLAY environment variable:

DISPLAY="salador:0.0"; export DISPLAY (for sh, ksh, pdksh, bash, zsh, etc.)

or

setenv DISPLAY "salador:0.0" (for csh and tcsh)

This variable sets the default value for the -display option and it is only used if a X client is started without specifying the -display option. This variable is usually set automatically by the X startup scripts when you begin an X session to make sure all the X clients come up on the right X server. If no X server is specified either through the command line or through the environment variable, the clients usually return an error message.

X Security

All this is nice, but there is still one big question: If any user can get an X client to talk to any server, how does a user block unwanted connections to the X server he is using? A malicious user could easily direct a series of X clients to another user's X server. These requests could be simple annoyances like changing the color of someone's background or popping up new windows on his screen, but they can also involve more serious intrusions like monitoring the user's keyboard for passwords or typing in the user's windows. Tools like xset and xv can easily be used to change the background on the desktop and turn on or off key click on someone's keyboard. If there is no security in place, one user just as easily change his settings or someone else's settings. The scary part comes with monitoring someone's keyboard that also is very easy to do under X.

To remedy this problem X also has a security system in place. The default system is to refuses all connections from any process except for the one X started from and the processes that already have the display. You can then tell X to allow certain messages to pass through or not depending on who sent the message and where it came from. Note: many X startup scripts already call one or more of these commands below by default.

Xhost

This is the lowest security under X as it operates by opening access to anyone on one or more systems. Each X server keeps a list of hosts that are allowed to connect to it. Any user on a machine specified in the list automatically has access to the X server. You can type:

xhost +hostnameadds a host to the access list.
xhost -hostnameremoves a host from the list
xhost +shuts off all X protection. Anyone in the world can connect to this X server independent of being in the access list. This one is like carrying a shoot me now sign. :)
xhost -revert the above insanity. This one makes only hosts in the access list capable of connecting. If the list is empty, no hosts are allowed to connect.
xhostlists the current access list

In the example below, salador is refusing all connections:

      % xhost
      access control enabled, only authorized clients can connect
   

The xhost command can then be used to add and remove hosts from the list. In the example below landreth was added, but localhost is not on the list so X clients from landreth are allowed to connect, but X clients on salador are not.

       % xhost +landreth
       landreth being added to access control list
       % xhost
       access control enabled, only authorized clients can connect
       INET:landreth
       % xhost -landreth
       landreth being removed from access control list
       % xhost
       access control enabled, only authorized clients can connect
   
In the following example, xhost was set up to allow all connections. This is a bad thing to do as its like dancing with shotguns. xhost - is also used to switch X back to the secure mode:
      % xhost +
      access control disabled, clients can connect from any host
      % xhost
      access control disabled, clients can connect from any host
      % xhost -
      access control enabled, only authorized clients can connect
   

Even if you know that no other user has access to a specific system, it is still not safe to rely on xhost +machine as a secure mechanism. There has been some work on improving the security provided by xhost. Other options include user and system authentication through Kerberos and NIS. Check the man page for xhost(1) for a more detailed description of which other options xhost provides on your systems. Be careful with the xhost +user@hostname as on some X implementations it ignores the user parameter and opens the X server to everyone on hostname although user@hostname still shows up in the access list.

The default on X is to form a wall between the X server and other users. This command is like making a hole in the wall so people can pass freely. Some systems like HP VUE automatically use xhost to open access to all local connections.

Xauth

As the man pages say, the host access list is a rudimentary security system. For grater security there is also a file called .Xauthority that usually resides in your home directory. This file stores a list of keys that the clients that are not in xhost's access list must have to be allowed access. The xauth command is used to manage this file.

Each time X starts up a new password is randomly generated and stored in this list. Any client that has access to the .Xauthority then can send the output to the display. Notice that any X client that you invoke from the same computer you started the X server on is automatically enabled as the same .Xauthority file is accessible by both programs. The same applies if you are using NFS mounted home directories. Any computer you rlogin to that mounts the same directory your X server wrote to also will have access to this .Xauthority file and all the keys in it. To run an X command from any of these places all you have to do is set the DISPLAY variable or use the -display option.

To open access to other computers you must copy the necessary keys into the .Xauthority of the other computer. This command was extracted from xauth's man page and it will work to distribute the key:

xauth extract - | rsh other_system xauth merge -

Rsh requires you to have a correctly configured .rhosts file on the destination system. This is not a requirement of xauth but of rsh. As an alternative, you could instead use SSH for this, but if you have SSH, there is an even safer method of using remote X covered later in this article.

If you have a .rhosts, I have found the following script to be quite useful:

   #!/bin/sh

   $PROGNAME=`basename $0`

   if [ $# -ne 1 || "$1" != "-h" ]
   then
      echo "usage: $PROGNAME [-h] hostname"
      exit 1
   fi

   xauth extract - | rsh "$1" xauth merge -
   

Save this script to a file, make it executable with chmod +x, then run it before you connect to your remote system.

You can type use the command xauth list to see what keys are available in the .Xauthority file:

   % xauth list
   salador:0  MIT-MAGIC-COOKIE-1  414388932141646f5744545554774f4f
   salador/unix:0  MIT-MAGIC-COOKIE-1  414388932141646f5744545554774f4f
   landreth:0  MIT-MAGIC-COOKIE-1  47234571795438693578754338585756
   landreth/unix:0  MIT-MAGIC-COOKIE-1  47234571795438693578754338585756
   %
   

In this case I have keys for salador, my computer and an X server on landreth. Either of the two can be used. Once an X session ends though the key becomes useless as each time an X server is invoked a new key is generated. This system also has some security problems. The key above for example was built using MIT-MAGIC-COOKIE-1 that is sent over the network unencrypted, so it could be grabbed. If another user got the key he would have complete access to your X server. X11R6 also provides another type of key: XDM-AUTHORIZATION-1. This system uses a DES based system to encrypt and authenticate the key. The exact options might change between different releases and versions of X so check the Xsecurity(7) man page for more details.

SSH

Xauth makes it more difficult to break into a system, but it is still not perfect. X windows is inherently insecure, but these commands make it more difficult to break in. Unless the malicious user is desperate to get in to your account, it should drive him away or convince him to try an easier target. The function of a security system after all is not to create a perfectly secure system, but to increase the trouble that the invader must go through. They will only try to break in if the cost of breaking in is less than the value of what they can do once they are in. Methods like this are also effective in keeping the student hacker thinks-he-knows-it-all wanna be away. :)

The most secure system discussed in this article is SSH. Unfortunately, while xhost and xauth are standard X commands and are available in just about any X distribution, SSH is a separate package. To use it, both the SSH client and the SSH server must be installed. If you do not have this software and cannot convince your administrator to install it, xauth will have to do. If you do have SSH, though, you should use it.

SSH is a package that provides replacements for rsh (or remsh on System V), rcp and rlogin. The syntax for these commands is very similar, but all communications are encrypted and compressed. This package also has a special X feature. When you use ssh command to connect to another system from a computer to which you have access to the display, it pretends it is an X server on the target side and waits for X protocol messages. These messages are then tunneled back through ssh's connection where they are handed to the local X server. No new connection is created. Ex: I am logged in on console on salador, my display variable is set by default to ":0.0".

   $ echo $DISPLAY
   :0.0
   

When I use ssh to connect to landreth, this tool allocates a new X server address for me on landreth and stores the address in the DISPLAY environment variable there. In this case, DISPLAY is set to "landreth:10.0". This address works just like any other X server address and landreth treats it as if another X server was running locally on it.

   $ ssh landreth
   ramalho's password:
   Last login: Sat Dec 12 00:30:55 from :0
   Sun Microsystems Inc.   SunOS 5.7       Generic October 1998
   $ echo $DISPLAY
   landreth:10.0
   $ xclock &
   [1]     6810
   $ xload -display landreth:10.0 &
   [2]     6935
   

When you run an X client like above to the address ssh provided, the X protocol messages are encrypted and sent back to salador. Notice that another user could be using the normal X server on landreth, as it uses a different address. Notice also that the X server on salador has no knowledge that another computer was involved as ssh handled all the communication. In fact the X server on salador could be set to have all external connections blocked as the only connection it sees is a local connection from the ssh program to itself.

These are three of the most popular ways to use remote X. Which to use depends on the environment being used. SSH is the easiest to use, as all you have to do is connect to a remote machine, and SSH does the rest. Its disadvantage is SSH must be installed in both the client and the server. SSH is also the most secure one as the messages are encrypted but that extra security comes at the expense of some speed. Depending on the complexity of the encryption you are using, the power of the local and remote machines, and the speed of the connection, this might not be noticeable. SSH also compresses the information automatically so it might in some cases run faster than other security systems. Xauth provides a reasonable alternative where SSH is not practical. Its not encrypted, so people can monitor the messages and even steal the authentication key. It is easy to set up if the .rhosts is in place or the same home directory is NFS mounted on both hosts. Use xhost as a last resort as it is the least secure.

Glenn Ramalho, ramalho@best.com