Your browser is very old. You might enjoy surfing the web more if you used something newer like:

Google Chrome

Even Firefox would be OK.

If you're being forced at gunpoint to use Internet Explorer, you should at least upgrade it. Version 8 is tolerable and 9 will be OK when it comes out.

Posts from July 2009

SSH Tunneling: Taming the series of tubes

How many times have you been in this situation?

You can connect to a server via SSH but you really need access to some other process on the server that doesn’t have an exposed port. Or worse, you need to connect to an entirely different server that isn’t exposed to the outside at all.

Well, thanks to the mystical voodoo of SSH tunnels, your worries are over!

The idea of SSH tunnels can be a little confusing at first but it’s actually pretty simple in practice.

SSH Tunnel diagram

Here’s the basic idea of how it works:

  • Start an SSH connection.
  • Define a port on the local machine (the machine where your SSH connection is starting from).
  • Define a remote port and IP address for the to local port map to.

For example:

Let’s say that you are allowed to SSH into the server at remote.foo.com but you want to be able to connect to it via VNC. You normally can’t because, even though VNC is running on remote.foo.com, the VNC port isn’t exposed to the outside.

But you can connect to VNC through an SSH tunnel.

Using your favorite SSH client, map the local port 5900 to localhost:5900 (in this case, localhost:5900 refers to port 5900 of the machine you’re connecting to via ssh), and connect.

Now you can fire up your VNC client and point it at localhost:5900 (in this case, localhost:5900 is the local machine (eg the machine your SSH connection started from). Your SSH client will then forward that local VNC connection through the existing SSH connection and you’ll be connected to VNC on the remote machine.

So how do you actually set up the tunnel in your SSH client?

It’s very easy if you’re using the command-line SSH client. Here’s the basic command syntax:

ssh -L LOCAL_PORT:REMOTE_IP:REMOTE_PORT

So, in our example above, the command would look like:

ssh -L 5900:localhost:5900 remote.foo.com

If you’re on Windows, you’re probably using PuTTY (and you should be if you’re not).

To set up an tunnel with PuTTY, click on the Connection item in the PuTTY Configuration, then click SSH, and then click Tunnels

Enter the local port in the Source port box and the remote ip/port in the Destination box.

Now here’s the really cool thing about SSH tunnels.

You can also tunnel to other machines on the same LAN as the machine you’ve SSH’ed into!

Let’s say there’s a server on the same network as remote.foo.com but it’s not exposed to the outside at all. Let’s say it has an IP address of 10.0.0.4 and it’s running a web server on port 80.

We can set up the following SSH tunnel to get access to the web server.

ssh -L 8080:10.0.0.4:80 remote.foo.com

Once you’re connected to remote.foo.com, start up your browser and surf to http://localhost:8080 and that traffic will get tunneled through to the machine behind remote.foo.com.

It’s important to note that the traffic from your local machine to remote.foo.com is secure because the SSH connection is encrypting it. However the traffic from remote.foo.com to 10.0.0.4 is not secure.

And, of course, you can stack up as many tunnels as you want.

ssh -L 5900:localhost:5900 -L 8080:10.0.0.4:80 -L 5901:10.0.0.4:5900 remote.foo.com

The above creates tunnels to VNC on remote.foo.com, port 80 on 10.0.0.4, and VNC on 10.0.0.4.

There you have it, the basics of SSH tunneling, one of my favorite tricks. My most common use of late has been tunneling connections to either PostgreSQL or MySQL so I can use PGAdmin or SQLyog Community.

My single-handed destruction of an Ecuadorian cafe

Parque Calderon

The heart of Cuenca is the cathedral and the Parque Calderon. At one corner of the square is the Café Raymipamba, a small restaurant with the most fantastic toasted chicken sandwiche I’ve ever tasted. Entering the cafe from the ground floor, the center of the room is full of tables, the perimeter lined with booths. Sun from the plaza outside comes pouring in through the windows lining the front. The small upstairs is made entirely of wood, lamps hanging over every table, and a low balcony that opens to the rest of the restaurant.

Raymipamba

It’s the spring of 1997 and I’m sitting at a table upstairs, eating my toasted chicken sandwich, trying desperately to wrap my head around the dense packet of  Cultural Anthropology in front of me.   The right side of my table is pressed firmly against the balcony’s bumpy wooden railing.  I’m making progress with my reading, turning page after page. The side of my binder closest to the balcony is getting taller and taller.

And then it happens.

The massive binder slides over the edge of the balcony onto a long table below. It hits with a crash like a body falling and food and beer go flying everywhere.

There is dead silence in that split second after the fall and I leap to my feet intending to rush below to make amends, completely forgetting about those god-damned lamps. The beautiful, stained-glass lamps clearly designed for the average Ecuadorian, not scruffy, six-foot gringos. I stand straight into the center of the lamp which explodes practically scalping me and spraying the upstairs with broken glass. I manage to not pass out or fall over, press a pristine cloth napkin to my bleeding head and make my way downstairs.

The six-top below is a group of amazingly understanding American tourists who are, luckily, more concerned about my well being than annoyed about the destruction I have wrought upon them. I flag a passing waiter and order another round for their table and then make my way over to the register where the owner is almost unable to stand from laughing.

I make many attempts to pay for, or at least help clean up, the damage to the lamp and the table below. Gasping for breath and red faced from laughing, he refuses my offers. With some difficulty, I manage to pay for my lunch and slink out.

I stave off my chicken sandwich cravings for almost two weeks before I am forced to return. I can’t tell if the owner remembers me or not and the evening passes without incident.

Basic page routing with CherryPy

My last CherryPy post covered how to set up a very basic site using the quickstart() function. This time, I’m going to go into some basic details on page handling..

The first thing we’re going to do is define a class for handling the root of our site.

class Root:
    def index(self):
        return "This is the root"
    index.exposed = True

if __name__ == "__main__":
    root = Root()

    cherrypy.tree.mount(root, '/')
    cherrypy.engine.start()
    cherrypy.engine.block()

There’s a lot going on in the above so let’s break it down starting with the code that’s actually running the site.

First we create an instance of the Root() class and mount it at the url ‘/’. Then we start the cherrypy engine. The default behavior in this case is for the site to run on port 8080 so our site is running on http://localhost:8080.

Hitting that url is going to call the index() of the Root() class. Note the index.exposed = True line below the method. That’s important because, without it, the method can’t be called from outside the class.

Now let’s add another url route.

if __name__ == "__main__":
    root = Root()

    root.names = NamesPage()

    cherrypy.tree.mount(root, '/')
    cherrypy.engine.start()
    cherrypy.engine.block()

See the line starting with root.names = ? That’s going to set up a handler for the url http://localhost:8080/names.

Let’s look at the definition of the NamesPage() class. The simplest would be something just like the Root() class.

class NamesPage:
    def index(self):
        return "This is the root"
    index.exposed = True

But what if we also wanted to handle the url http://localhost:8080/names/help?

class NamesPage:
    def index(self):
        return "This is the names index"
    index.exposed = True

    def help(self):
        return "This is the help page"
    help.exposed = True

You can see how the first part of the request URI maps to the index method of the page handler class. The next part of the request URI maps to any method in the routing class with a matching name.

The next neat bit about routing comes into play when the last part of the URI doesn’t match any defined methods. For example, how do we handle the url http://localhost:8080/names/mark?

As the NamesPage() class stands now, we’ll end up with a 404 exception. But, by using the default() method in the NamesPage() class, we can handle it in a very cool way.

class NamesPage:
    def default(self, name=None):
       return "Hello " + name
    default.exposed = True

    def help(self):
        return "This is the help page"
    help.exposed = True

With this definition of NamesPage(), everything that comes after “/names/” (except for help/) gets passed as an argument to the default() method.

The above is a pretty simple summary. There’s a lot more that can be done as you can see from the PageHandlers documentation.