SSH X-Forwarding (a more secure alternative to VNC)


To totally unlock this section you need to Log-in


Login

X is a popular window system for Unix/Linux workstations (similar to explorer.exe for Windows systems), and one of its best features is its transparency. A great feature about using X is that 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 normal X inter-machine communication is insecure (as eve normal VNC connections if kept alive for too long) and wide open to snoopers. But there's a feature about OpenSSH package that address this strong limitation in terms of security: SSH X forwarding makes the communication secure by tunneling the X protocol over SSH (Secure Shell).

SSH 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 (the secure way), and want to run an graphical performance-monitoring tool, such as perfmon, that uses the X Window System. Without an SSH tunnel established (as long as the only connection allowed is SSH) you will not be able to do that, because to do that, the external machine needs to make a normal and unencrypted 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, allowing X protocol connections to pass through the firewall, securely tunneled via SSH.

Enabling X Forwarding

X forwarding is on by default in SSH1 and SSH2, but it is off in OpenSSH.

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 (bit switch). This configuration will be only specified on SSH client configuration file, use the keyword ForwardX11 with a value yes (the default, to enable) or no (to disable):

# SSH1, SSH2, OpenSSH
ForwardX11 yes

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

# SSH1, SSH2, OpenSSH
$ ssh -x server.example.com

SSH2 and OpenSSH enables X forwarding with the following options:

# SSH2 only
$ ssh2 +x server.example.com

# OpenSSH only
$ ssh -X server.example.com

Server Side

For X11 forwarding (or SSH X-Forwarding), the remote server host doesn't need to have a full X11 system installed. However, at least the server host needs to have the xauth package installed.

xauth is a utility that maintains Xauthority configurations used by server and client for authentication process of X11 sessions. To install xauth package execute the following apt-get command (for Debian systems) on a remote server (that will be the server from which we will require programs remotely):

For Debian etch (4.0) and earlier, and Ubuntu 7.04 and earlier:

$ sudo apt-get install xbase-clients

For Debian lenny (5.0) and higher, and Ubuntu 7.10 and higher:

$ sudo apt-get install xauth xfonts-base

On RHEL and CentOS system you should install the following packages to properly enable your server to X-Forwarding:

yum install -y xorg-x11-server-Xorg xorg-x11-xauth xorg-x11-apps

Then, enable X11 forwarding in sshd (SSH Daemon) configuration file and finally restart sshd service as follows:

$ sudo vi /etc/ssh/sshd_config
...
X11Forwarding yes
...
$ sudo /etc/init.d/sshd restart

The above setup enables X11 forwarding system wide on the server host. You should see the following output if it’s working correctly:

$ echo $DISPLAY
localhost:10.0

In OpenSSH and SSH2 you could find also the X11DisplayOffset directive: this keyword lets you reserve some X11 display numbers so 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 and 1, set:

# SSH1, OpenSSH
X11DisplayOffset 2

Windows (PuTTY and Xming)

Almost every medium and advanced Linux's user knows that distributions like Fedora or Ubuntu use X11. Desktops like GNOME and KDE are displayed by X11. Programs that you open on a Linux desktop are displayed by X11, but usually, when we want to connect and manage our Linux computer remotely we will rely on SSH (Secure Shell), that however doesn't give us any fancy graphical interface but it will give us only a simple terminal as CLI (Command Line Interface).

To be able to use X-Forwarding from Windows to a remote Linux server we will need forst a terminal client. For Windows, PuTTY is a perfect and free SSH client that allow us to connect to a remote Linux computer and use the command line. PuTTY can also be used to forward secure data over SSH to other programs.

This is called tunneling. We’re going to be taking advantage of PuTTY’s ability to tunnel X11 data.

First we will need to download putty.exe to your Windows desktop from the following address: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html. You will notice soon that PuTTY is a standalone program: there is no installer. Once downloaded, put it somewhere you can easily find it, and make a desktop shortcut to it if you like.

When you connect to your remote Linux computer, you will need to set several connection settings to make everything work correctly. PuTTY lets you save these settings in a session so you can reuse them the next time you connect. We’ll make a session that allows PuTTY to forward your Linux computer’s X11 graphical interface over SSH.

  • Open PuTTY on your Windows desktop.
  • PuTTY will open and display the Session panel.
  • In the Host Name field, type the hostname or IP address of your Linux computer.
  • In the field underneath the Saved Sessions label, type a name for your saved session.

SSH X-Forwarding (a more secure alternative to VNC)

Under the Connection category, expand SSH and choose X11. Click the Enable X11 Forwarding checkbox.

SSH X-Forwarding (a more secure alternative to VNC)

Go back to the Session category and click Save to save your session connection settings.

Xming

Xming is a free X Window server for the Windows desktop. With Xming, you can display graphical applications from your remote Linux computer on your Windows desktop. To take advantage of Xming’s capabilities, we’ll need to first install it.

  1. Download the Xming installer to your Windows desktop from the following address: http://www.straightrunning.com/XmingNotes/
  2. Look for the Xming link under Public Domain Releases.
  3. Run the Xming setup program on your Windows desktop. When selecting components to install, make sure the following are selected: XLaunch Wizard (selected by default), Normal PuTTY Link SSH Client (selected by default).

Running Xming

The developers of Xming have provided a simple utility called Xlaunch that allows you to configure Xming easily, and also save your configuration for future use. To run Xming, open XLaunch and select the configuration you wish to use. We’ll use the configuration that follows.

Open XLaunch from the program menu, then select Multiple Windows and click Next. This tells Xming to open each remote Linux application in a new window.

SSH X-Forwarding (a more secure alternative to VNC)

Select Start No Client and click Next. This will instruct Xming to launch and wait for commands from another program (like PuTTY).

SSH X-Forwarding (a more secure alternative to VNC)

Optionally, make sure that Clipboard is selected and click Next. This tells Xming to enable your remote Linux applications to share a unified clipboard.

SSH X-Forwarding (a more secure alternative to VNC)

Click the Finish button to launch Xming.

SSH X-Forwarding (a more secure alternative to VNC)

Launching Graphical Applications on Windows from Linux

Now that Xming is running, you can open your PuTTY session on Windows and launch a graphical application. The example Linux computer is running the Gnome desktop. So now, to test the X11 Forwarding we are going to launch remotely the Linux computer’s calculator on Windows desktop through the SSH connection.

Now open PuTTY on Windows and then double-click on the saved session you created earlier. PuTTY will create an SSH connection to the remote Linux computer.

SSH X-Forwarding (a more secure alternative to VNC)

Login to your Linux computer as usual (with the Linux credentials) and then type gcalctool (Gnome) at the command prompt and hit the Enter button.

SSH X-Forwarding (a more secure alternative to VNC)

If everything worked correctly, your remote Linux computer’s calculator should appear on your desktop.

SSH X-Forwarding (a more secure alternative to VNC)

MobaXterm

MobaXterm is another free Xserver and tabbed SSH client (not only) for Windows Operating Systems which allows you to run native Linux applications like they are running on your Windows.

The general procedure to enable MobaXterm to work with X11 Forwarding enabled system is the following:

  • Open MobaXterm
  • Enable the X Server Button on the top toolbar (the great red X icon will turn green if enabled)
  • Go to Sessions tab on the left sidebar
  • Right-Click Saved sessions and create a new session
  • Click the SSH tab and fill in: Host and username
  • Make sure X11-Forwarding is Checked and click OK

SSH X-Forwarding (a more secure alternative to VNC)

Now running xclock will show you, on Windows system, the xclock utility of the Linux system:

SSH X-Forwarding (a more secure alternative to VNC)

If you are getting this error:

D-Bus library appears to be incorrectly set up; failed to read machine uuid: Failed to open “/var/lib/dbus/machine-id”

Just run:

dbus-uuidgen > /var/lib/dbus/machine-id

Remember to enable X11 forwarding to allow the use of graphical applications from the host machine:

  • Ensure that X11 forwarding is enabled for a particular session by right clicking on the session and select Edit Session. In the session settings window, select Advanced SSH settings and ensure that the X11-Forwarding checkbox is checked.
  • Ensure that the red icon for the X server in the top right corner of the main window is green. If it isn't green that means that you do not currently have an X server running. To start, click on the red "X" icon.

The following screen shows a connected remote host with SSH from inside MobaXterm (internal SSH client):

SSH X-Forwarding (a more secure alternative to VNC)

While the following screen shows how to enable X11 Forwarding on MobaXterm (client) on Windows:

SSH X-Forwarding (a more secure alternative to VNC)

How works X11 Forwarding (SSH)?

After these quick tutorials, let'see in more depth how all of this works. Let's take two systems, a machine named home that has a keyboard, mouse, display, and is running an X server (so with GUI enabled).

Then take another networked system (in this case Linux based) called remote, which doesn't have and need to have an X server running, connect with SSH to it and finally run a program like firefox or chrome which will probably pops in a window on the home screen.

SSH X-Forwarding (a more secure alternative to VNC)

X, on Linux systems, has a client-server infrastructure, so when can distinguish the following two elements:

  • X client: a process (like firefox or xemacs) which uses the X client API to display things and receive mouse/keyboard events.
  • X server: a process (usually just "X") which X clients connect to. At times (as we'll see below) other processes can act as X servers.

Whenever an X client starts up, it reads the local $DISPLAY environment variable, whose value looks like: [hostname]:display_number[.screen_number]. The X client immediately opens a connection to that X server. If it can't, it fails. In the following example we first open xcalc program on localhost (:0), then we change the $DISPLAY variable to falseHost:99 (display number as 99) and then we retry opening xcalc, but since there is no falseHost host on the same network we are connected the opening process of xcalc will fail:

user@home: echo $DISPLAY 
:0 # hostname is "localhost" by default
user@home: xcalc # pops up a calculator on my screen
user@home: DISPLAY="falseHost:99"
user@home: xcalc
Error: Can't open display: falseHost:99

Now let's see what happens when we connect with SSH to another, existing, machine:

user@home: ps aux | grep X     # X server running @home
root ... /usr/bin/X :0 ...
user@home: ssh -X user@remote    # -X enables X-forwarding
user@remote: ps aux | grep X     # No X server here
user@remote: echo $DISPLAY
:11.0
user@remote: xcalc    # Pops up on screen @home

Wait a minute, the $DISPLAY variable is pointing to the localhost ("remote"). Natural questions to ask at this point:

  • There is no X server on @remote, so why didn't xcalc just fail on startup?
  • Why was the display number "11"?
  • How did xcalc show something @home?

The answer has to do with the ssh-daemon running @remote:

user@remote: ps aux | grep user
root ... sshd:user@pts/11

After we have run ssh -X user@remote the sshd daemon on @remote has created an "X emulator" running at @remote that was setup just for the incoming @home ssh session, and the sshd daemon, enabled with X Forwarding, is now listening on display 11 for our user.

To review, here's a full explanation of what happened in the last example:

  1. You type "ssh -X user@remote" in your terminal (to establish an SSH connection with X Forwarding enabled).
  2. The ssh process connects to the sshd server of @remote system.
  3. sshd spawns a new process that is an X-server-emulator listening on some random display number, e.g. "11".
  4. sshd sets the $DISPLAY to point to that local "X-server" (e.g. ":11").
  5. xcalc reads this $DISPLAY and conncects to this X-server. xcalc thinks it's displaying to the local machine.
  6. The X-server-emulator simply forwards the X commands from xcalc through the ssh connection, to the original ssh process.
  7. The ssh process @home now acts as a normal X-client and sends those commands to the X-server @home.

SSH X-Forwarding (a more secure alternative to VNC)

You could recall that the X protocol is designed to go over the network, right? So, let's see how to use X protocol without SSH and also why we shouldn't use it without SSH:

user@remote: DISPLAY="home:0"
user@remote: xcalc

This doesn't work because the X server @home won't let other hosts connect to it. To change this (you should not) you can do:

user@home: xhost +remote

xhost is a command line tool fo X Server which says that host can connect to our X-server. However, everybody uses and should use SSH with X forwarding instead for the following security reasons:

  • Normally, X-traffic (like your keystrokes) is sent unencrypted from X-client to X-server (so a sniffer could collect those and reconstruct sensitive data, like passwords).
  • SSH nicely sends that data through an encrypted channel, so it doesn't go over the internet in the clear.
  • xhost +remote is putting a lot of trust in remote being a good and reliable system. If remote ever gets hacked, it could connect to the X-server @home and listen to all its keystrokes.
  • There's also an issue with firewalls: by doing DISPLAY=home:0, you're assuming that a connection can be established from remote to home system. But this isn't always possible because the home might be sitting behind a firewall (like your home router). Since the SSH connection is already setup, X traffic will take advantage of this established connection without issues about firewall or other blocking walls between those two systems.

The following notes are for curiosity:

  • If the $DISPLAY variable is set to "localhost:0" the system will use TCP/IP (because hostnames are viewed as network resources) to send the X-traffic locally.
  • If $DISPLAY is just ":0", as default, it will use a special (more efficient, not TCP/IP) connection.