OpenVPN with TomatoUSB sauce and TAP dancing

I just bought a Netgear WNR3500L to replace my Linksys WRP400 wireless router. The main reason I bought that particular device is the Tomato firmware, specifically the TomatoUSB variant of it (at http://tomatousb.org/) which has OpenVPN support.

Flashing the firmware was straightforward - I flashed the DD-WRT mini CHK firmware first, and then TomatoUSB (tomato-K26USB-1.28.9051MIPSR2-beta22-vpn3.6, to be precise). One hard reset later Tomato was running.

So far it's been rock solid for me - time will tell how solid it really is.  The only thing that has irked me so far is that it comes with a SIP ALG and SIP NAT-helper turned on by default - this plays havoc with work's equipment (yes, I'm currently in the VoIP business).  Easy enough to turn off, though, once you know about it.

Now for the OpenVPN setup. One thing that immediately struck me was that there is no way to set up auth-user-pass authentication (which is what work uses).  But the "custom" option looks promising...  Let's try it!

Here's the basic page of my config:

Note that interface type is TAP, Firewall is Automatic, and Create NAT on tunnel is checked.

Now for the advanced page:

Here is the custom config.  As there is no user to be queried for credentials when bringing up the tunnel, they  need to be stored on disk somehow.  I'll get to the "how" part later; for now, rest assured that /tmp/ca.crt and /tmp/client1-userpass will be available.

Interesting to note here:

  1. We explicitly say that we're a client, as tomato only adds this automatically in the TLS mode; I figure this is a bug in TomatoUSB
  2. We set script-security 3 (to tell OpenVPN that it's ok to run our up script)
  3. We reference a script in /tmp as our up script; I'll get to why in a bit
So how are the files in /tmp generated?  At boot-time!

Have a look at my init script:

Of course the values here aren't real. :)

As you see, we stuff our credentials and the CA certificate in the files where we've told OpenVPN to look for them; we also generate the up script.

The up script is as it is because of two other (IMAO) bugs in TomatoUSB:
  1. You cannot receive DNS server entries from the VPN server in custom mode; to work around this, we call out to the same script as would have been done in the other modes
  2. Even though you can tell it to do NAT on the tunnel, and it will even generate the script to set it up (/etc/openvpn/fw/client1-fw.sh), it will never get run if the interface is not TUN.
After all this, I now have always-on VPN on the router.  :)

1 comment:

pashdown said...

Thanks for this. That last bit about OpenVPN not running the NAT script for tun was a lifesaver for me. I was pulling my hair out!