Saturday, April 15, 2006

OpenVPN + DNS + OS X

OpenVPNOS X has a very cool feature built into to its resolver: /etc/resolver. It allows you to specify different DNS servers for different domains. After creating the /etc/resolver directory, I can create a /etc/resolver/erdelynet.com file with "nameserver 192.168.25.10" in it. Now, my Mac will use 192.168.25.10 for resolving erdelynet.com and whatever my ISP assigned me for everythying else.

When is this useful? erdelynet.com runs a MySQL server. My firewall blocks attempts from the Internet to port 3306. But suppose I want to just run a MySQL admin tool from my PowerBook and don't want to mess around with SSH tunnels.

With OpenVPN & /etc/resolver/erdelynet.com, I can seemless move from external user to internal user with two clicks.



So, I pop open my PowerBook at Starbucks (their coffee sucks, but they're a common example). I get some DNS server. When I connect to erdelynet.com, I'm connecting via its public IP address and connect as anyone else would. But I want to manage my MySQL server or VNC to my wife's computer or access some internal, private web site. But these features are blocked at the firewall.

OpenVPN gets me halfway there. I can connect to my web server's private IP address directly, but I cannot resolve it's IP address. Starbucks' DNS server knows nothing of it.

Using OpenVPN's "up" and "down" script options, I add "up ~/bin/up.sh" and "down ~/bin/down.sh" to my ~/Library/openvpn.conf file. Then I create my up.sh and down.sh scripts...

up.sh:
#!/bin/bash -x
mkdir -p /etc/resolver 2> /dev/null
echo "nameserver 192.168.25.10" > /etc/resolver/erdelynet.com
# Added to script Mar 7 2007
killall lookupd
# Removed from script Mar 7 2007
# /usr/sbin/lookupd -flushcache
exit 0


down.sh:
#!/bin/bash -x
rm -Rf /etc/resolver/erdelynet.com
# Added to script Mar 7 2007
killall lookupd
# Removed from script Mar 7 2007
# /usr/sbin/lookupd -flushcache
exit 0


NOTE: If /etc/resolver didn't exist since the last time lookupd started (probably when you last rebooted), you have to restart it: sudo killall lookupd ; sudo /usr/sbin/lookupd.

I thought I'd mention, if you haven't tried it yet, Tunnelblick is an AWESOME OpenVPN GUI for Mac. It's what I use.

When I make my OpenVPN connection, I see that a new file, /etc/resolver/erdelynet.com, is created. And when I ping erdelynet.com, I now see it's private IP address instead of its public IP address. Assuming that I've allowed connections through OpenVPN to my MySQL server, I can just fire up my admin tool and connect directly to my MySQL server -- through the VPN.

Then, when I disconnect, the file automatically gets deleted. The "lookupd -flushcache" command tells OS X's resolver to forget about my internal network and it goes about using the ISP assigned DNS server for erdelynet.com again. Talk about easy.

There's only one problem: Suppose my Mac or the OpenVPN connection shutdown un-gracefully. The /etc/resolver/erdelynet.com file does not get deleted. Then, DNS to my domain is fubar'd. To prevent this from happening (only happened once that I can remember), I added "rm -rf /etc/resolver/erdelynet.com" to /etc/rc.local (I did have to create rc.local, but /etc/rc is configured to run commands from it upon bootup if the file exists).

Enjoy.