Remote X Windows

There are times when it's necessary to run a graphical program on a remote server.

 
The X Windows system allows programs to interact with your Mouse, Keyboard and Screen. Within an individual workstation, the program that you want to run connects to X Windows on your workstation. It does this using the information in the DISPLAY environment variable. When the remote program starts, it checks the DISPLAY environment contents and uses the information found to open a socket to your workstation. It then sends commands to draw on your screen and query your keyboard and mouse.

As you can imagine, it happens quite often that we want to connect a local workstation running X Windows to a remote computer which is not running X Windows. In this case, it is still possible to run X-enabled software if you want to.

There are three issues to consider:

  1. The value in the DISPLAY environment variable on the remote computer.
  2. The firewalls between the remote computer and your local workstation.
  3. Available bandwidth - X Windows needs a fast connection.

1. The DISPLAY environment variable

This is where information pointing to X Windows is stored. It usually looks something like this:

DISPLAY=localhost:0.0

  • The first part is the name of the host (or the IP address,) that is running X Windows. If the name is missing, it defaults to localhost.
  • The first digit is the X Windows instance number. Each instance of X Windows on a workstation will have a different number with the first instance having number zero. This is important because it is used to determine the Port number (or the socket name,) that X Windows is listening to.
  • The second digit, after the decimal point, is the screen number. If your workstation has multiple screens, you can connect to the one you want through this number. In most cases this number is set to zero to refer to the first screen (the user can usually move a program window from one screen to another manually.)

To get a program to connect from a remote computer to your local keyboard and screen, you will want to make sure the DISPLAY variable is set correctly on the remote computer.

One way to do this is manually: If there are no firewalls or other obstructions between the two computers, and if you absolutely trust everybody on the computer you are connecting to and everybody on the network you are using, you can tell your local X Windows to listen for incoming remote connections and simply set the remote DISPLAY variable to point to your local workstation. Again, this is very insecure! Do this only while on a trusted network and with computers that are used by people you trust:

First, if your remote computer has an IP of 192.168.1.23, tell your local workstation to allow connections from that IP using the xhost program:

$ xhost +192.168.1.23

The xhost program simply tells the X Windows software to allow any connections from 192.168.1.23 to access your keyboard and screen (which, if you think about it, is kind of scary... any connection that is spoofed to look like it comes from 192.168.1.23 will be able to watch your screen and log your keystrokes.)

Next, find out what instance of X Windows and which screen you are using on your local workstation:

$ echo $DISPLAY

In most cases you will see something like :0 but it's possible that you might get a number like :1234. Make a note of it. For this example, let's say it's :1234.

Finally, shell into your remote computer and set your DISPLAY environment variable. If your local workstation is 192.168.1.34, you would type:

$ export DISPLAY=192.168.1.34:1234.0

At this point you can run some X software on the remote computer. Typing

$ xterm

should display a small X terminal on your local workstation. If you are on a fast network this will happen instantly. If you are on a slow network it will take some time - possibly lots of time as X Windows uses lots of bandwidth to send mouse movement information, bitmaps (lots of bitmaps,) and lots of related information. See #3 below for more information about low bandwidth X connections.

If you don't see anything it's probably because your firewall is blocking access to your X Windows instance - which is probably a good thing for security purposes. However, if you absolutely trust your local network and want to make this work - you can open a port on your firewall. The port to open is 6000 plus the instance number you are currently using. Again, the instance number is often zero so you would normally open TCP Port 6000 on your firewall. However, if you are using instance 1234, as in our example, you would need to open TCP port 7234 instead.

2. Using SSH

Another solution to the problem of routers and firewalls between the two computers is to use SSH. These days almost everybody is using it anyway - so we can take advantage of the -X option that automatically handles forwarding of X Windows connections.

In general this is supposed to work fine without any further effort. In theory you just add -X when connecting to the remote host and the SSH program will create a tunnel from the remote host back to the local workstation.

In practice the results are mixed. After installing Cygwin-X on my notebook computer there's no problem shelling into workstations that are running X Windows. The -X (and -Y) options of SSH work as expected. The same is true for connections made with Putty (after setting the X11 Forwarding options in the Putty connection configuration.) Unfortunately, connections attempted with remote computers that do not have X Windows installed - never seem to work as expected!

The easiest way to find out what's going on is to use the -v option to find out what's going on:

$ ssh -X -v 192.168.1.23

This produces a rather long list of messages - SSH reports everything that happens in the process leading up to the opening of the shell. Towards the end of the sequence I found a message indicating that the xauth program was missing on the remote workstation:

debug1: Requesting X11 forwarding with authentication spoofing.
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Remote: No xauth program; cannot forward with spoofing.

This makes sense because the remote workstation is not running X Windows. On a Fedora-derived distribution of Linux (ie: Fedora, Redhat, CentOS and others,) you can find out how to get the xauth program by checking a workstation that has X Windows installed:

$ which xauth
/usr/bin/xauth

$ yum whatprovides /usr/bin/xauth
xorg-x11-xauth.i386 : X.Org X11 X authority utilities

So the solution to the problem is to install the xorg-x11-xauth package on the remote computer:

$ ssh 192.168.1.23
$ sudo yum install xorg-x11-xauth

Then, finally, it becomes possible to use the -X (or -Y) option with SSH and enjoy the expected results:

$ ssh -X 192.168.1.23
$ echo $DISPLAY
localhost:10.0
$ xterm

(xterm is a convenient program to use for testing the connection. If you don't already have it installed you can install it through the package of the same name: xterm.)

3. Slow Connections

Once you get X Windows working from your remote server - you will find that it demands quite a bit of bandwidth. So much, in fact, that it's not really usable over a slow connection.

Fortunately, there are some options. Google FreeNX or NX from nomachine.com. These are excellent programs that cache bitmaps and compress data to the point where it's possible to run graphical programs over dialup lines.

Notes

DNS counts. Even if you use IP numbers and not host names, you can run into trouble if host names don't resolve properly. Make sure you can execute a getent hosts localhost successfully on the remote server. Also make sure you can similarly lookup any other names you are using.

See the documentation for the xhost program for more information about allowing external hosts to connect to your workstation. See the ssh documentation for the -X and -Y options for more information about the security issues related to remote X11 connections.