I’ve recently purchased an Edgerouter PoE from Ubiquiti, which is a great deal regarding its price and performance. The only caveat was related to the lack of native support for load balancing and failover. This lack has been fixed with the release of the 1.4.0 firmware, which embeds a load balancing functionnality with native connection tracking.
For this example, I’ll take a generic scenario of a dual WAN setup, in a failover configuration with some policy routes, as we assume some ISP specific services are not available from the internet (e.g. administration interfaces, SMTP and DNS servers…)
Let’s also assume your ISP CPEs are configured in bridge mode. To show all the potential of the router, the IP address we’ll get from ISP 1 is dynamic and the one from ISP 2 is static, but both are acquired from ISP’s DHCP server (yes, my ISP are serious people, and they don’t use PPPo[E|A] ^.^).
I also use an internal autonomous DNS server to avoid unreachability delays during failover, and to have a trusted DNSSEC anchor. You will find below the schema for this scenario. The fqdn and IP addresses in this scenario have been changed to protect the innocents.
To begin with, set up your 3 interfaces on the router, the dhcp on the inside part, and the DNAT rules.
interfaces { ethernet eth0 { address dhcp description ISP_1 duplex auto poe { output off } speed auto } ethernet eth1 { address dhcp description ISP_2 duplex auto poe { output off } speed auto } switch switch0 { address 192.168.0.254/24 switch-port { interface eth2 interface eth3 interface eth4 } } } service { dhcp-server { disabled false hostfile-update disable shared-network-name Home { authoritative disable subnet 192.168.0.0/24 { default-router 192.168.0.254 dns-server 192.168.0.252 lease 86400 start 192.168.0.1 { stop 192.168.0.50 } } } } } nat { rule 5000 { description ISP_1_NAT log disable outbound-interface eth0 protocol all type masquerade } rule 5001 { description ISP_2_NAT log disable outbound-interface eth1 type masquerade } }
Next, we’ll setup the load balancer to use ISP1 as our primary access and ISP2 as our failover access. I decided to change some of the check parameters to show you how powerful the tool is. As we are in a failover setup, I won’t use the weight command, which you would use for load balancing scenarios, to adjust the percentage of traffic you’d like to send to the corresponding interface.
load-balance { group lb-output { interface eth0 { route-test { count { failure 3 success 4 } interval 5 type { ping { target 203.0.113.42 } } } } interface eth1 { failover-only } } }
As told at the beginning of this article, the load balancer will take care of tracking and marking the connection, to avoid that a current session gets in and out by different IP addresses. This is especially useful if you decide to use SNAT rules. As shown above, I decided to check ISP 1 connectivity against a specific IP address, but by default, the equipment will run the check against « ping.ubnt.com ».
Next, we’ll configure the fwr-lbalance firewall modifier group to set the policy routes. This firewall modifier will be used to let the trafic through the load balancer « lb-output », expect for:
- RFC1918 networks which we will route through the main routing table.
- 192.0.2.129 which is only reachable via ISP 1 (we’ll set up the target VRF table 10 for this case).
- 198.51.100.192/28 which is only reachable via ISP 2. (we’ll assume our gateway is 198.51.100.62, and we’ll set up another target VRF table 20 for this case).
Edit: ubnt-stig advised me to use a firewall group to define the RFC1918 in the comment, so you will find an updated version below.
And here is the associated configuration:
firewall { group { network-group RFC1918 { network 10.0.0.0/8 network 172.16.0.0/12 network 192.168.0.0/16 } } modify fwr-lbalance { rule 1 { action modify destination { group { network-group RFC1918 } } modify { table main } } rule 100 { action modify destination { address 192.0.2.129 } modify { table 10 } } rule 200 { action modify destination { address 198.51.100.192/28 } modify { table 20 } } rule 500 { action modify modify { lb-group lb-output } } } } protocols { static { table 10 { interface-route 0.0.0.0/0 { next-hop-interface eth0 { } } } table 20 { route 0.0.0.0/0 { next-hop 198.51.100.62 { } } } } }
Now, you need to tell the router to apply the firewall modifier instance to your internal interfaces:
interfaces { switch switch0 { address 192.168.0.254/24 firewall { in { modify fwr-lbalance } } switch-port { interface eth2 interface eth3 interface eth4 } } }
And finally, you’re done! Your dual wan setup is operationnal. Now you can configure SNAT rules for your publicly available services. If you want to use different a different load balancing policy, create another load-balancer group with the appropriate settings, and add a new rule into the firewall modifier group. Before exiting configuration mode, don’t forget to commit the configuration, and to save the configuration if it fits your requirement.
Edit: On the following screenshot, you can see the output of the load-balancer status commands.