X Forwarding

Now that you’ve seen general TCP port forwarding, we move to a new topic: forwarding of X protocol connections. X is a popular window system for Unix workstations, and one of its best features is its transparency. Using X, you can run remote X applications that open their windows on your local display (and vice versa, running local applications on remote displays). Unfortunately, the inter-machine communication is insecure and wide open to snoopers. But there’s good news: SSH X forwarding makes the communication secure by tunneling the X protocol.

X forwarding also addresses some firewall-related difficulties. Suppose you’re a system administrator with a set of exposed production machines on the other side of a firewall from you. You log into one of these machines using SSH, and want to run a graphical performance-monitoring tool, such as Solaris’s perfmon, that uses the X Window System. You can’t, though, because to do that, the external machine needs to make a TCP connection back to the internal machine you started on, and the firewall blocks it (as it should, since X is quite insecure). X forwarding solves this problem, permitting X protocol connections to pass through the firewall, securely tunneled via SSH.

Our discussion begins with a brief overview, then explains the details of X forwarding. In addition to explaining how to use X forwarding, we also expose the internals of X authentication and how it interacts with SSH, as well as other technical topics.

9.4.1 The X Window System

The X Window System, or X, is the most widely used graphical display system for Unix machines. Like SSH, X has clients and servers. X clients are windowing application programs, such as terminal emulators, paint programs, graphical clocks, and so forth. An X server is the underlying display engine that processes requests from X clients, communicating via a network protocol called the X protocol. A machine typically runs a single X server but possibly many X clients.

Most important to our discussion, X supports sophisticated window management over a network. X clients can open windows not only on their local machine, but also on other computers on the network, whether they are down the hall or across the globe. To accomplish this, an X client makes a network connection to a remote X

server and carries on a conversation, using the X protocol to draw on the remote screen, receive remote keyboard events, learn the remote mouse location, and so on. This obviously requires some type of security, which we discuss soon.

A central concept of X is the display, an abstraction for the screen managed by an X server. When an X client is invoked, it needs to know which display to use. Displays are named by strings of the form HOST:n.v, where:

  • HOST is the name of the machine running the X server controlling the display.

  • n is the display number, an integer, usually 0. X allows for multiple displays controlled by a single server; additional displays are numbered 1, 2, and so on.

  • v is the visual number, another integer. A visual is a virtual display. X supports multiple virtual displays on a single, physical display. If there’s only one virtual display (which is the most common scenario), you omit the “.v”, and the default is visual 0.

For example, on the machine server.example.com, display 0, visual 1 is represented by the display string “server.example.com:0.1”.

Under Unix, most X client programs let you specify the display string in two ways: the -d or -display command-line option, or the environment variable DISPLAY. For example, to run the X client program xterm on the only X display of the workstation anacreon, use the command-line option:

    $ xterm -d anacreon:0 &

or the environment variable:

    $ setenv DISPLAY anacreon:0
    $ xterm &

X is a large, deep software product whose documentation fills a dozen O’Reilly books. We’ve barely scratched the surface with our explanation, but you’ve now seen enough to understand X forwarding.

9.4.2 How X Forwarding Works

Although X clients can communicate with remote X servers, this communication isn’t secure. All interactions between the X client and server, such as keystrokes and displayed text, can be easily monitored by network snooping because the connection isn’t encrypted. In addition, most X environments use primitive authentication methods for connecting to a remote display. A knowledgeable attacker can get a connection to your display, monitor your keystrokes, and control other programs you’re running.

Once again, SSH comes to the rescue. An X protocol connection can be routed through an SSH connection to provide security and stronger authentication. This feature is called X forwarding.

X forwarding works in the following way, as illustrated in Figure 9-10. An SSH client requests X forwarding when it connects to an SSH server (assuming X forwarding is enabled in the client). If the server allows X forwarding for this connection, your login proceeds normally, but the server takes some special steps behind the scenes. In addition to handling your terminal session, it sets itself up as a proxy X server running on the remote machine and sets the DISPLAY environment variable in your remote shell to point to the proxy X display:

    syrinx$ ssh sys1
    Last login: Sat Nov 13 01:10:37 1999 from blackberry
    Sun Microsystems Inc.   SunOS 5.6       Generic August 1997
    You have new mail.
    sys1$ echo $DISPLAY
    sys1:10.0
    sys1$ xeyes
    The "xeyes" X client appears on the screen

The DISPLAY value appears to refer to X display #10 on sys1, but there’s no such display. (In fact, there might be no true displays on sys1 at all!) Instead, the DISPLAY value points to the X proxy established by the SSH server, i.e., the SSH server is masquerading as an X server. If you now run an X client program, it connects to the proxy. The proxy behaves just like a “real” X server, and in turn instructs the SSH client to behave as a proxy X client, connecting to the X server on your local machine. The SSH client and server then cooperate to pass X protocol information back and forth over the SSH pipe between the two X sessions, and the X client program appears on your screen just as if it had connected directly to your display. That’s the general idea of X forwarding.

X forwarding

Figure 9-10. X forwarding

X forwarding can even solve the firewall problem mentioned earlier, as long as the firewall permits SSH connections to pass through. If a firewall sits between your local and remote machines, and you run an X client on the remote machine, X forwarding tunnels the X connection through the firewall’s SSH port to the local machine. Therefore, the X client’s windows can open on your local display. If X forwarding were not present, the firewall would block the connection.

Some aspects of X forwarding probably sound familiar from our earlier explanation of port forwarding. In fact, X forwarding is just a special case of port forwarding for which SSH has special support.

9.4.3 Enabling X Forwarding

X forwarding is on by default. If you need to enable or disable X forwarding for your clients, here’s how to do it. Unlike general port forwarding, which requires you to fiddle with TCP port numbers, X forwarding has only an on/off switch. In your SSH client configuration file, use the keyword ForwardX11 with a value of yes (the default, to enable) or no (to disable):

    ForwardX11 yes

On the command line, you may also use -x to disable X forwarding:

    $ ssh -x server.example.com

OpenSSH and Tectia enable X forwarding with the following options:

    # OpenSSH
    $ ssh -X server.example.com

    # Tectia
    $ ssh +x server.example.com

9.4.4 Configuring X Forwarding

The behavior of X forwarding can be modified through compile-time configuration, serverwide configuration, and per-account configuration.

9.4.4.1 Compile-time configuration

Tectia can be compiled with or without X support. The compile-time flags --with-x and --without-x make this determination:

    $ configure ... --without-x ...

You can also enable or disable all X forwarding by default with --enable-X11-forwarding or --disable-X11-forwarding:

    # Tectia
    $ configure ... --enable-X11-forwarding ...

Remember, enable/disable flags simply set the default behavior. You can override these defaults with serverwide and per-account configuration.

9.4.4.2 Serverwide configuration

The serverwide configuration keyword X11Forwarding [137] enables or disables X forwarding in the SSH server. By default, it is enabled.

    X11Forwarding no

The X11DisplayOffset keyword lets you reserve some X11 display numbers so that sshd can’t use them. This keyword specifies the lowest display number SSH may use, preventing sshd from clashing with real X servers on the lower-numbered displays. For example, if you normally run actual X servers on displays 0 and 1, set:

    #  OpenSSH
    X11DisplayOffset 2

The XAuthLocation keyword specifies the path to the xauth program, which manipulates authorization records for X. We describe this keyword later, after we discuss xauth. [9.4.6.4]

    # OpenSSH
    XAuthLocation /usr/local/bin/xauth

9.4.4.3 Per-account configuration

In your authorization file for public keys, you may disallow X forwarding for incoming SSH connections that use a particular key for authentication. [8.2.7] In OpenSSH and Tectia this is done with the option no-X11-forwarding:

    # OpenSSH
    no-x11-forwarding ...key...

    # Tectia
    Key mykey.pub
    Options no-x11-forwarding

9.4.5 X Authentication

We’ve mentioned in passing that X performs its own authentication when X clients connect to X servers. Now we’re going to dive into technical detail on the inner workings of X authentication, why it’s insecure, and how SSH X forwarding builds on it to create a secure solution.

In most cases, X forwarding simply works, and you don’t have to think about it. The following material is to aid your understanding and satisfy any intense cravings for tech talk (both yours and ours).

9.4.5.1 How X authentication works

When an X client requests a connection to an X server, the server authenticates the client. That is, the X server determines the client’s identity to decide whether to allow a connection to the server’s display. The current release of the X Window System (X11R6) provides two categories of authentication: host-based and key-based:

Host-based X authentication

The simpler method. Using the program xhost, you indicate a list of hosts that may connect to your X display. Notice that connections are authenticated only by hostname, not by username. That is, any user on a listed host may connect to your display.

Key-based X authentication

Uses the xauth program to maintain a list of X authentication keys, or display keys, for X clients. Keys are kept in a file, usually ~/.Xauthority, along with other data associated with the various displays the client wants to access. When an X client connects to a server requiring authentication, the client supplies the appropriate credentials for that display from the xauth data. If authentication is successful, the X client can then connect to the display managed by the X server.

Display keys are obtained from the X server in various ways depending on the environment. For example, if you start the server directly on the console of a machine using xinit or startx, these programs invoke an X server and insert a copy of the server’s key directly into your xauth data. Alternatively, if you connect to a remote machine that runs the X Display Manager (XDM), the key is sent to your remote account when establishing your XDM session.

9.4.5.2 xauth and the SSH rc files

SSH has startup files that can be set to execute on the server side when a client logs in. These are the systemwide /etc/sshrc and the per-account ~/.ssh/rc files. These can be shell scripts or any kind of executable program.

An important thing to note is that sshd runs xauth only to add the proxy display key if it doesn’t run an rc program. If it does run an rc program, it feeds the key type and data to the program on a single line to its standard input, and it is up to the rc program to store the display key. This feature provides a way to customize handling the display key, in case just running xauth isn’t the right thing to do in your situation.

9.4.5.3 Trusted X forwarding

The X Windows protocol was not designed with much security in mind. Usually, once an application has access to an X display, it pretty much has the run of it. A malicious X client can easily read all keyboard input, see all screen contents, add or modify keystrokes, and so on. This is why X forwarding is risky and should generally be turned on only when you need it, and only for hosts you trust.

There is a security extension to the X Windows protocol that allows at least some further granularity, partitioning X clients into “trusted” and “untrusted” groups. Programs like the X Window Manager must be trusted, since they have to manipulate the windows of other applications and perform other global operations on the display. Other programs may be left untrusted, though, with more limited access to the display and less opportunity for mischief.

Both OpenSSH and Tectia support this trust distinction in X forwarding. OpenSSH has the ForwardX11Trusted client option and Tectia has TrustX11Applications. Set to yes or no, these keywords control whether remote X clients accessing the local display via SSH X forwarding will be considered trusted or untrusted by the X server.

    # OpenSSH
    ForwardX11Trusted yes

    # Tectia
    TrustX11Applications yes

The default setting is no, meaning “untrusted.” You can override this setting per connection with ssh -Y (OpenSSH) or ssh +X (Tectia):

    # OpenSSH
    $ ssh -Y ...              Equivalent to ssh -X -o ForwardX11Trusted=yes

    # Tectia
    $ ssh +X ...              Equivalent to ssh +x -o TrustX11Applications=yes

Technically, for trusted forwarding, the client uses the existing xauth key to access the display: that is, it inherits whatever trust is already in effect. For untrusted forwarding it generates a new, specifically untrusted key using the command xauth generated ... untrusted, and uses the new key with forwarded X connections. In either case, the local key never goes to the remote host; that is always a throwaway key used only for authenticating the connection within SSH.

9.4.5.4 Problems with X authentication

If you’ve used X, the authentication was probably transparent and seemed to work fine. Behind the scenes, however, the mechanism is insecure. Here are the major problems:

xhost is insecure

Once you give permission for a remote host to connect to your display, any user on that host can connect. As with the r-commands, this authentication method depends on the network address of the connecting host, which can be easy for an attacker to usurp.

Key transfer may be manual and insecure

Some remote-login protocols, such as telnet, don’t assist with X authentication. If your display keys aren’t available on a remote machine, you have to transfer them yourself, either manually or by automating the transfer, perhaps in your login script. This isn’t only a nuisance but also insecure, since you’re sending the key in plaintext over the network.

The most common key-based method, MIT-MAGIC-COOKIE-1, is insecure

Although it uses a random string of bits, or cookie, as the xauth display key, this key is transmitted in plaintext at the beginning of every connection, where it can be intercepted and read.

The remote host might not support your chosen X authentication method

X11R6 supports other, more secure authentication methods. SUN-DES-1 employs Sun’s secure RPC system, XDM-AUTHORIZATION-1 uses DES, and MIT-KERBEROS-5 involves Kerberos user-to-user authentication.[138] Unfortunately, these methods are often not available in particular instances of the X software. Sometimes they aren’t compiled into X installations due to cryptographic export restrictions; other times, the X version is too old to support the more secure methods.

If the remote host is insecure, your display key can be compromised

In the best scenario, where the X server supports strong authentication and your key can be copied securely to the remote machine, you still have to store your sensitive display key there. If that machine is untrustworthy, your key can be at risk. (SSH doesn’t have this problem, since only your public key is stored on the SSH server machine.)

9.4.5.5 SSH and authentication spoofing

Through X forwarding, SSH provides transparent, secure authentication and key transfer for X sessions. This is done by a technique called authentication spoofing, as depicted in Figure 9-11. Authentication spoofing involves a fake display key, which we call the proxy key, that authenticates to the SSH X proxy server on the remote side. When relaying X traffic containing a key, SSH cleverly substitutes the real display key. Here’s how it works.

Authentication of forwarded X connections

Figure 9-11. Authentication of forwarded X connections

The players begin in the following positions. You are logged into a local machine with a local display. The local machine runs an X server and SSH clients. On the other side of the network connection, an SSH server is running on a remote machine, where you invoke X clients. The goal is for the remote X clients to appear on your local display by way of SSH.

First, you run a local SSH client, asking it to set up X forwarding. The SSH client requests X forwarding from the remote SSH server, and it also reads your local display key from your .Xauthority file.

Next, the SSH client generates a proxy key. This is a string of random data of the same length as your local display key. The SSH client then sends the proxy key and its key type (e.g., MIT-MAGIC-COOKIE-1) to the remote machine, and the SSH server runs the xauth program on your behalf to associate the proxy key with your local display. The stage is now set for X forwarding.

When you start a remote X client, your local SSH client connects to your local X display. It then watches for the first X protocol message sent over the forwarded connection and treats it specially. Specifically, the SSH client parses the message, finds the X authentication key inside it, and compares it to the proxy key. If the keys don’t match, the SSH client rejects and closes the connection. Otherwise, if the keys match, the SSH client substitutes the real display key in place of the proxy key and relays the modified message to your local X server. The X server, blissfully unaware that a key switch has taken place, reads the display key and proceeds normally with X authentication. The forwarded X connection is now established.

X forwarding with authentication spoofing solves all but one of the X authentication problems we raised earlier:

xhost

X forwarding doesn’t use xhost. (By the way, make sure to disable all xhost permissions when using X forwarding, or you’ll undermine the X security provided by SSH.)

Key transfer

SSH transfers the X display key automatically and runs xauth on your behalf to install it on the remote side. The transfer is secure since the key travels over the encrypted SSH connection.

MIT-MAGIC-COOKIE-1 insecurity

The key transmitted at the beginning of every X session is now encrypted, along with the rest of the X traffic, inside the SSH session. This greatly increases the operational security of this common X authentication scheme.

Untrustworthy remote hosts

With authentication spoofing, only the proxy key, not the true display key, is sent to the remote host. The proxy key is good only for connecting to your display through SSH, not for connecting to your display directly. As soon as your SSH session ends, the proxy key becomes useless. Since SSH sessions come and go, but some people leave their X sessions up (with the same key) for days, X forwarding can be a great improvement.

9.4.5.6 Improving authentication spoofing

The remaining problem with X forwarding is the possibility of unsupported X authentication mechanisms. The local side can use a more sophisticated authentication method that a remote host might not support.

In theory, SSH X forwarding can solve this problem by always installing a proxy key of type MIT-MAGIC-COOKIE-1, no matter what local authentication method is actually in use. After the SSH client has checked the X client’s key against the proxy key for a match, its client could then generate and substitute whatever local authenticator is required using the true authentication type and key.

Unfortunately, SSH implementations don’t go this far. The server compares keys literally as bit strings, and the SSH client substitutes keys verbatim, regardless of the key types. As a result, if you use a stronger X authentication method such as XDM-AUTHORIZATION-1, sshd blindly compares an encrypted authenticator with the proxy key, rightly determines that they don’t match, and invalidly rejects the connection. The failure is silent and mysterious; we wish the software would detect the presence of an unsupported mode and issue a warning when setting up the connection.

If SSH knew the details of all X authentication modes, it could check the proxy authenticators on one side and generate correct ones for the X server on the other. However, this can be a significant development effort, though perhaps one could link SSH against the X11 libraries to obtain the necessary algorithms. SSH would also have to deal with differing key data lengths, constructing a new X message to hold the proxy key instead of copying it to an existing message.

It would also be useful if X forwarding could be used without authentication spoofing. Then you could arrange your own security for the connection by, say, using xhost to allow any connection from your local machine (and hence the SSH X proxy), while still applying key-based authentication to X connections originating from elsewhere. You can accomplish this with general port forwarding, as discussed in the next section, but direct support is more convenient.

9.4.5.7 Nonstandard X clients

X clients generally do X xauth-style authentication by virtue of having been linked against Xlib, the common X programming library. Occasionally, though, you run across particular X client programs that don’t use Xlib and simply ignore authentication issues. Since you can’t turn off SSH X authentication spoofing, you can’t use such programs across SSH X forwarding; you get this message:

    X11 connection requests different authentication protocol: 'MIT-MAGIC-COOKIE-1' vs.
    ''

You can, however, use a general port forwarding instead. For example:

    foo% ssh -R6010:localhost:6000 bar
    bar% setenv DISPLAY bar:10

Note that this bypasses the discipline imposed by X forwarding, of requiring xauth authentication on forwarded X connections. If your real X server is using xhost for access control, this port forwarding allows anyone on host foo to connect to your X server. Use this sort of thing with caution.

9.4.6 Further Issues

As we’ve said, X forwarding usually works fine without any special effort on your part. In some special situations, however, you might need to take some extra steps.

9.4.6.1 X server configuration

In order for X forwarding to work, your X server must accept the proxy X connections from your SSH client. This is sometimes not set up to begin with, because normal use doesn’t require it. For example, if you’re using an X server on a PC to access a remote Unix machine via XDM, you might never run local X clients at all, and they may not be allowed by default. You can use xhost +localhost to allow all connections from your PC, while still applying key-based authentication to connections from other sources. This allows SSH-forwarded (and authenticated) connections to be accepted.

9.4.6.2 Setting your DISPLAY environment variable

SSH sets the DISPLAY variable automatically only if X forwarding is in effect. If you don’t use X forwarding but want to use X on a remote machine you logged into via SSH, remember that you have to set the DISPLAY variable yourself. You should really do this only when both machines are on the same, trusted network, as the X protocol by itself is quite insecure.

Be careful not to set DISPLAY unintentionally! It is common for people to set the DISPLAY variable in a login command file or by other means. If you’re not careful, this can make your X connections insecure without your noticing! If you use SSH to tunnel through a firewall that blocks normal X connections, then of course you’ll notice because your X clients won’t work. But if normal X connections are possible but undesirable, and X forwarding isn’t in effect, your X programs will work but (silently) not be secured! This is a good reason to block X traffic at the firewall if it presents a security risk or to configure your X server to accept connections only from the local host (the source of the SSH-forwarded X connections). If that’s not feasible, you may want to put something like this in your login script:

    #!/bin/csh
    if ($?DISPLAY) then
       set display_host   = `expr "$DISPLAY" : '(.*):'`
       set display_number = `expr "$DISPLAY" : '.*:([^.]*)'`
       set my_host = `hostname`
       set result  = `expr '(' "$display_host" = "$my_host" ')' '&' '(' 
                     "$display_number" '>' "0" ')'`
       if ($result == 0) then
          echo "WARNING: X display $DISPLAY does not appear to be protected by SSH!"
          echo "unsetting DISPLAY variable just to be safe"
          unsetenv DISPLAY
       endif
    endif

9.4.6.3 Shared accounts

If you share a single account among multiple people, you may have some trouble with X forwarding. For example, it is common for a group of sysadmins to share use of the root account. For each person to retain their own environment when using the root account, they may set their USER, LOGNAME, and HOME environment variables explicitly to reflect their personal accounts rather than the root account. If you use SSH to log into the root account with X forwarding turned on, though, it adds the proxy xauth key to root’s .Xauthority file before the shell reads your login script and resets these environment variables. The result is that once you’re logged in and try to use X, it fails: the X client looks in your .Xauthority file (because of the setting of your HOME variable), but the key isn’t there.

You can deal with this problem by setting the XAUTHORITY variable to point to root’s .Xauthority file, or by using code like the following in your login script to copy the needed key into your personal one:

    if (($uid == 0) && ($?SSH_CLIENT) && ($?DISPLAY)) then
    # If I do ssh -l root with X forwarding, the X proxy server's xauth key
    # gets added to root's xauth db, not mine.  See if there's an entry for my
    # display in root's xauth db...
      set key = `bash -c "xauth -i -f /.Xauthority list $DISPLAY 2> /dev/null"`
    # ... and if so, copy it into mine.
      if ($? == 0) then
        xauth -bi add $key
        chown res ~res/.Xauthority >& /dev/null
      endif
    endif

9.4.6.4 Location of the xauth program

Remember that sshd runs the xauth program on your behalf, to add the proxy key to your .Xauthority file on the remote side. The location of the xauth program is discovered when you configure the SSH package and compile into the sshd executable. If xauth is subsequently moved, X forwarding won’t work (ssh -v reveals this explicitly). For OpenSSH, the system administrator on the server side can use the serverwide configuration keyword XAuthLocation to set the path to the xauth program without having to recompile sshd1:

    # OpenSSH
    XAuthLocation /usr/local/bin/xauth

XAuthLocation can also appear in the OpenSSH client configuration file; the client uses xauth to get the local X display key.

9.4.6.5 X forwarding and the GatewayPorts feature

The GatewayPorts (-g) feature discussed earlier applies only to general port forwarding, not to X forwarding. The X proxies in OpenSSH and Tectia always listen on all network interfaces and accept connections from anywhere, though those connections are then subject to X authentication as described earlier. To restrict X client source addresses, use TCP-wrappers, which we discuss in the next section.



[137] And its Tectia synonyms ForwardX11 and AllowX11Forwarding.

[138] See the X11R6 Xsecurity(1) manpage for details on these methods. Also, remember that this is authentication only, not encryption. The contents of your X connection remain unencrypted and open to snooping or modification on the network.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.12.240