How to use SSH to graphically access remote machines and applications safely

November 19th, 2009

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.

How to safely use SSH to protect your information

November 16th, 2009

How to safely use SSH to protect your information

SSH stands for Secure Shell. It was originally created as a safer method to access remote shells then current implementations at the time such as telnet. However you can use the secure channel that SSH provides for virtually any communication between two networked devices to add a higher level of confidentiality to your communications. Before we go any further with this article though it is important that we discuss some of the often overlooked technical aspects of SSH that can render it useless in the presence of decent hackers if you don’t really know what you’re doing.

Where SSH has failed us in terms of security and how we can fix it

When the SSH1 protocol first came out it was the most secure means to access remote terminals at it’s time. However, years passed and hackers missed good old plain text transmissions so they quickly discovered that through the use of MiTM (man in the middle) attacks they could snatch up the encryption keys being transmitted across the wire and read transmissions in plain text just like it was telnet. Thankfully the SSH2 protocol came out shortly after and fixed this mess, or at least it tried. The new problem with the arrival of SSH2 is that it was incompatible with SSH1 so it broke when trying to communicate with SSH1 servers. So for legacy reasons most clients to date still fall back on SSH1 if they detect that the server doesn’t support SSH2. Now clients falling back to SSH1 did absolutely nothing to fix the insecurity issue of the protocol as it was still being used. MiTM attacks still take advantage of this legacy feature today by tricking the client into using SSH1 by making it think the server doesn’t support SSH2.

Theirs still hope for SSH though. SSH2 has been around since 1996 and since then their has never been a working proof of concept of a way to decrypt a transmission in it. Theory says it’s entirely possible however i must reiterate, 13 years and nobody’s made even a proof of concept that they can do it. Most clients today have an option, that isn’t enabled by default for some reason, to force the connection to use SSH2 and SSH2 only. You accomplish this in the OpenSSH client by passing ‘-2′ as an argument. You can write this as an alias in .bashrc (or equivalent) so your shell will automatically enforce SSH2 connections only. You can do this with the following command:

echo "alias ssh='ssh -2'" >> ~/.bashrc

How can i use SSH to keep my information confidential?

First of all, i guess it’s worth noting that unless you can SSH or similar directly to the destination theirs no such thing as completely confidential information in an internet transmission. However by the end of this article you will have enough information to establish and maintain secure channel communications capable of providing 100% confidentiality in a wide open LAN regardless on any given protocol you choose to use. This will most notably be useful for people who don’t wish to shoot out their passwords in plain text over the air in public wi-fi hot spots, for students using college connections who don’t want nosy admins groping their packets, or the employee at work just trying to check his personal email with some privacy (during his break of course). This can also be used to sneak around annoying firewalls that restrict access to certain websites and services. Regardless of the case confidentiality on the internet can be a priceless tool at times.

Why not just use a VPN

As a matter of fact OpenSSH has built in support for VPN over SSH right out of the box and it’s relatively easy to set up. I’ll discuss VPN over OpenSSH in another article though. Anyways, setting up a VPN would be a great option as well and by all means i encourage you to set one up some time. However SSH is easy and most *nix boxes already have it installed and if it’s not already installed it’s a pretty painless procedure. So I’m aiming for out of the box confidentiality.

What you need

You’re going to need at least one of the following three requirements: 2 computers (one as the client you’d use and another as the tunneling server), a remote shell account or a router flashed with DD-WRT/OpenWRT. The main thing is to be able to establish an SSH connection with a box either outside of your current network or with the router itself. The way I achieve this on my home network is by establishing the SSH connection to the my router which is a custom FreeBSD server. However the easiest way to accomplish this would be with either a remote shell or with a router flashed with DD-WRT/OpenWRT.

For people wanting to go the DD-WRT/OpenWRT way and aren’t super comfortable with flashing their firmware I recommend they either pick up a Linksys WRT54GL (~$45 USD), which is a router designed for enthusiasts that’s pretty much made to be flashed (the appended L actually stands for linux rumor has it) and can be flashed in about 1 minute through the admin WebUI. You can even buy routers pre-flashed with DD-WRT/OpenWRT for a $10-15 added cost on average.

I have to re-iterate that the SSH server you want to connect to must either be on the edge of your network (router) or outside of it, otherwise the purpose is lost as no improved confidentiality is achieved due to your traffic still being forwarded in plain text across the local network.

Ok, i want to know how to tunnel already!

Ok, now the fun part. So you’re going to need to know the IP/web address of the SSH server you want to tunnel through and I’m going to assume you already know how to do this. If you don’t know how and you’re tunneling through your router you should look up how to set up DynDNS on the router which will give you a custom domain name. For this demo I’ll be tunneling through my router which has a local IP of 192.168.1.1, so whenever you see that IP just substitute it for the IP/Address that you wish to connect to. We’ll start the fun off by firing up our terminal of choice (windows users have no excuses this works in cygwin too) then entering the following command.

ssh -2NfD 4321 thetan@192.168.1.1

Now what this does is force the ssh client to use the SSH2 protocol (secure), tells the SSH server not to run a command (focus on connection tunneling instead), pushes the ssh client in the background and sets up a SOCKS 4/5 proxy on the local machine listening to port 4321 (can be any port greater then 1023, otherwise you have to run the ssh client as root) that will take all incoming traffic through the SOCKS proxy, encrypt it and push it through the secure channel. Now all you have to do is configure your client’s to talk through the local SOCKS proxy. Not all clients support SOCKS proxies but most major ones do.

To make Firefox connect to this local SOCKS proxy (in linux, i think it’s slightly different in windows) you’d open up Firefox, Navigate to Edit -> Preferences -> Advanced -> Network -> Settings, check ‘manual proxy configuration’, in the box that says SOCKS host type ‘127.0.0.1′ and for the port type ‘4321′ (or whatever port you used), click ok and viola you’re speaking alien to everyone else who doesn’t need to know.

What if i want to use a client that doesn’t support SOCKS?

Your favorite client for whatever doesn’t support SOCKS proxies, no problem. You can forward on a port by port basis as well. The process similar so I’m just going to jump in and show you the goods with a sample command. The following command you could use to keep prying eyes from reading your IRC conversations and nickserv/oper passwords. This would be useful if either the server or client you are connecting to/with doesn’t have built in support for SSL.

ssh -2fL 3337:irc.criticalsecurity.net:6667 Thetan@192.168.1.1 sleep 120

Now the above command forces the SSH client to use SSH2, pushes it in the background, and starts listening on port 3337 for TCP connections, found connections and associated data will be pushed through the secure channel to the SSHD host (192.168.1.1) and then forwarded to irc.criticalsecurity.net on port 6667. The sleep command is used to keep the ssh client open and listening for connections as ssh will die if no connections are found or programs are running.

What you would do to use this is instead of connecting to the remote IRC server directly you would have your IRC client connect to 127.0.0.1:3337 instead and no further configurations are required.

The same process applies to all other protocols on all other ports. In order to run multiple clients with this method you’d have to issue a similar port forward command through ssh with non conflicting local ports per command. So as you can tell using the dynamic forwarding method via the SOCKS proxy can be a lot less head ache prone.

HiveMind protocol updated

November 16th, 2009

Yeah so i uploaded an updated version of the HiveMind protocol I’ve been working on. Not really to much significantly different with this version. Most notably i added server responses for a couple commands that were missing them and i added topic support. You can view the current protocol here. I think I’m just going to take it easy for the rest of the day. If i find the time I’m going to work on some weather proof casings for my wireless nodes.

nada lot’a

November 15th, 2009

Been mostly hanging out this weekend didn’t have much time to work on anything as kids do tend to take up a lot of time. Perhaps tomorrow i’ll knock some shit out. I got a couple of things i want to do, but let’s see what happends

Let the fun begin

November 14th, 2009

Ok, I’ve never really had a blog before so let’s see how this goes.