X is the GUI environment that's most often used with Linux. As noted earlier, X is a network-enabled GUI environment. This means that X programs use network protocols to display their windows , menus , dialog boxes, and so on, even when they're run on a single computer. Understanding how these protocols work is vital to understanding how to configure two computers to allow remote GUI access. You must set options on both the client and the server.
Understanding the X Client/Server Relationship
Most people who aren't intimately familiar with network protocols tend to think of a server computer as being a big, powerful box that sits in a room somewhere, whereas a client computer is a much smaller and less powerful computer at which the user sits in order to interact with the server. Although this conception is technically inaccurate, it's usually not misleadingas a practical matter (not a matter of definitions), servers usually are powerful systems that handle data requests from less powerful systems at which users sit. This conception leads to confusion, however, in the case of X servers, because the arrangement is exactly the opposite of what most people expect: The user sits at the computer that runs the X server, and this computer can be quite limited in capabilities. The X client programs run on a computer that's often much more powerful than the X server computer.
To understand this peculiar twist, it's useful to think of the situation from the point of view of the client program. When a network client program engages in network interactions, it initiates a connection with a server program in order to transfer data. The server program exists to serve. Consider for comparison a word processor like WordPerfect and its interactions with an NFS server. (Technically, a Linux kernel module functions as the NFS client, but WordPerfect is the program that causes the kernel module to initiate transfers.) You as a WordPerfect user select the options to open a file on an NFS export, so WordPerfect initiates the network transfers, telling the NFS server to deliver a file. The NFS server responds to these requests, delivering a network service to the client. Now, suppose you're running WordPerfect remotely, from a computer in another room, via an X server. WordPerfect functions as a client for the X protocols. When WordPerfect opens a file selector dialog box, it does so by requesting that the X server display a dialog box, text, and so on. To WordPerfect, the X server is just another input/output resource, like an NFS server. The fact that the ultimate destination of the data is a human being is irrelevant to the program. This relationship is illustrated in Figure 14.1.
Figure 14.1. An X server provides an interface between the user and a program that may run on another computer.
An X server provides a GUI display device and one or more input devices (typically, a keyboard and mouse). The X server may itself be a client for other servers, such as font servers (described in Chapter 15, Providing Consistent Fonts with Font Servers). A font server delivers fonts to the X server upon request, allowing many X servers to provide a consistent set of typefaces for users.
When you install Linux on a computer, most distributions allow you to configure an X server. This server can be used to provide local computers with access to the display. Referring to Figure 14.1, such a configuration makes the X client and X server computers one and the same. For instance, Figure 14.1's X server system might have its own X programs that it runs. The X server on a Linux system can also be used to interface with X clients running on other systems, though. Doing so requires issuing a few commands, as described shortly. If both X and other network protocols function normally on a system, it already has all the software it needs to function as an X server, so you need not install any special packages.
X client computers (those that host the programs you want to run remotely) need no special software; the X programs you want to run are the clients. To be sure, these clients almost invariably require various GUI libraries, like Qt or GTK+. With systems based on RPM or Debian packages, though, you'll be told if you need to install such libraries when you install the client program itself. In theory, you don't need to install an X server on this system, although in practice it's often simplest to do so, because dependencies between packages end up requiring you to install most of X. Technically, the X server itself is a single program that interfaces to the screen, mouse, keyboard, and so on. You may be able to omit this server, but it's often convenient to have it installed to test X-based programs locally. To make use of the X server program, you must have X client programs, either locally or on another computer.
Configuring an X Server to Accept X Client Access
An X server, like other types of server, must respond to connections initiated by clients. Most Linux distributions, however, are designed with the premise that the system will be used as a workstation or a server for other protocols, not as an X terminal. Therefore, to use a Linux system as an X server for anything but programs run locally, you must reconfigure the system to accept X connections from other systems. There are two main ways to do this: You can use xhost on the X server, or xauth on both the X server and the X client.
One way to grant access to an X server is to use the xhost program to allow specific remote computers to access your X display. In an xterm or similar command-prompt window, you can type a command resembling the following:
$ xhost +biggie.threeroomco.com
This command instructs the X server to accept connections from biggie.threeroomco.com for your display. Consequently, any user on that computer can connect to your X server to display windows, accept keyboard and mouse input, and so on. If you omit the hostname (typing just xhost + ), your X server will accept connections from any source.
Using xhost to open your X server to connections from other systems is simple and convenient, and may be acceptable in a low-security environment. It has its problems, though. Most importantly, it doesn't provide you with any way to restrict access to specific users of a remote system. If you want to run programs that are stored on a system that has many users, a shady character on that remote system might be able to display windows and pull other pranks , or even read your keystrokes, if you use xhost in this way to open your system. For this reason, another method exists: xauth .
The idea behind xauth is to provide a more-or-less transparent authentication system for X connections. This utility is used transparently by the X login protocols described shortly in "Using a Remote X Login Server," but you can use it manually when connecting in some other way, as well. Although it's a bit more tedious to set up xauth than to use xhost , it's far better from a security point of view, because your X server is much more selective about the clients from which it accepts connections.
The xauth system relies on a file called .Xauthority in each user's home directory. This file must be present on both the X server and the client system, although if it's not present on one system or another, the xauth tool will create it. Unlike most Linux configuration files, .Xauthority isn't a text-mode file; you manipulate it with the xauth tool. Using xauth , you can add, delete, or otherwise manipulate X connection keys. Certain methods of starting X, such as the GUI login servers described later, check .Xauthority and, if necessary, generate a new key for the server in this file. The X server then accepts connections from any client that possesses this key. (Because .Xauthority is stored in an individual user's home directory, this key generation occurs when a user logs in or the user starts X, whichever occurs later. Different users can have different .Xauthority files.) To allow an X client to use an X server, you must copy the key from the user's .Xauthority file on the server to the user's .Xauthority file on the client. Client applications automatically try to use the key when they try to use the X server. There are several different ways to transfer an authorization key. One such procedure is as follows (a quicker one appears after this):
If your systems both have SSH installed, you can use the following command, typed on the X server system, in place of this ten-step procedure:
# xauth list xserver :0 sed -e 's/^/add /' ssh xclient -x xauth
This procedure compresses the preceding ten steps into a single long command, using xauth in command line mode, sed to add the command add to the start of the output, and SSH's ability to run programs remotely to execute xauth on the X client system. You should note the following features of this command:
At this point, your X server should accept connections from the X client system, although you may still need to set an option on the client system to connect to the X server, as described in the next section, "Setting Client Options to Use an X Server." When the X client program makes the connection, it will check its local .Xauthority file for the key associated with the X server.
Because the xauth system relies on keys that are, ideally , known only to the X server and its authorized clients, it's more secure than is the xhost system, at least in some respects. If you use xauth , for instance, the server will only accept connections from specific users on a client that are authorized to use the display. The X server using this system is also less susceptible to IP spoofing attacks. On the downside, the keys used by xauth are sent in an unencrypted form, so if your local network isn't secure, or if you use this method over the Internet, these keys are vulnerable to interception, thus allowing anybody with access to the key to connect to your X server. Ultimately, if highly secure X connections are desirable, SSH is a superior connection method, as described in the upcoming section, "Tunneling X Connections Through SSH."
Setting Client Options to Use an X Server
Whether you use xhost or xauth to control access to the X server, you must configure the client to use the correct server. If you sit down at term.threeroomco.com and log in to biggie.threeroomco.com , and if that system tries to use wrongone.threeroomco.com as an X display, you won't be able to use the display. In fact, many Linux systems default to using their own X servers, even when you log in remotely.
When an X program starts, it checks the value of the DISPLAY environment variable to determine what X server to use. You can check the value of this variable yourself with the following command, which you type on the X client system:
$ echo $DISPLAY biggie.threeroomco.com:0.0
If the output ( biggie.threeroomco.com:0.0 in this example) is your X server, then you need do nothing. (The first display is usually numbered or 0.0 , and these two values are equivalent.) If the output shows your X client or some other system, or if there is no output (indicating the DISPLAY environment variable isn't set), then you must set it, thus:
$ export DISPLAY=term.threeroomco.com:0
You should use your own X server's hostname, of course. Subsequent attempts to run X programs will use the server you specify. In order for these attempts to succeed, though, you need to have configured the X server to accept connections from your X client by running xhost on the server or transferring an xauth record to the client, as described earlier.
Tunneling X Connections Through SSH
The preceding discussion relates to initiating an X connection using two distinct and independent protocols. First, you connect from the X server computer using a text-mode remote login client, such as a Telnet client. Second, you use this text-mode connection to initiate a link in the opposite direction for X clients. After performing basic setup tasks , you might type xclock in your Telnet program to start the xclock program, for instance. This configuration is adequate for many purposes, but it's not without its problems. For one thing, all the data transferred over the X connection is unencrypted, and so is vulnerable to interception by third parties. The fact that each side must run a server is also a drawback in some situations, because firewalls or Network Address Translation (NAT)/IP masquerading routers may require special configuration to allow this procedure to work. One possible solution to both of these problems is to use the Secure Shell (SSH) protocol, as described in Chapter 13, to both make the initial connection from the X server system to the X client system and to tunnel X data back from the X client to the X server.
Chapter 13 describes the basics of SSH configuration and use. There are specific configuration options you need to set for SSH tunneling of X protocols to work, though:
X forwarding by SSH works by having the SSH server run what is essentially a stand-in for a local X server. When properly configured, SSH sets the DISPLAY environment variable so that X programs send data to a particular local X server port (X server 10 by default, or TCP port 6010). The SSH server then connects to this port. Rather than display data locally, SSH encrypts the data and passes it to the SSH client. This client then makes requests of its own local X server (as determined by the SSH client machine's DISPLAY environment variable), and passes any results back to the SSH server, which delivers these results to the ultimate X client program. Essentially, the SSH server pretends to be an X server, and the SSH client pretends to be the originating X client program.
This procedure has certain advantages. For one thing, the fact that there need be only one network connection between the two computers simplifies network configuration. If you want to use an X server behind a firewall or NAT router, you may find it easier to do so if you use SSH than if you use Telnet or some other remote login protocol. Second, because SSH supports encryption, passing X data through SSH can greatly enhance security. Passwords and other sensitive data are not likely to be useable even if data packets are intercepted. The drawback derives from this encryption: Encryption requires computation, so using SSH to tunnel X connections consumes CPU time on both computers, thus slowing X displays. On CPUs of more than about 200MHz, these effects may be noticeable, but probably won't be objectionable when security is important. In some cases, the -C option to ssh , which enables compression, can improve matters by reducing bandwidth requirements. On the other hand, the compression adds further to the CPU load, which can make matters worse . You'll have to try it both ways and decide which is better on your hardware and network.
These instructions assume that you're using Linux or UNIX systems on both sides of the connection. If you're using Windows, MacOS, OS/2, or some other system as the X server, it's possible that the SSH client software won't support tunneling X connections. Even if it does support this option, you may need to determine how to activate this feature in a configuration dialog box. Consult your SSH client's documentation for more details.
A Summary of Remote-Login X Access
The preceding discussion illustrates several steps and options available to you in establishing an X connection by working off a text-mode login. There are so many possibilities, though, that it's easy to get lost. To summarize, then, a prototypical connection involves steps like the following:
Some of these steps, such as 2 and 4, may not be necessary depending upon the methods you use to connect and authenticate. Also, some X servers for Windows and MacOS automate some of these steps. For instance, some X servers include minimal automated Telnet or other remote-access tools that can log in using the appropriate protocol, and that then launch an xterm. Thus, once configured with your username and password, these X servers can start a connection at the click of a button, with the result being an xterm window. Consult your X server's documentation for details.
The procedures described here result in the remote system's programs being displayed on the X server computer's desktop, or sometimes in a separate window that the X server opens to host the client's desktop. (This option is particularly common on MacOS and Windows X servers.) Typically, the local system runs a window manager, although that's not always true, particularly of MacOS and Windows X servers. (X supports running the window manager from either computer.) Likewise, the desktop environment is normally run locally. If you want to maintain a minimal system locally and run the window manager and desktop environment on the remote system, you can adjust the local and remote X startup scripts to disable these features on the X server computer and enable them on the remote system. Another approach is to use a remote X login server, which typically shifts more of the burden for maintaining window managers and desktop environments to the remote system.