My little ssh hell

March 21, 2012

An “old” computer of mine is nicely hosted at my $work offices in France. This machine serves as a VPN server for each and every worker that would like a remote access to our local network in Paris. I’m my first client, so it’s not that unfair that I used my own computer (plus some company time…) to setup some services.

The office is linked to the net through a fiber with very decent up/down rates, plus a backup on two DSL lines, just in case. Some ports are simply NAT-ed to out little VPN server. Let’s call her polaris, since it’s kinda pointing home.

I couldn’t not abuse this setup, so my IRC client is sitting on polaris, and is used for (mostly) professional discussions. However, I can’t really rely on the VPN to be up all the time to connect to the machine, and a proper out-of- band channel was needed.

Out of pure boredom, I decided I would use another server of mine as a tunnelling outpost where I’d forward polaris’ local SSH port. Using a crontab, I’ll just launch periodically a script that looks just like this one:

#!/bin/sh
  
count=`pgrep -cf oz@outpost.tld`
  
if [ $count -eq '0' ]; then
  
    # Root is needed to forward privileged ports...
  
    sudo -u oz ssh -fNi /home/oz/.ssh/outpost-key oz@outpost.tld -R 2222:localhost:22
  
fi
  

On my laptop I would then add the following lines to ~/.ssh/config:

Host tunnel-outpost
  
    User oz
  
    Host outpost.tld
  
    LocalForward localhost:2222 localhost:2222
  

To connect to polaris, from my laptop, I’ll have a background ssh -fN tunnel- outpost running, so I can connect to polaris ssh oz@localhost -p 2222

I’m sorry sir, but that’s way too simple. I also want to use my IRC client (irssi) as a bouncer/proxy. For this, you’ll have to /load proxy in irssi and then set a port for each network you want to proxy using /set irssiproxy_ports network_name=PORT (quite fastidious IMHO…). Let’s add a few more SSH config lines to my laptop then:

Host tunnel-polaris
  
    User oz
  
    Host localhost
  
    Port 2222
  
    LocalForward localhost:4242 localhost:4242
  
    LocalForward localhost:4243 localhost:4243
  
    # One line per forwarded IRC network (I have like 6 of those...)
  

Now I’ll have to run two backgrounded SSH tunnels to have my ports tunneled: ssh -fN tunnel-outpost && ssh -fN tunnel-polaris. This is getting fun (or ridiculous?) I can now run whatever IRC client I want connecting it to the forwarded TCP ports on localhost… Let’s do one more silly thing while we’re at it. Let’s imagine, I’m sitting in a Starbucks somewhere in Mexico, and one of our beloved clients decided she would open her secret development service only to a few public IPs, including my office’s. That’s a very weak security measure, but sadly not uncommon. Well that’s a job for a proxy.

Using SSH, you can setup a really dumb Socks proxy in seconds. I typically use DynamicForward. So my SSH config is now starting to look like this:

Host tunnel-polaris
  
    User oz
  
    Host localhost
  
    Port 2222
  
    LocalForward localhost:4242 localhost:4242
  
    LocalForward localhost:4243 localhost:4243
  
    # One line per forwarded IRC network (I have like 6 of those...)
  
    DynamicForward 4200
  

And… That’s how you get a spaghetti SSH config.

As a side note, I should add, that I fell in love with SSH’s ControlPersist feature, that allows you to share a connection to the same server between several SSH clients (I’ll let you check the excellent ssh_config manpage for this). In the end, my laptop’s SSH config is more in the lines of:

ControlPath "/home/oz/.ssh/%h-%p.sock"





Host tunnel-polaris
  
    ControlMaster yes
  
    ControlPersist yes
  
    User oz
  
    Host localhost
  
    Port 2222
  
    LocalForward localhost:4242 localhost:4242
  
    LocalForward localhost:4243 localhost:4243
  
    # One line per forwarded IRC network (I have like 6 of those...)
  
    DynamicForward 4200
  

cough … :)

Sadly, I have a few of these things. Hosts should be in different countries or it’s pointless and spoils all the fun, and maybe you could add Tor proxying here and there for those times when invisibility is more important than latency.

So, as a conclusion, I’m so not publishing my dotfiles to Github.