Intro
This is part 2 in my “SSH as the swiss army knife of networking” series of articles that I just started writing recently. This time we’re going to be playing with a fun feature that’s built into SSH that allows us to run graphical applications remotely while having the GUI displayed locally. The way this will be accomplished is by forwarding X11 headers through an SSH connection, known simply as X11 forwarding through SSH.
How is this different then VNC?
VNC is a desktop sharing system where multiple users can manipulate the same desktop environment in real time. The method we will be discussing is more simply a GUI forwarding system that works by taking advantage of the natural client-server structure of X11. X11 forwarding through SSH isn’t meant for desktop sharing and works more by giving each user a desktop to remote host.
What is this X11 you keep talking about?
You might not of ever heard of it but if you use a major linux distro and you run either a windows manager (fluxbox, blackbox, enlightenment, etc) or a desktop environment (Gnome, KDE, XFCE, etc) then congratulations you are already running an X11 server along with numerous X11 clients. X11 or simply X is a client-server architecture for networked/local GUI’s. X was originally developed at MIT as part of a bigger project known as “Project Athena”, which was the first major shot at “thin-client” computing. The idea was that client’s could be low cpu and disk-less by booting through PXE (Pre eXecution Environment) over the LAN and running all applications remotely and having GUI data forwarded via X11.
The client-server architecture of X can be confusing to X beginners as it seems slightly backwards. This is because every ‘client’ running a GUI display has to run an X server. Every GUI application is a X client that sends GUI data to the X server and the X server takes the data and draws it to the screen. The X server is also responsible for forwarding relevant keyboard and mouse data back to the X client (the GUI application). A couple of examples for X clients would be Gnome, KDE, Firefox, Xchat, Thunderbird, etc.
Ok, let’s run a single program remotely and forward the GUI
Where going to start off simple by running just a single program over SSH and having the GUI forwarded. We’ll start off by running Wireshark on a computer in a remote LAN and having the GUI forwarded to us. This can be effectively achieved with the two following commands:
ssh -2X thetan@174.XXX.XXX.XXX sudo wireshark
You may be prompted for your SSH user password and depending on your configuration of sudo you may be prompted for the root password (you can use su by the way if you don’t like sudo). The first command opens the SSH client, forces it to use SSH2 (secure), forward X11 headers (GUI information) and connect to remote host ‘174.XXX.XXX.XXX’ (part of my IP removed for privacy
) as user ‘thetan’ (obviously you should change this to the appropriate user). The second command just runs Wireshark as root in our current SSH session, which forwards all X headers to our X server to be displayed locally. While you have Wireshark open remotely go ahead and play around with it for a while. You shouldn’t see any data about the current SSH session that’s forwarding the GUI data to you’re local client because Wireshark filters it out by default to avoid a horrible loop that would flood both networks. However, if you managed to run Wireshark on a machine that’s outside your LAN and in another LAN somewhere you’ll notice that if you open up Wireshark locally and compare the network traffic displayed on both GUI’s you’ll notice that it’s different. First of all the copy of Wireshark running locally can detect the SSH session that’s forwarding the GUI data. Most notably though the biggest difference is that the local copy and the copy being ran remotely are listening to two separate NIC’s behind to separate LAN’s. This is possible because all though the remote GUI is being displayed locally, all other processes not associated with GUI display are being ran remotely.
You should note that closing the terminal that the SSH session was started in will kill the SSH session along with the GUI that’s being forwarded through it. SSH has built in support for forking to the background from the command line but if you try to fork SSH into the background while sending it a sudo command it will fail with an error. A way around this is by installing gksudo on the remote machine and using gksudo instead of sudo like this:
ssh -2fX thetan@174.XXX.XXX.XXX gksudo wireshark
This will fork the entire SSH session to the background and forward all Wireshark X headers to your local X server and continue to do so after you close the terminal.
The sudo issue is not relevant if you are running programs that do not require root privileges. So i can also run Emacs remotely just like this:
ssh -2fX thetan@174.XXX.XXX.XXX emacs
That’s cool, but let’s run an entire desktop environment remotely.
Ok, now for the fun stuff. Lets start off lightweight with a window manager instead of a full blown desktop environment. For the first example we’ll run fluxbox remotely while having all the GUI drawn up locally. You could do this simply from a blank tty (CLI no WM/DE running) but that’s not as fun. We’ll assume that you are already running in a graphical environment (WM or DE doesn’t matter) and I’ll show you how to run your current desktop (locally) and multiple desktops (remotely) at the same time.
Ok, first thing you’re going to want to do is already be in a desktop environment or window manager (Gnome, kde, fluxbox, openbox, etc) now open up a new tty by pressing ctrl+alt+f2. You may be prompted to log in, go ahead and do so. Once logged in you should get dropped into whatever shell you have configured. From here we type the following command:
xinit -- :1 vt9
This will start up another X server running a basic X terminal as the only client on display 1 (display 0 should already be being used) and binds the GUI session to F9. You should be able to switch between your old GUI session and your new one by pressing ctrl+alt+f7 and ctrl+alt+f9. Now from your new GUI session use the X terminal to log into the remote host via SSH like so (i’ll be connecting to another machine on my network that’s in my garage):
ssh -2X thetan@192.169.1.115
Now all i do is just start up fluxbox by simply typing:
fluxbox
and all the GUI data will get sent to me and i have full GUI access via fluxbox to the remote machine. Once again i can switch between the local GUI and the remote GUI being forwarded by toggling between ctrl+alt+f7 and ctrl+alt+f9. This is cool and all, but let’s step it up a notch. Let’s fire up one more X server and connect to another machine and run Gnome off of it. So the same procedure applies. NOTE: Gnome must be installed on the remote machine
<ctrl+alt+f3> // this will open up another tty xinit -- :2 vt10 // same thing as earlier just incrementing our way up ssh -2X thetan@192.169.1.117 // different machine this time gnome-session // and that's it i'm running gnome in a GUI session bound to ctrl+alt+f10
Now this is cool, play around with this for a while bounce between the 2 remote and one local desktop by toggling around with ctrl+alt+f[7,9,10], open different programs on each of them run games remotely, have fun.
You can even log into the same machine twice and run different desktop environments/window managers off of it at the same time, as this is what X was originally intended to do.
Why doesn’t sound work?
Yeah, that’s probably one of the more notable draw backs with the original way X was implemented (and still is). X has no support for sound, it’s purely a graphical suite.
Why forward through SSH why not just use raw X?
X is designed to be an insecure protocol and believe it or not the original developers call this a feature. X is meant to be used through a secure channel or third party encryption scheme, this seperates the design of the X protocol from the design of an encryption protocol. Thus issues with any given encryption scheme can be dealt with separately. This philosophy comes partially from the standard unix philosophy of “do one thing, and do it good”.
Raw X can subject you to a plethora of security woes such as screen sniffing (yes, watching some ones screen remotely), Key jacking (stealing key strokes over LAN, ouch) and much more. So in conclusion, X was intended to be tunneled through a secure channel. Don’t make the mistake of thinking otherwise.
END
Well, hope you learned something. I’ll be writing a couple more articles on cool things to do with SSH soon so stay tuned.