Wednesday, January 25, 2012

SSH Tunneling for Fun and Profit

When you finally, finally understand how SSH tunneling works, it opens up a whole universe of possibilities...

Dynamic DNS

If you don't have a static IP address, you'll need to get yourself set up with a dynamic DNS provider so that you can find your computer no matter what IP address your ISP has given you. There are plenty of service providers to pick from. I like DynDNS because it's free and my provided domain name can be updated from my router (they also provide installable daemons for any flavor of OS).

Tunnel through NAT (with static DHCP leases)

You've got a few options for trying to tunnel through to a SSH server behind your NAT/firewall. You can set up your router to forward a certain port to your SSH server, or if your router itself has an SSH server, the ssh tunneling syntax can do the forwarding for you:

ssh -L 9999:targetserver:1234 sshuser@sshserver

This command will tunnel port 9999 on the local machine to port 1234 on the target machine through the SSH server. Keep in mind that the data flow between the SSH server and target server will not be encrypted. This issue is addressed later.

Stream Ampache (or any web application)

Simple enough--build a tunnel to the web server's http port.

ssh -L 8888:webserver:80 remoteuser@sshserver

Then point your web browser to http://localhost:8888.

VNC over SSH

Here's a handy scenario for tunneling a VNC server to local port.

ssh -L 5900:vncserver:5900 remoteuser@sshserver

Now just point your VNC client application to localhost:5900 and bam! you're connected. With this tunnel, traffic between sshserver and vncserver is exposed to the network, and since VNC is not a secure protocol by default, this could be an issue. The next section demonstrates a potential solution.

Tunnel Within a Tunnel (We Have to Go Deeper) (via1, via2)

Say you need to SSH tunnel from your localhost to host1, and then from host1 to host2. Provided that host1 and host2 both have SSH servers, you can join two tunnels in the following way:

ssh -L 9999:host2:22 host1user@host1
ssh -L 9998:localhost:5900 -p 9999 host2user@localhost

The first tunnel connects the SSH server on host2 port 22 to localhost port 9999 (using host1's SSH server). The second tunnel connects the service at port 5900 on host2 to the localhost port 9998 (through host2's SSH server available now as a result of the first tunnel).

So when whatever client application is pointed to the localhost port 9998, it's really tunneling to host2 port 5900 through host2's SSH server... where the connection to host2's SSH server is actually through another tunnel (from localhost port 9999 to host2 port 22 over host1's SSH server). And there you have it: a tunnel within a tunnel. My head hurts.

Stream iTunes (via1, via2)

This gets a little trickier because of the way iTunes advertises itself on the network. We'll need to use another application to assist with that bit, but the tunneling is the same. iTunes streams over port 3869, so:

ssh -L 9999:itunesserver:3689 sshuser@sshserver

Then, with the tunnel up and running,

dns-sd -P "Home iTunes" _daap._tcp local 3689 localhost.local. 127.0.0.1 "Arbitrary text record"

Package that up into a script, and you're good to go.

No comments:

Post a Comment