Posts Tagged ‘dd-wrt’

Vyatta to DD-WRT: OpenVPN Site to Site

Sunday, July 17th, 2011

I recently changed my site-to-site VPN configuration.  Previously, I had been running my remote OpenVPN endpoints on CentOS with Quagga and OpenVPN installed.  Now that I have a couple Vyatta VM’s routing traffic on the internal network I’ve been wanting to use those as the VPN endpoints.  This simplifies things a big, and lets me remove Quagga from the two CentOS boxes.  I’ve also been wanting to switch my OpenVPN to bridge mode as opposed to routed mode.  OpenVPN doesn’t currently support IPv6.  Using bridge mode allows me to configure the L3 aspects outside of OpenVPN.

Rather than bridged the OpenVPN interface directly to one of the VLAN’s on each end of the tunnel (which would result in broadcasts traversing the WAN, and hosts on both locations being on the same Layer 3 network, not desirable in this case) I’m not actually “bridging” the VPN tunnel interfaces to other interfaces.  Instead, I created a bridge interface on each end of the connection with only the OpenVPN tunnel interface included in it.  I assigned the IP addresses on the bridge interfaces.  Here’s a diagram on how the interfaces are set up:

diagram2

I hadn’t used OpenVPN on Vyatta before, or OpenVPN in bridged mode, so this was a little new for me.  I generated a static key and copied it to all of the devices.  I have the OSPF costs on my internal Vyatta routers set so that one is always preferred.  (I also have that router preferred in VRRP, though this is unrelated to OpenVPN).  The Vyatta VM’s aren’t directly connected to the Internet, so I have OpenVPN listening on an internal address instead.  That internal address is then NAT’ed to a public IP on my edge router.  Ignoring the edge router, here’s a simplified diagram of the tunnels:

diagram1

Here is the configuration I used on the two Vyatta endpoints.  The only OpenVPN feature I’m using that Vyatta doesn’t have a configuration option for is the compression.  Thankfully, Vyatta let’s you manually specify OpenVPN configuration that they don’t support with “openvpn-option”.

intra-rtr-1:

bridge br0 {
        address 172.16.5.1/30
        description "L3 IF for APT site to site VPN"
        hello-time 2
        ip {
            ospf {
                authentication {
                    md5 {
                        key-id 1 {
                            md5-key myospfkey
                        }
                    }
                }
                cost 51
                dead-interval 40
                hello-interval 10
                priority 1
                retransmit-interval 5
                transmit-delay 1
            }
        }
        max-age 20
        priority 0
        stp false
    }
openvpn vtun0 {
        bridge-group {
            bridge br0
        }
        local-host 192.168.1.21
        local-port 1501
        mode site-to-site
        openvpn-option --comp-lzo
        protocol udp
        shared-secret-key-file /root/apt-rtr.secret
    }

intra-rtr-2:

 bridge br0 {
        address 172.16.6.1/30
        description "L3 IF for APT site to site VPN"
        hello-time 2
        ip {
            ospf {
                authentication {
                    md5 {
                        key-id 1 {
                            md5-key myospfkey
                        }
                    }
                }
                cost 49
                dead-interval 40
                hello-interval 10
                priority 1
                retransmit-interval 5
                transmit-delay 1
            }
        }
        max-age 20
        priority 0
        stp false
    }
 openvpn vtun0 {
        bridge-group {
            bridge br0
        }
        local-host 192.168.1.22
        local-port 1502
        mode site-to-site
        openvpn-option --comp-lzo
        protocol udp
        shared-secret-key-file /root/apt-rtr.secret
    }

I’m still using DD-WRT on the endpoint in my apartment. I’ll soon be switching this over to Vyatta as well, but until then I’m relying on some somewhat messy methods of using OpenVPN. I don’t trust the OpenVPN setup that the DD-WRT web GUI uses (for one, they use NAT’ing in the site-to-site connection…which makes no sense whatsoever), so I have a shell script on an attached flash drive that runs on the OpenVPN daemons. The included version of Quagga also does not work on DD-WRT (apparently they compiled it wrong), so I had to find an old statically compiled version. That’s what I’m using for OSPF on the DD-WRT box right now. For this new VPN setup, I just added a few lines to the shell script I already use for OpenVPN.

Anyway, here is the OpenVPN config on my DD-WRT router. It’s fairly simple. I actually have two separate OpenVPN daemons on the DD-WRT system. One that connects to each of my two internal Vyatta routers. The only thing different between them is the port that they connect to.

dev tap0
proto udp
remote my.vpn.endpoint 1501
resolv-retry infinite
nobind
secret intra-rtr.secret
comp-lzo

Here is the script I’m using on the DD-WRT router. It creates the bridge interfaces, and adds the OpenVPN interfaces to the bridge groups. It also assigns the IP’s on the bridge interfaces, starts Quagga, and starts the OpenVPN daemons. When starting the OpenVPN daemons, it also calls DD-WRT’s route down script, to make sure the NAT’ing that DD-WRT tries to do by default is removed from iptables.

openvpn --mktun --dev tap0
openvpn --mktun --dev tap1
brctl addbr br10
brctl addif br10 tap0
brctl addbr br11
brctl addif br11 tap1
ifconfig tap0 up
ifconfig tap1 up

ifconfig br10 172.16.5.2 netmask 255.255.255.252
ifconfig br10 promisc
ifconfig br10 up
ifconfig br11 172.16.6.2 netmask 255.255.255.252
ifconfig br11 promisc
ifconfig br11 up

zebra --daemon --config_file /jffs/opt/zebra.conf
ospfd --daemon --config_file /jffs/opt/ospfd.conf

( sleep 2 ; killall openvpn ; /tmp/openvpncl/route-down.sh ;
    /jffs/opt/ovpn --config /jffs/opt/openvpn-intra-rtr-1.conf --daemon) &
( sleep 3 ; killall openvpn ; /tmp/openvpncl/route-down.sh ;
   /jffs/opt/ovpn --config /jffs/opt/openvpn-intra-rtr-2.conf --daemon) &



Here’s the relevant OSPF configuration in Quagga on my DD-WRT router. Most of it’s fairly straightforward:

interface br10
 description L3 IF for site to site VPN - intra-rtr-1
 ip ospf authentication message-digest
 ip ospf message-digest-key 1 md5 myospfkey
 ip ospf cost 51
!
interface br11
 description L3 IF for site to site VPN - intra-rtr-2
 ip ospf authentication message-digest
 ip ospf message-digest-key 1 md5 myospfkey
 ip ospf cost 49
router ospf
 ospf router-id 192.168.17.1
 network 192.168.5.0/24 area 0.0.0.0
 network 192.168.6.0/24 area 0.0.0.0
 network 192.168.16.0/21 area 0.0.0.0
 area 0.0.0.0 authentication message-digest

I haven’t fully set up IPv6 yet. I’m planning on waiting until I replace my DD-WRT router with Vyatta to set all of that up. The version of Quagga I found that would run on DD-WRT doesn’t support OSPFv3. Vyatta does though.

My Experiences with DD-WRT

Wednesday, September 15th, 2010

I recently set up DD-WRT on my router at my apartment.  While it is quite a bit cheaper to buy a consumer class device and load DD-WRT on it, compared to purchasing a traditional business class device, there were several aspects of DD-WRT that I was disappointed with.  I’m not sure I can really recommend using DD-WRT in a business environment unless your needs are relatively simple.

Hardware

I am using DD-WRT on a Netgear WNR3500L.  I specifically bought this device to use with DD-WRT after researching what devices will work best with DD-WRT.  I was specifically looking for something that had enough memory to be able to use OpenVPN, and that could support multiple SSID’s / VLAN’s.  802.11n support wasn’t crucial for me, but it was a “nice-to-have”.  The WNR3500L does support all of those. 

I had no real problem flashing the firmware to install DD-WRT.  If I recall correctly, there was an interim firmware that has to be used first before you can upload the full version of DD-WRT.  As long as you follow the directions / tutorials from the DD-WRT site you should have too much trouble.

Site to Site VPN

My most important requirement was to set up a site-to-site VPN to another LAN that hosts my servers.  I use OpenVPN for a road warrior style VPN for when I’m working remotely, so I intended to use this as well for the site to site VPN.

The endpoint on my other LAN is a CentOS box.  Unfortunately, DD-WRT makes it difficult to use a custom OpenVPN config on the device.  A lot of things, like TLS Auth or having multiple remote endpoints (for reliability) aren’t really possible to do. 

Furthermore, the OpenVPN software is hard-coded to NAT the connection.  This means that the remote network you are connecting to cannot see your local network – only IP address on the VPN interface on the DD-WRT router.  This was a ridiculously bad decision on the part of the DD-WRT developers / maintainers.  In almost no conceivable circumstance would you want to NAT a site-to-site VPN connection.  It does this by calling the route-up.sh script in the /tmp/openvpncl directory. 

After hours of frustration, I eventually found a solution that works.  I added a startup command that disables the NAT’ing by running the route-down script, and then restarts OpenVPN without running the route-up script.

( sleep 20 ; killall openvpn ; /tmp/openvpncl/route-down.sh ; openvpn –config /tmp/openvpncl/openvpn.conf –daemon ) &

This works, but its still ugly in my opinion.  Due to the way DD-WRT works its not possible to actually edit the OpenVPN configuration file.  The changes won’t persist after a reboot.  This makes it much more difficult to customize and configure than it would be if it were just a normal Linux box with OpenVPN installed on it.

VLAN’s

Configuring the separate VLAN’s turned out to be a lot more difficult than I was expecting.  In my opinion, the naming scheme for interfaces and the web interface to add VLAN’s / associate interfaces with VLAN’s is inconsistent and illogical.  Wireless interfaces are treated completely different than wired interfaces and can’t be added to what DD-WRT considers the VLAN.  The wired interfaces are added to the VLAN, and then that resulting VLAN is bridged with the wireless SSID (s).  Complicating matters it the fact that the LAN port numbers as shown by DD-WRT may or may not be the in the same order as they are on the device. 

Here is a diagram showing how the physical interfaces, VLAN’s and bridges are connected in my example:

image

This screenshot below shows the interface for adding SSID’s.  Note, for SSID’s to be assigned to different VLAN’s each SSID has to be set to be bridged.  The wireless security tab is where you can configure the authentication / encryption mechanism for each SSID. 

image

Here is the interface for adding LAN ports to VLAN’s.  Note the inability to add a wireless SSID to a VLAN.  Also note the “Assigned to Bridge” column – the “bridge” that the VLAN is assigned to here has nothing to do with the bridges configure in the next screenshot.

image

 

This is the place that you connect the wired VLAN’s to the wireless SSID’s.  Then you put an IP on the resulting bridge interface.  (The IP on the default bridge, br0 is configured on the Basic Setup tab).    A couple items of confusion to pay attention to here.  First, the name “Bridge 0″ is not related to the interface name “br1″.  Secondly, if the SSID’s are set to be bridged, they will all be bridged to br0 by default.  You only have to add bridge assignments for VLAN’s / SSID’s that you don’t want to be bridged to br0.

image

A little further down on this same page is where the WAN VLAN assignment (VLAN 2 by default) is configured, along with the DHCP service offered for non-default bridge interfaces is setup.

image

Capturing Traffic with tcpdump

The WNR3500L has a USB port.  With a flash drive, you can add some persistent storage to DD-WRT.  After formatting and mounting the flash drive I installed ipkg so I would be able to install additional software on the flash drive.  The DD-WRT site has a good explanation of how to do this here.

From time to time, I find it useful to enable traffic capture on the router for troubleshooting.  I was able to install tcpdump through ipkg on the flash drive.  I can run tcpdump to dump traffic to a file on the flash drive.  Then, I can transfer the resulting file back to my computer via SCP and open it up with Wireshark to analyze it. 

Issues: Routing Daemon

For me this was extremely disappointing.  The quagga routing software that comes with DD-WRT will not function.  I found a post on the DD-WRT forum that explained this was because quagga was compiled incorrectly in this version of DD-WRT.  As far as I know this has not yet been fixed.  To me, the routing software is one of the most important aspects of a router.  This is something that should have been tested before the firmware was released.  The fact that it was not, makes me question how much I can really rely on DD-WRT.  If something this significant could slip through the cracks, what else have they messed up?

So instead of using OSPF over the site-to-site VPN to easily tell my other LAN how to reach this site, I have to add static routes on both ends.  This is pretty annoying and shouldn’t be necessary.  In a larger environment this would be a show-stopper.

Other Stuff

One feature I do really like is the Wake-On-LAN support.  You can easily add a computer on the network to a list of Wake-On-LAN hosts that you can remotely start with the click of a button.  With this, I can leave my desktop turned off, saving power, but easily start it up if I need to remote in to it. 

image

DD-WRT uses DNSMasq by default for providing DHCP and DNS forwarding service.  In my environment, I need a couple internal domains to be resolved by DNS servers across the site-to-site VPN.  This is easy enough to do with DNSMasq, by specifying additional options in the DNSMasq section of the Service tab.  In the example below, DNS requests for the two domains specified will be forwarded to one of the two servers specified for each. 

server=/internal-domain.com/IP-of-DNS-Server-1
server=/internal-domain.com/IP-of-DNS-Server-2
server=/internal-domain2.com/IP-of-DNS-Server-1
server=/internal-domain2.com/IP-of-DNS-Server-2

I have not tried updating to a newer version of the DD-WRT firmware.  However, from reading the DD-WRT wiki, it sounds like its not possible to upgrading without clearing the configuration settings and starting over.  To me, this seems like a pretty serious issue as well.  It’s taken quite a while to set everything up and find workarounds for some of the limitations of DD-WRT.  To have to do that all over again when I update the firmware would be a nightmare.  On Cisco IOS devices, you can easily use the same configuration on different versions of IOS, provided the new image supports all of the features used in the configuration.

In summary, while I was eventually able to get DD-WRT to work well enough for me, I can’t really recommend it.  It has a lot of potential, but a lot of the features really need to be polished up before a business can rely on them.  The interface for managing VLAN assignments for example, seems to be an afterthought rather than a primary focus of the device.  Businesses that need these features would probably be better off purchasing one of the Cisco 800 series routers.  While the Cisco hardware is more expensive and some of Cisco’s practices are maddening (like charging for access to updated images), it’ll still be cheaper when you factor in the time to get it up and running.  Configuring VLAN’s, site-to-site VPN’s, etc, on a Cisco router will take much less time than it does with the DD-WRT firmware.

Copyright 2009 Simpliciti Solutions