HOWTO: Simply Connect Mac OSX to a dd-wrt OpenVPN Server on TCP Port 443

If you find yourself on a really restrictive network but still want to connect to a remote VPN, consider this solution. It allows you to connect a Mac OS X OpenVPN client to an OpenVPN server using a static key. I figured it out using a combination of webistes, including dd-wrt’s OpenVPN wiki, OpenVPN’s documentation, and tinyapps.org.

This solution can probably be way more automated using tunnelblick, but I’m alright with running a couple scripts (for now) to get my VPN going. Here’s what you’ll need:

Network
– No web proxy or a proxy that allows persistent connections.

Server
– A Linksys WRT54GL router
dd-wrt.v24_vpn_generic.bin (follow instructions on the website to flash from scratch.)

Client
– MacOS X Snow Leopard
OpenVPN v2.1.3
tuntap_20090913.tar.gz
lzo 2.02

I downloaded all of these then compiled and installed them myself. Not because I’m leet, but because the network I was on blocked sync and I couldn’t use MacPorts. So go download and compile these or use MacPorts.

First thing is first, I changed the subnet on my wireless router. I hate the 192.168 subnet; it’s aesthetically unappealing and overused. Now 172.20.0.x is something pretty. Let’s go with that.

We will not be using dd-wrt’s GUI to enable or configure OpenVPN, but rather startup and firewall scripts in the /tmp directory. I also avoid using the default protocol and port (udp, 1194) and go with tcp port 443.

Here’s a step by step

Server
– Generate the static key: openvpn –genkey –secret static.key
– Cat that key and place it in your clipboard
– Open up dd-wrt’s admin webpage, and go to Administration -> Commands. Paste the following:

openvpn --mktun --dev tap0
brctl addif br0 tap0
ifconfig tap0 0.0.0.0 promisc up
echo "
-----BEGIN OpenVPN Static key V1-----
[Insert your static key  here]
   -----END OpenVPN Static key V1-----
"> /tmp/static.key
ln -s /usr/sbin/openvpn /tmp/myvpn
/tmp/myvpn --dev tap0 --secret /tmp/static.key --comp-lzo --port 443 --proto tcp-server --verb 3 --daemon

– Save that to Startup Scripts
– Next, back in the blank box, we’ll place the code for the firewall and NAT:

iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Client
You will be creating 2 scripts and one key: openvpn.conf, startvpn.sh and secret.key. Place them in ~/Library/openvpn.

For your key, copy/paste your static.key from the dd-wrt router into a file named secret.key. Save the following two scripts as openvpn.conf and startvpn.sh, respectively. Don’t forget to make startvpn.sh executable.

#openvpn.conf
remote my.vpn.external.ip
port 443
dev tap0
secret static.key
proto tcp-client
comp-lzo

Now this part is kinda ghetto. I want to route all my traffic through the VPN but I was unable to get route-gateway and redirect-gateway to work inside of openvpn.conf. I decided to save time and just do it through the startup script instead.

kill -9 <code>ps aux | grep openvpn.conf |grep config| awk '{ print $2 }'
openvpn2 –config openvpn.conf –script-security 2 &
sleep 3

# Change your vpn server and internal subnet here
vpnserver=’my.external.vpn.ip’
vpngw=’172.20.0.1′

# If you use DHCP supplied DNS Servers, leave this as true
changedns=true

previousgw=cat ./gateway 2> /dev/null
currentgw=netstat -nr | grep '^default' | awk '{ print $2 }'

if [ -f ./gateway ]
then
# Set it back to the regular gateway
route delete default
route delete $vpnserver $previousgw
route add default $previousgw
rm ./gateway

echo gateway set back

if [ $changedns ]; then
networksetup -setdnsservers Ethernet empty
networksetup -setdnsservers Airport empty
echo dns reset
fi
else
# Set it to the VPN gw
route add $vpnserver $currentgw
sleep 7
route delete default
route add default $vpngw
echo $currentgw > ./gateway

# Tunnel your DNS Requests too.
if [ $changdns ]; then
networksetup -setdnsservers Ethernet $vpngw
networksetup -setdnsservers Airport $vpngw
echo new dns set
fi
fi

Check out this post on updating client-side DNS servers if you’d like to update all of your adapters instead of the ones most often used (Ethernet and Airport.)

Or something like that… Simple, right? ;)

Chrissy is a PowerShell MVP who has worked in IT for nearly 20 years, and currently serves as a Sr. Database Engineer in Belgium. Always an avid scripter, she attended the Monad session at Microsoft’s Professional Developers Conference in Los Angeles back in 2005 and has worked and played with PowerShell ever since. Chrissy is currently pursuing an MS in Systems Engineering at Regis University and helps maintain RealCajunRecipes.com in her spare time. She holds a number of certifications, including those relating to SQL Server, SuSE Linux, SharePoint and network security. She recently became co-lead of the SQL PASS PowerShell Virtual Chapter. You can follow her on Twitter at @cl.

Posted in Networking, OS X & iPhone, Security

Leave a Reply

Your email address will not be published. Required fields are marked *

*