My little ssh hell
March 21, 2012An “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.