TL-WDR3600If you’ve always wanted your WiFI router to do more, but the software seems too limited, don’t spend hundreds on a router from the likes of Zyxel or Sonicwall. You may be able to supercharge your router with a freely available firmware called DD-WRT. I’m not going to cover the basics of DD-WRT as there are tons of resources out there. But my business network utilizes a few things that have a fairly advanced configuration and after some experimentation, I wanted to share what I did to get a $60 router performing like one costing hundreds more.

I upgraded my old Asus WL-520GU (Broadcom based) router to a new TP-Link TL-WDR3600 (Atheros based) at my business and it was a bit of an effort to get the same functionality I had. The Broadcom chips were almost universal in SOHO routers, so their support is widespread and DD-WRT’s web interface supports them widely. However, chips from Atheros have gained a LOT of traction of late and due to differences in how they operate, the DD-WRT web interface doesn’t always support everything. So you have to do some command line tweaking to get exactly what you want. The TP-Link routers are wonderful because they have a ton of memory (128MB) and large flash chips (8MB) for loading firmware with more advanced features. I needed tagged and port based VLAN support in addition to enabling OpenVPN. For the longest time, Atheros based routers only supported tagged VLANs. But now their newer chipsets support both. So I wanted to see if I could upgrade my router without changing anythign else in my network configuration.

Getting the exact config working was a challenge and I had to do lots of trial and error along with referencing a LOT of forum posts to finally reach the correct set of configuration options. So figured I’d share…

This was all done on v23082 dd-wrt. While the main website suggest much older firmware for most routers, the most recent bug fixes and features are added to the ‘BrainSlayer Builds’, which are released intermittently by the lead developer of DD-WRT.

VLANs
I have 5 networks at my business run through a 24 port smart switch and other smaller switches farther out. I use a combination of port based and tagged VLANs. I could have gone to all tagged, but one high power AP was wired to the router and I didn’t feel like running it to the switch so… I made my life difficult for fun.

Here is the setup:

Private LAN 192.168.5.1
Public WiFi 192.168.6.1
Repair LAN 192.168.7.1
VoIP 192.168.8.1
Partner LAN 192.168.10.1
  • 5.1 is the main network. It’s not tagged and is the default LAN on the smart switch (I use port configurations in the smart switch to block the traffic from going elsewhere) Not ideal and I should do it ‘right’ but for now… That’s how it worked. The router’s wireless radios tie directly to Private LAN and are WPA2/AES encrypted. If I had wanted them on a different vlan, I’d have had to use a bridge to remove them from ‘vlan1’ and put them onto another vlan.
  • 6.1 (vlan7) is Public WiFI through a Ubiquiti Nano so it was port based due to laziness and desire to try both methods. When I upgraded the router, the LAN cable was right there and so I left it at the router vs going to the smart switch (tagged)
  • 7.1 (vlan3) is the LAN for my repair benches so there’s all sorts of nasty traffic on it. All wired.
  • 8.1 (vlan4) is my VoIP network. No real NEED for this to be segmented, but it’s an artifact from when I ran asterisk and why make life simple?
  • 10.1 (vlan6) is a partner network for a few people subletting a small section of our building.

So all the VLANs are isolated and share our single Internet link.

I tried every possible combination I could to get tagging to configure properly via the web mgmt interface. I can’t say it’s broken because once I got into the command line stuff, I realized maybe I never had the exact combination I needed (the vlans need to be tagged to eth0 from what I can tell). But with all the eth0.x interface identifiers and unsure about the need for bridging (some people did VLANs via bridges, but I never had to do that before), I wasn’t clear on HOW the web interface wanted you to specify certain parameters. So if the GUI way won’t work, on to the command line! I found a post using command line startup stuff, and it worked! After some tweaks here is what I did:

First you need to get the router properly configured, which requires a startup script (Administration -> Startup). These commands will get run every time the router boots and will lay the groundwork for the VLANs:

# Enable VLANs against the eth0 switch internally
swconfig dev eth0 set enable_vlan 3
swconfig dev eth0 set enable_vlan 4
swconfig dev eth0 set enable_vlan 6
swconfig dev eth0 set enable_vlan 7
# Assign ports to vlans. Port 1 internally is WAN port. 2-5 are LAN ports 1-4 on the back)
# Keep Ports 1, 3, and 4 on main VLAN/LAN. Tag the trunk for later
swconfig dev eth0 vlan 1 set ports “0t 2t 4 5”
# Assign smart switch trunk to other VLANs for tagging.
swconfig dev eth0 vlan 3 set ports “0t 2t”
swconfig dev eth0 vlan 4 set ports “0t 2t”
swconfig dev eth0 vlan 6 set ports “0t 2t”
# Assign Public WiFI AP port to it’s VLAN. No tagging.
swconfig dev eth0 vlan 7 set ports “0t 3”
swconfig dev eth0 set apply
vconfig add eth0 3
vconfig add eth0 4
vconfig add eth0 6
vconfig add eth0 7
# Create VLAN interfaces and assign network IPs (which you redo later, but…)
ifconfig vlan3 192.168.7.1 netmask 255.255.255.0
ifconfig vlan4 192.168.8.1 netmask 255.255.255.0
ifconfig vlan6 192.168.10.1 netmask 255.255.255.0
ifconfig vlan7 192.168.6.1 netmask 255.255.255.0
# Bring the interfaces up…
ifconfig vlan3 up
ifconfig vlan4 up
ifconfig vlan6 up
ifconfig vlan7 up

So we create some easy to identify vlan interface identifiers and assign various ports to them. vlan1 is the main network, so we left everything there EXCEPT port 3 (#2 on the back of the router) which is the port based VLAN for Public Wifi. Port 2 (labelled #1 on the back) is the trunk to the smart switch, carrying tagged AND untagged traffic. I didn’t need the tag option (2t) for vlan1, but put it there anyway in case I decided to tag everything like a good network dweeb. But I wanted to see if tagged and untagged would work so there we go. I assigned the switch trunk port to all the other VLANs except vlan7, which is the Public WiFi VLAN (it used to be VLAN 2 in the broadcom router, but Atheros changes the vlan setup and vlan2 is the WAN port. So we made it vlan7 and updated the smart switch config)

Yes my vlan numbering is bizarre. Part artifact from Broadcom (For them the WAN port was vlan5. With Atheros it’s vlan2) and I should have just made the vlan number match the LAN block number for simplicity, but I’m OCD in a weird way and was too lazy to update everything in the smart switch. So I left the VLAN IDs the same and changed just that one.

Save the Startup Scripts. You also want to isolate your VLANs, so you need a couple things in your firewall script:

# Restrict RIP access from WAN
iptables -I INPUT -p udp -i vlan3 --dport 520 -j DROP
iptables -I INPUT -p udp -i vlan4 --dport 520 -j DROP
iptables -I INPUT -p udp -i vlan6 --dport 520 -j DROP
iptables -I INPUT -p udp -i vlan7 --dport 520 -j DROP

# Block all traffic between VLANs
iptables -I FORWARD -i vlan+ -o vlan+ -j DROP
iptables -I FORWARD -i vlan+ -o br0 -j DROP
iptables -I FORWARD -i br0 -o vlan+ -j DROP

# Allow VLANs to communicate with WAN (vlan2)
iptables -I FORWARD -i br0 -o vlan2 -j ACCEPT
iptables -I FORWARD -i vlan2 -o br0 -j ACCEPT
iptables -I FORWARD -i vlan+ -o vlan2 -j ACCEPT
iptables -I FORWARD -i vlan2 -o vlan+ -j ACCEPT

Save all this and reboot the router…

Now go to Setup -> Networking… For each new VLAN section that now appears, (3, 4, 6, and 7 in my case), Select ‘Unbridged’, enable NAT, and configure the LAN IP (192.168.x.1) and netmask (255.255.255.0). Don’t unbridge vlan1, eth0, or the athx networks (unless you need to like pulling the WiFi into a different LAN). Save.

If you need DHCP on the VLANs like I do, add them at the bottom. Select the vlan ID for each one that needs DHCP, set a start IP, the # of clients allowed, and a lease time. Apply and reboot. That’s it! Your networks should be working with tagged and untagged traffic pouring out of the trunk port.

Note – if you need additional DHCP options for your vlans, you can specify them in the DNSMasq options section of Services. I specify different DNS depending on the network (for some basic DNS filtering with OpenDNS). Just tag the option to the vlan:

dhcp-option=vlan3,6,208.67.222.222,208.67.220.220
dhcp-option=vlan7,6,208.67.222.222,208.67.220.220
dhcp-option=vlan4,6,8.8.8.8,8.8.4.4
dhcp-option=vlan6,6,8.8.8.8,8.8.4.4

Static Leases apply across all the DHCP instances, so the normal web mgmt stuff works there.

OpenVPN
One reason for upgrading my router? I wanted OpenVPN access to my business network. Chrome Remote Desktop works well for much of what I need, but having direct network access comes in handy too. After a bit of research I was able to get things working. Here are some decent pages dedicated to this:

http://www.dd-wrt.com/wiki/index.php/OpenVPN
http://goo.gl/leS8 (Excellent resource!)
http://www.howtogeek.com/64433/
https://community.openvpn.net/openvpn/wiki/Easy_Windows_Guide

Setting up OpenVPN overall is beyond the scope of this post – the above resources will give you the general idea. The key is properly creating your CA, server, and client certificates and copying them to your router config. Note that due to GMT time differences, your certs/keys may not work for up to a day. Easy fix? After you install OpenVPN on your computer, set the clock back one day and create your keys = no GMT issues. Then set it back once the certificates and keys are all created.

Under Services -> VPN, enable the OpenVPN server. The startup type probably is not critical – but I start the VPN stuff when the system boots vs when the WAN port comes online. Not sure it matters though. I left it as a daemon vs server. You copy in the appropriate Certificate/Key segments (not the other junk on top – only the BEGIN/END lines and the block of characters in between) into the four text fields. See the howtogeek article for exactly which key file goes into which form field.

The key to getting it working well is the Additional Config options and everyone had some things different. Here is what is working well for me for a bridged VPN:

mode server
proto udp
port 1194
dev tap0
# This will link me into my main LAN using a small slice of IPs I carved OUT of my DHCP pool
# Be sure to update your DHCP LAN settings so there is no overlap
server-bridge 192.168.5.1 255.255.255.0 192.168.5.251 192.168.5.254
keepalive 10 120
daemon
verb 3
# Prevents warnings and allows push route to work
script-security 2
client-to-client
# Unsure but this seemed to speed things up a bit. You have to configure your client for this too.
comp-lzo adaptive
# This gets the OpenVPN status tab working. Ports 5001 or 5002 did NOT work
management localhost 16
dh /tmp/openvpn/dh.pem
ca /tmp/openvpn/ca.crt
cert /tmp/openvpn/cert.pem
key /tmp/openvpn/key.pem

I use a bridged setup – which means the VPN ‘bridges’ to your existing LAN. It’s like your computer is there. Same network with an IP address as if you were there (though from a different slice of the DHCP pool). Another option is routed where you are linking two networks and route between them. Again out of this article’s scope. But bridging is the simple way and works for most cases.

You also have to add a couple things to your Startup Script under Administration in order to get the VPN network interface (tap0) active. You’re basically telling the router to link the VPN (tap0) into the main network bridge (br0) along with vlan1/ath0 (wired/wifi). Note it is possible to VPN into a VLAN (in theory – I have not tried), by creating a new bridge and adding tap0 and your VLAN to it. But for now – we’re going with a simple main LAN bridge:

openvpn –mktun –dev tap0
brctl addif br0 tap0
ifconfig tap0 0.0.0.0 promisc up

VPN has to come in from the outside, so we have to add the following to our firewall script:

# OpenVPN Access
iptables -A INPUT -i tap0 -j ACCEPT
iptables -I INPUT -p udp --dport 1194 -j ACCEPT

Reboot and configure your client installation according to the articles above. I got this working with much less hassle than I thought. Make sure you check EVERY box when installing OpenVPN so you get the easy-rsa and openssl tools. Otherwise the creation of your CA, certs, and keys won’t be possible. There are supposed to be sample configuration files installed when you install OpenVPN on Windows, but for some reason they didn’t install for me. Google will find them for you. Here is my client side .opvn file:

remote X.X.X.X 1194
client
dev tap0
proto udp
resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo adaptive

ca “C:\\Program Files\\OpenVPN\\config\\ca.crt”
cert “C:\\Program Files\\OpenVPN\\config\\mikesdv7.crt”
key “C:\\Program Files\\OpenVPN\\config\\mikesdv7.key”

ns-cert-type server

If you don’t have a static IP address, go to freedns.afraid.org and get a free Dynamic DNS account. This will give you a hostname that always points to your router and use that instead of the direct IP address. No need to pay $20/mon for a static IP.

Hopefully this helps some of you and if any experts out there have suggestions or improvements, by all means let me know! Things I still want to research/tweak/improve:

  • I’m pretty sure when I’m connected to my VPN, *all* my network traffic is going through the VPN, not just traffic meant for my business LAN. This is the nature of ‘bridged’ networking. I’d rather have only my business network traffic go over the VPN.
  • I’m still not sure if adaptive is the best option for LZO compression and if it’s even working.
  • I really should update my smart switch and config so vlan6 = 192.168.6.x and so on.

UPDATE! I learned a little bit of a lesson. Being OCD, I like to have DHCP reservations for all my machines with nice recognizable names in the DD-WRT status screens. So I create lease records for everything. Well now that I have OpenVPN working great, I wanted to create hostnames for them as well. So not thinking this through (OpenVPN doesn’t USE DNSMasq for DHCP), I created two leases for the OpenVPN client MAC addresses and IP addresses. As soon as I saved them, the router CPU pegged at 100%. Thankfully it was a ‘nice’ process, so the router continued to pass traffic just fine, but the web GUI slowed to a crawl. Eventually I was able to get the Services tab to load and remove the two entries. Once I did that and clicked Apply? CPU load returned to it’s normal 0.01 self. So word to the wise – don’t do this!

UPDATE #2: I’ve been working on turning Raspberry Pi’s into small Network Sentinel/OpenVPN devices. While researching and configuring them, I realized I had overlooked an important feature of OpenVPN. Opening any port to the Internet is risky, especially if it will respond to probes. While OpenVPN is very secure with few vulnerabilities found for it, it has a feature called TLS Auth/HMAC Authentication that can harden it even more against attacks. It requires the generation of a 2048-bit key that is stored on both the server and client sides. When you initiate a connection to OpenVPN, the first thing it will require is this key. It the client does not present the key, the port stops responding to traffic. This ensures scan/vulnerability scans are shutdown immediately. Setting it up is very easy. First, you need to create the key on either the client or server:

  • openvpn –genkey –secret ta.key

Open the key file and copy all the text within it. Paste it into the TLS Auth Key field in DD-WRT (Services->VPN). Then add the following to the Additional Config section:

  • key-direction 0
  • tls-auth /tmp/openvpn/ta.key

Click Apply to save. Now copy the ta.key file into your computer’s OpenVPN config directory and add the following to the appropriate ovpn file:

  • key-direction 1 # Enables tls-auth HMAC protection
  • tls-auth “C:\\Program Files\\OpenVPN\\config\\ta.key”

Now when you initiate a connect, the server will require this key be presented before anything else. Otherwise it won’t respond. An excellent safety measure.

UPDATE #3: If you have an OpenVPN setup, it IS affected by the Heartbleed OpenSSL vulnerability. So you’ll need to respin your certificates (I’d suggest just starting from creating a new CA and work your way down through the client certificates). However, if you had TLS Auth/HMAC enabled as outlined above in Update #2, you’re fine since this would have prevented anyone from pinging your server trying to get crypto info through the vulnerability. Just ensure OpenVPN and OpenSSL get updated to the latest releases. if you haven’t enabled TLS Auth – you really should. It was designed to prevent hackers from exploiting vulnerabilities like this.

UPDATE #4: My initial firewall rules relied on vlan1 being the primary LAN but, at least on this hardware, it turns out you have to use br0 in iptables for that. So I’ve updated the rules to account for that. See this post for additional information on vlan interface naming.