Pseudo-VPN stuff with SSH

Firstly, there are *lots* of ways to do this. This is one way.

Secondly, poking holes in your corporate network is occasionally frowned upon and may contravene your workplace Acceptable Use Policy or equivalent. If you have a VPN solution (HTTPS, L2TP, or whatever) which works on everything you need, then I shouldn’t need to tell you to use that instead.

Anyway…

At home, on the end of my DSL line I have a PC running Linux.

At work I have lots of PCs running Linux.

Sometimes I’m using a random machine and/or a platform unsupported by my corporate VPN and I want to connect to work without using the (recommended) HTTPS VPN or (complicated) L2TP. So I turn to a trusty source of cool networky stuff: SSH.

Importantly, SSH understands how to be a SOCKS server. This allows applications which understand SOCKS (most Windows stuff for example) to redirect all their traffic over SSH without the addition of a proxy server like Squid on the corporate end.

So, how do you set it up? It’s fairly easy:

1. Set up the work-to-home connection:

user@work:~$ while [ 1 ]; do ssh -NR20000:localhost:22 user@home.net; done

2. Set up the laptop-to-home connection:

user@laptop:~$ ssh -L15000:localhost:20000 user@home.net

3. Set up the laptop-to-work connection:

user@laptop:~$ ssh -D15001 localhost -p 15000

If you’re at home and your “other” machine is on the same network as your home server you can be a bit more adventurous and do the following:

1. set GatewayPorts yes in your sshd_config

2. Set up the work-to-home connection, where home_ip is the IP of your home server on your internal network:

user@work:~$ while [ 1 ]; do ssh -NRhome_ip:15000:localhost:22 user@home.net; done

3. Set up the laptop-to-work connection:

user@laptop:~$ ssh -D15001 home_ip -p 15000

Passwordless authentication can be configured by setting up your ssh host keys correctly.

In both scenarios above, SOCKS-aware applications can be configured with server as “localhost” and port as “15001”. For non-SOCKS-aware applications, you can generally get away with using tsocks.

You’ll also notice that step (1) needs bootstrapping while you’re on the corporate network. Persuade someone to su to you, or do it while you’re in the office one day.

Generally you also want to reduce the possibility of your work-to-home connection failing, so run it in screen, or in a nohup script or use something like autossh or rstunnel to bring it back up for you.

Don’t forget you’ll also need to open appropriate holes in your home firewall, generally some sort of NAT, PAT, or DMZ settings to allow incoming SSH (TCP, port 22) to be forwarded to your home server.

Update 2010-06-30 17:57
It’s worth mentioning that if you don’t have a static IP on your home DSL line that you’ll need to use a dynamic DNS service (like DynDNS) to keep a static name for your dynamic IP. Personally I do other stuff with Linode so I’ve set something cool up using their web-service API.

Bookmarks for June 14th through June 28th

These are my links for June 14th through June 28th:

Bookmarks for June 8th through June 14th

These are my links for June 8th through June 14th:

Adventures in UTF-8

I think I’m very nearly at the verge of beginning to understand UTF-8.

Internal UTF-8 string, encoded
Wrong:

sentinel:~ rmp$ perl -MHTML::Entities -e 'print encode_entities("°")'
°

Right:

sentinel:~ rmp$ perl -Mutf8 -MHTML::Entities -e 'print encode_entities("°")'
°

External UTF-8 input, encoded
Wrong:

sentinel:~ rmp$ echo "°" | perl -MHTML::Entities -e 'print encode_entities(<>)'
&Acirc;&deg;

Right:

sentinel:~ rmp$ echo "°" | perl -MHTML::Entities -e 'binmode STDIN, ":utf8"; print encode_entities(<>)'
&deg;

External UTF-8 string, as UTF-8 (unencoded)
Wrong:

sentinel:~ rmp$ echo "°" | perl -e 'binmode STDIN, ":utf8"; print <>'
?

Right:

sentinel:~ rmp$ echo "°" | perl -e 'binmode STDIN, ":utf8"; 
binmode STDOUT, ":utf8"; print <>'
°

External Input – Encoding after-the-fact
Wrong:

sentinel:~ rmp$ echo "°" | perl -Mutf8 -e '$in=<>; utf8::upgrade($in);
binmode STDOUT, ":utf8"; print $in'
°

Wrong:

sentinel:~ rmp$ echo "°" | perl -Mutf8 -e '$in=<>; utf8::encode($in);
binmode STDOUT, ":utf8"; print $in'
°

Wrong:

sentinel:~ rmp$ echo "°" | perl -Mutf8 -e '$in=<>; utf8::downgrade($in); 
binmode STDOUT, ":utf8"; print $in'
°

Right:

sentinel:~ rmp$ echo "°" | perl -Mutf8 -e '$in=<>; utf8::decode($in);
binmode STDOUT, ":utf8"; print $in'
°

Bookmarks for May 13th through June 4th

These are my links for May 13th through June 4th: