How X Over SSH really works September 27, 2008Imagine you are sitting in front of a machine named "home" that has a keyboard, mouse, display, and is running an X server. Now you open a terminal and ssh to a machine called "remote" (which doesn't need to have an X server running), and run a program like "firefox" which pops a window in your screen. How does this all work?
First, let's clear up the client/server terminology confusion. When talking about X:
- 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.
Now let's see what happens when you ssh to another machine:
Wait a minute, the $DISPLAY variable is pointing to the localhost ("remote"). Natural questions to ask at this point:
- There is no X server @remote, so why didn't xcalc just fail on startup?
- Why was the display number "11".
- How did xcalc show something @home?
What's happening is that there's an "X emulator" running @remote that was setup just for your ssh session, that is listening on display 11.
To review, here's a play-by-play:
- You type "ssh -X user@remote" in your terminal
- The ssh process connects to the sshd server @remote.
- sshd spawns a new process that is an X-server-emulator listening on some display number, e.g. "11"
- sshd sets the $DISPLAY to point to that local "X-server" (e.g. ":11")
- xcalc reads this $DISPLAY and conncects to this X-server. xcalc thinks it's displaying to the local machine.
- the X-server-emulator simply forwards the X commands from xcalc through the ssh connection, to the original ssh process.
- The ssh process @home now acts as a normal X-client and sends those commands to the X-server @home.
Some of you might be wondering: wasn't the X protocol designed to go over the network? Can't you do all this without ssh? You might be tempted to try something like:
This doesn't work because the X server @home won't let other hosts connect to it. To change this (not that you should -- see below) you can do:
xhost is a command which says "that host can connect to our X-server". However, everybody uses ssh X forwarding instead. Here are some security reasons why:
- Normally, X-traffic (like your keystrokes) is sent unencrypted from X-client to X-server.
- 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 nice guy. If remote ever gets hacked, it could connect to the X-server @home and listen to all its keystrokes.
Other notes for the curious:
- if $DISPLAY is set to "localhost:0" (or any explicitly named host) it uses tcp-ip to send the X-traffic locally.
- if $DISPLAY is just ":0" it uses a special (more efficient, non-tcp-ip) connection. blog comments powered by Disqus