EdgeRouter - Dual WAN Load-Balance Feature

Overview


Readers will learn about the WAN load-balance feature between interfaces on the EdgeRouter, based on version EdgeOS v1.4.0 and later.  Versions of EdgeOS prior to v1.8.0 only supported 2 WAN interfaces, but in v1.8.0 you can have up to 8.

There are a few requirements for this type of configuration:

1) A load-balance section that defines the interfaces, and optionally ping targets, timer intervals, route-test, etc.
2) A firewall modify ruleset that defines the match criteria.
3) At least 1 LAN interface that has the firewall modify ruleset applied to it's firewall in.

Note: Before configuring load-balancing it is a good practice to 1st verify that both WAN interfaces are configured correctly with nat/firewall/etc.  Take one WAN interface down, verify LAN clients can access Internet. Then do the same with the other WAN interface. 

Minimal Configuration


Below is a configuration example that uses mostly default values (using "show" command while in configuration mode):

ubnt@ER-Pro# show load-balance 
 group WLB {
     interface eth0 {
     }
     interface pppoe0 {
     }
 }

ubnt@ER-Pro# show firewall modify 
 modify WAN_WLB {
     rule 10 {
         action modify
         modify {
             lb-group WLB
         }
     }
 }

ubnt@ER-Pro# show interfaces ethernet eth2
 description LAN
 address 192.168.16.1/24
 firewall {
     in {
         modify WAN_WLB
     }
 }

With this configuration all the traffic inbound traffic on eth2 will be subject to load-balance (default 50/50 per WAN). This configuration will also start up a watchdog thread for each WAN interface that pings www.ubnt.com every 10 seconds. If there 3 consecutive failures, all traffic will fail over to the other WAN interface.  Of course if you don't like those defaults, they can be configured.

 

Operation Command: Show


The first "show" command displays the "status" of the interfaces associated with the WAN Load-Balance Group.

ubnt@ER-Pro:~$ show load-balance status 
Group WLB
  interface   : eth7
  carrier     : up
  status      : active
  gateway     : 22.0.0.1
  weight      : 50
  flows
      WAN Out : 7451
      WAN In  : 0
    Local Out : 8854

  interface   : pppoe0
  carrier     : up
  status      : active
  gateway     : pppoe0
  weight      : 50
  flows
      WAN Out : 7566
      WAN In  : 0
    Local Out : 3904

The second "show" command displays "watchdog" related information, including status, failed pings, and ping gateway.

 

ubnt@ER-Pro:~$ show load-balance watchdog 
Group G
  eth7
  status: Running 
  pings: 98
  fails: 1
  run fails: 0/2
  route drops: 0
  ping gateway: ping.ubnt.com - REACHABLE

  pppoe0
  status: Running 
  pings: 27
  fails: 0
  run fails: 0/3
  route drops: 0
  ping gateway: ping.ubnt.com - REACHABLE

 Note: If your WAN interface is PPPoE, it's a good idea to not get a route from the pppoe server and instead add an interface route:

 

configure
set interfaces ethernet eth1 pppoe 0 default-route none
set protocols static interface-route 0.0.0.0/0 next-hop-interface pppoe0 commit save exit

Configuration Options


For those that want to tweak the default values, there are several configuration options (notes follow after the output)

 

load-balance {
	group <name> {
		interface <name> {
			route {
				default
				table <name>
			}
			weight <number>
			failover-only
			route-test {
				type {
					default
					ping {
						target <host>
					}
					script <name>
				}
				initial-delay <number>
				interval <number>
				count {
					success <number>
					failure <number>
				}
			}
		}
	}
}

Route Section

Under the "route" section, EdgeOS will by default try to determine the gateway to use for the interface. The gateway it picks will show up in "show load-balance watchdog". If it does find a default gateway or if you want to have control over the gateway, you can use PBR to define your own routing table, like so:

 

configure
set protocols static table <num> route 0.0.0.0/0 next-hop <gateway IP>
set load-balance group <name> interface <name> route table <num>
commit
save
exit

Route-test Section
Under the "route-test" section you can change the default behavior of the "watchdog route-test," according to the parameters below:

  • The "ping target" option allows you to decide which host to ping.
  • The "script" option let you completely decide whether the WAN interface should be considered active or inactive. The script will get called with 3 parameters (group name, interface name, and current status as either "OK" or "DOWN"). If the script exits with 0 then the route-test is considered good and any other value is considered a fail.

Note: Even though the watchdog timers are multi-threaded, it still would not be a good idea to have the script run for a long period of time. 

 

DNS

If you get your WAN address via dhcp or pppoe, then your ISP is likely giving you a dns-server that will only work with that WAN interface.  Load-balance needs all the name-server in /etc/resolv.conf to be able to be used by both WANs.  Both dhcp and pppoe have a option to ignore the ISP name-server:

 

configure
set interfaces ethernet ethX dhcp-options name-server no-update
commit
save
exit
configure
set interfaces ethernet ethX pppoe <num> name-server none
commit
save
exit

Of course then you'll need to add a global name-server for the system to use.

configure
set system name-server 8.8.8.8
commit
save
exit

Health Test

By default the system will use ping to determine if the WAN interface is up.  The default host that gets pinged is ping.ubnt.com however it make make more sense to ping someother host that is closer to you.  In addition if you use an address, then if removes dns from the equation.

configure
set load-balance group <name> interface <name> route-test type ping target 8.8.8.8
commit
save
exit

 

LAN-to-LAN Exclusion


The way the load-balance feature works is by creating new routing tables for the WAN interfaces to use.  That works great for LAN to WAN traffic, but we don't want to load-balance traffic that is going from LAN to LAN.  The easiest way to handle this is to create a firewall group with the LAN networks and add a rule to the "modify" ruleset to use the main routing table for those destitnations. Note: this rule needs to come before the load-balance rule.

 

configure
set firewall group network-group LAN_NETS network 192.168.0.0/24
set firewall group network-group LAN_NETS network 192.168.1.0/24
set firewall group network-group LAN_NETS network 172.16.0.0/24
commit
set firewall modify WAN_WLB rule 10 destination group network-group LAN_NETS
set firewall modify WAN_WLB rule 10 action modify
set firewall modify WAN_WLB rule 10 modify table main
commit
ubnt@WLB# show firewall modify 
modify WAN_WLB {
    rule 10 {
        action modify
        destination {
            group {
                network-group LAN_NETS
            }
        }
        modify {
            table main
        }
    }
    rule 20 {
        action modify
        modify {
            lb-group WLB
        }
    }
}
[edit]

Port Forwarding


We also don't want to load-balance port-forwarded traffic.  So add another rule to exclude the router's public address.  Since the public address might be dynamic, use the address alias.  In this case my port-forward rules go to pppoe0:

firewall {
    modify WAN_WLB {
        rule 10 {
            action modify
            description "do NOT load balance lan to lan"
            destination {
            group {
                network-group LAN_NETS
            }
            modify {
                table main
            }
        }
        rule 20 {
            action modify
            description "do NOT load balance destination public address"
            destination {
                group {
                    address-group ADDRv4_pppoe0
                }
            }
            modify {
                table main
            }
        }
        rule 30 {
            action modify
            modify {
                lb-group WLB
            }
        }
    }



Making sessions stay with the same WAN

Some website such as banks drop session when they see a different IP address. In version v1.7.0 a "sticky" feature was added to the load-balance feature such that the user can define which fields in the packets are used to hash to a given WAN interface. For example:

configure
set load-balance group G sticky source-addr enable
set load-balance group G sticky dest-addr enable 
set load-balance group G sticky dest-port enable
commit
save
exit

The sticky does mean that the weighting may not be as accurate as without sticky since session get locked to a given WAN. Over time and with enough flows it tends to even out.

 More examples:

- Multi WAN best practices - LINK.

- Simple dual WAN, but only use WAN2 for fail-over - LINK

- Restrict some devices to 1 WAN link unless fail-over - LINK.

- Restrict HTTPS traffic to 1 WAN link unless fail-over - LINK.

- Using a script to determine route health instead of ping - LINK.

- WAN load-balance breaks NAT hairpin and LAN to LAN - LINK.

- One LAN1 to WAN1, LAN2 to WAN2 with fail-over - LINK

- Run a script on failover - LINK.

- Load-balance and IPsec - LINK.

Powered by Zendesk