I spent too much time trying to get OpenVPN fully working on my DD-WRT router. All the documentation I found was either outdated or seemed overly complicated given the GUI options available in my build. This post is my attempt to document a full and working configuration of an OpenVPN server on a DD-WRT router.

My router is a Linksys WRT1900AC v2 running DD-WRT v3.0-r29048 std.

When looking for documentation this thread on the DD-WRT forums gave me the idea that it should in fact be easier than most documentation states. And it basically is!

These are the catches that added complication to the configuration:

Bridged TAP mode isn’t supported on iOS necessitating TUN for me

DNS doesn’t push to clients out of the box

TUN setups need a NAT rule to access the Internet via VPN

Below are steps to get things working as per my setup. The details really aren’t critical as long as they match within your config and between your server and clients. My LAN is 192.168.166.0/24 (netmask 255.255.255.0) so in theory all you should have to do to get things up is replace that network with yours in the steps below.

1.) Create your certs and keys following the official instructions here. Generating these isn’t specific to DD-WRT so there are plenty of resources available. I’d say generate more than you need so you won’t need to revisit if you need more — generation is a bit of a pain.

2.) Configure settings in “Services” > “VPN” as below.

OpenVPN: Enable

Enable Start Type: WAN Up

WAN Up Config as: Server

Server Server mode: Router (TUN)

Router (TUN) Network: 192.168.88.0

192.168.88.0 Netmask: 255.255.255.0

255.255.255.0 Port: 1194

1194 Tunnel Protocol: UDP

UDP Encryption Cipher: AES-256 CBC

AES-256 CBC Hash Algorithm: SHA1

SHA1 Advanced options: Yes

Yes TLSCiphter: No

LZO Compression: Yes

Yes Redirect default Gateway: Disable (I have this disabled so I can choose on the client side whether or not to route all traffic over the VPN).

Disable (I have this disabled so I can choose on the client side whether or not to route all traffic over the VPN). Allow Client to Client: Enable

Enable Allow duplicate cn: Disable

Disable Tunnel MTU setting: 1500

1500 Tunnel UDP Fragment:

Tunnel UDP MSS-Fix: Disable

Disable CCD-Dir DEFAULT file :

: Client connect script:

Static Key:

PKCS12 Key:

Public Server Cert: Paste yours in

Paste yours in CA Cert: Paste yours in

Paste yours in Private Server Key: Paste yours in

Paste yours in DH PEM: Paste yours in

See below:

If you want to resolve DNS names over the VPN you will need to add the below lines to “Additional Config.” If this isn’t the case you need no further configuration on this page.

push “dhcp-option DNS 192.168.88.1”

push “dhcp-option DOMAIN HOME”

push “route 192.168.166.0 255.255.255.0”

Here’s how it looks in the DD-WRT GUI:

Here’s a breakdown of what’s going on:

A route is pushed to clients so that they will go to DD-WRT for requests on the LAN network (192.168.166.0/24 for me).

The local DNS server at 192.168.166.1 is pushed to clients so they can make queries on the server’s network.

The domain is specified so hostnames will resolve without specification.

At this point you can click “Apply Settings”

4.) If you are using DD-WRT as a DNS server you’ll need to tell DNSMasq to listen for requests on the interface your VPN clients will query on. To do this you’ll need to figure out what interface that is. You can find this in the GUI by clicking “Setup” > “Advanced Routing” > “Routing Table.” In there you’ll see a route that specifies the tun adapter you are using.

For me:

Take that piece of information and navigate to “Services” > “Services.” Scroll down to “Additional DNSMasq Options” and enter

interface=tun#

where # is the number you pulled from routing table.

This is how it looks for me:

5.) At this point VPN clients exclusively have access to the LAN due to the lack of a NAT rule. Navigate to “Administration” > “Commands,” click “Edit” in the “Firewall” commands and add

iptables -t nat -A POSTROUTING -s 192.168.88.0/255.255.255.0 -j MASQUERADE

After clicking “Save Firewall” you should see your rule, see below:

Here’s the breakdown of what’s going on:

iptables is the program that does packet filtering in Linux.

The -t nat argument and parameter specifies that we will be working with the NAT table in iptables.

The -A POSTROUTING argument and parameter appends the rule to the POSTROUTING processing chain.

The -s argument and parameter filters the rule to apply to packets coming from our VPN network. These need to match the network you specified in step 2 (iptables will accept either a netmask (e.g. 255.255.255.0) bitmask (e.g. /24)).

-j MASQUERADE tells iptables to masquerade the packet as coming from the router itself — this is the part that makes the NATing happen.

Finally you’ll need your client side config. I’m using this:

remote private.veryprivate.superprivate;) 1194

client

dev tun

proto udp

resolv-retry infinite

nobind

persist-key

persist-tun

cipher aes-256-cbc

float

tun-mtu 1500

ca ca.crt

cert client0.crt

key client0.key ns-cert-type server

comp-lzo

verb 3

You’ll need to add your own target after remote.

If you want all traffic to go over the VPN just add:

redirect-gateway def1

As you can see things are basically default and matching my server settings.

That’s it!

Hopefully this helps somebody!