I wanted to set up OpenVPN, to protect myself from Firesheep when web browsing from the local free WiFi.  It is almost easy, but there are a few non-obvious points.  I won't cover setting up the keys and certificates, because that is well documented elsewhere and it works as documented.  This is for DD-WRT v24-sp2 (08/12/10) mega.

In my case, I have two routers: A wired router connected to the Internet, and a wireless router, which is connected to the wired router via Ethernet.  I'm going to get VPN working on the wireless router, and then I'll turn down the wired router and replace it with the wireless router.  I recommend this route.  You really want to work out your VPN from inside your LAN before you put it outside your LAN.

  • Turn off the firewall on your router. 
    • There's a checkbox on the DD-WRT Security->Firewall screen. 
    • This is to simplify, and allow you to focus strictly on one source of errors at a time.
  • On the DD-WRT Services->VPN screen:
    • Paste the content of your certificate authority certificate (ca.crt) into the "CA Cert" field.
    • Leave Certificate Revoke List empty.
    • Paste the content of your server certificate (server.crt) into the "Public Client Cert" field.
      • This is poorly named.  It should be named "Server Cert."
    • Paste the content of your server key (server.key) into the "Private Client Key" field
      • This is poorly named.  It should be named "Server Key."
    • Paste the content of your "Diffie-Hellman PEM" (dh1024.pem) into the "DH PEM" field.
      • If you care, PEM stands for "Privacy Enhanced Mail" format.
    • Paste the following into the "Open VPN Config" field.
server 192.168.8.0 255.255.255.0
dev tun0
proto udp
port 1194
keepalive 15 60
daemon
verb 3
comp-lzo
client-to-client
duplicate-cn  
tls-server
dh /tmp/openvpn/dh.pem
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem
  • Note that this will create a VPN where the network addresses are on the 192.168.8.* subnet. You might decide to change this, later. My advice is to use my values exactly, and later come back and tinker with it once you've got it working.

You can press the "Apply" button once you've filled in all of the fields mentioned above.


The client config file is below.  Again, just use my values for now.  Come back and tinker later.  The one thing you'll need to change is "192.168.9.1".  Change that to the IP address of your router.  I recommend using the LAN IP address of your router.  Eventually, you'll want to come back and make this work via the WAN IP address, but let's stay inside until we get things working.:

# Be the client, not the server
client

# Use any TUN (not TAP) device on the client.
dev tun

# The address of the VPN server.  1194 is the default port for OpenVPN.
remote 192.168.9.1

# Send ALL traffic via the VPN (except the link-level frames that your VPN tunnels inside)
redirect-gateway def1

# We don't care what interface or port we use on the client.
nobind

# These are described as 'Make the link resistant to connection failures, dealing with keeping
# connection alive through NAT and following the DNS name of the server if its IP address changes.'
keepalive 10 60
ping-timer-rem
persist-key
persist-tun

# Enable data link compression.
comp-lzo

# You can set this to a higher level, and you'll get lots of detail information.  It won't help.
verb 1

# --float tells OpenVPN to accept authenticated packets from any address, not only the address which was specified in the --remote option.
# Useful if you're using round-robin DNS.  Also useful if your server has a dynamic IP address which the ISP could change.
# I use float so I can connect from inside AND outside my router.
float

# Connect only to servers with the right certificate.
ns-cert-type server

# Certificate Authority certificate file used to "certify" other certificates.  Same CA file must be used on the client and the server.
ca ca.crt

# The client's certificate file.  Should be different on each client.  Public Client Cert.
cert client1.crt

# The client's private key.
key client1.key
  • Copy the Certificat Authority certificate to ca.crt, in your VPN client's config directory
  • Copy the client's certificat and private key to client1.crt and client1.key (respectively), in your VPN client's config directory.

Next, let's test and confirm that it really works.

  • Tell your client to connect to the server.  It should take about 10-15 seconds.  Different client's tell you about their success in different ways.  If you don't get a connection, look at the following:
    • Make sure you've got your keys and certificates in the right folders.
    • You might need to change "remote 192.168.9.1" or "server 192.168.8.0 255.255.255.0" in my config to match your network.
    • If all else fails, reboot your router and your client, and try again.  (Windows XP appears to need a reboot after installing OpenVPN.)
  • Assuming that you're connected, here are some things to test:
    • ping 192.168.8.1
      • This confirms that you can reach the server's VPN endpoint.  (Substitute your server endpoint, if you didn't use the 192.168.8.* subnet.)
    • ping 192.168.9.1
      • This confirms that you can reach your real, physical router's LAN IP.  (Substitute your router's LAN IP, if it is different.)
    • ping your-upstream-router-IP-here
      • This is the address of the router that is upstream from your router running DD-WRT and the VPN.  On my network, it is the wired-router-to-the-internet.  If your DD-WRT is directly connected to the internet, this is the gateway at your ISP.
      • This confirms that you can send traffic past the VPN's router.
    • ping mindspring.com
      • This confirms that DNS is working.
      • There is nothing magic about mindspring.com.  It is just the first ISP I ever used, so my fingers are "hard-wired" to ping them.  I've been pinging them since the days of Windows 3 and Trumpet Winsock for TCP/IP.
    • tracert your-upstream-router-IP
      • or "traceroute your-upstream-router-IP", depending on your operating system.
      • You're looking to confirm that the first step in the route is via the VPN (e.g. 192.168.8.1).  This shows that all traffic will go via your VPN.
    • Note: For the longest time, I found that using "redirect-gateway def1" made everything stop working. 
      • If I left it out, I could establish the VPN, but traffic didn't default to using the VPN. 
      • If I put it in, ALL traffic failed. 
      • I Googled for hours, and found many people with a similar problem, and lots of people trying to be helpful but not actually helping.
      • Disabling the firewall on my router 'solved' the problem.  This is why I recommend disabling the firewall.  It just makes one less thing to debug.  You WILL want to re-enable it before you connect it to the outside world.


Some suggested tweaks, once everything above is working:

  • Re-enabling your firewall:
    • Go to DD-WRT Security->Firewall, and re-enable the firewall.
    • Go to DD-WRT Administration->Commands, and past the following:
iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT
iptables -I FORWARD 1 --source 192.168.8.0/24 -j ACCEPT
  • If you didn't follow my advice to use my config exactly, you'll have to substitute your VPN's subnet for 192.168.8.0.
  • Press the "Save Firewall" button.
  • Go back to "here are some things to test" above, and connect and confirm that your VPN still works, now that you've enabled the firewall.  (You're still inside your router.  Remember -- deal with one source of trouble at a time.)
  • Now it is time to make this work from outside the router.
    • Edit your VPN client's config file and change "remote 192.168.9.1" to "remote your_external_ip_address 1194"
    • Re-establish your VPN connection.
    • Go back to "here are some things to test" above, and connect and confirm that your VPN still works, now that you're using the external IP.
  • You might want to set up ad-blocking on your router.  I used a simplified (customized) edition of the script from http://hotfortech.wikispaces.com (Basically, I removed the automatic updates of nvram.)
    • scp the modified disable_ads.sh to root@router:/jffs/etc/config/disable_ads.startup
    • scp pixelserv to root@router:/jffs/dns/pixelserv
    • ssh to the router, and run /jffs/etc/config/disable_ads.sh.  You want to ensure that this runs error-free before you reboot your router, or you could end up with a brick.
    • Add these lines to "Additional DNSMasq Options" on DD-WRT Services->Services:
      • conf-file=/jffs/dns/dnsmasq.adblock.conf
      • addn-hosts=/jffs/dns/dlhosts
  • MORE TO FOLLOW