Saturday, January 30, 2021

EdgeRouter Failover Configuration with Partial IPv6

I am in that fortunate first world situation to have two Internet connections wired to my humble abode. One is fast, and the other is pretty slow by modern standards. I considered getting rid of the slow connection, but I got a killer lifetime deal on the price, so it hardly seems worth getting rid of it.

My EdgeRouter supports failover so I figured I would take advantage of the second Internet connection and add a some redundancy to my home network. I wanted to bias things in favor of the faster connection, so it was important to ensure that I was only on the slower connection whenever the faster connection was unavailable. The faster connection also supports IPv6, which I wanted to retain as much as possible.

The basic failover configuration is simple enough that you can use one of the build-in Wizards in the EdgeMAX web UI to set it up. 

 

To ensure that the secondary connection only stands-in when the primary connection is unavailable, simply check this box:

In the EdgeOS config, this sets a failover priority value of 100 on the eth0 interface (the fast connection) and 60 on the eth1 interface (the slow connection). Your mileage may vary, but my experimentation showed that it only took six seconds to fail over to the slow connection, and about 40 seconds to fail back to the fast connection.

This particular configuration is quick and easy, but it omits IPv6, so that part requires some hand tweaking and a few compromises in my situation.

The intention behind IPv6 is that everything on the Internet gets a unique address. In contrast, IPv4 simply does not have enough addresses to go around, so the normal approach is to use a DHCP server to hand out RFC 1918 addresses to stuff inside of your private network.

Supporting IPv6 is great for the health of the Internet, but it complicates things when you want to set your SOHO network up for redundancy. When you failover, your alternate ISP does not recognize the IPv6 address range assigned to all of your devices, so everything stops communicating until each device updates their IPv6 address. In contrast, private IPv4 assignments are typically translated at your firewall, so nothing is required on the client side when you failover.

To fix this problem with IPv6 we have a few tools at our disposal NPTv6NAT66, and ULA. I agree with many other voices on the Internet that NAT66 is a fundamentally broken hack and should not be used. There are privacy concerns with NPTv6, but RFC 4941 seems to address most (all?) of them. ULA solves the problem that RFC 1918 solves with private addresses, and is probably not a significant factor in any SOHO failover design like this.

If I had two connections that supported IPv6, I would probably figure out how to get NPTv6 working, but since I only have one, I really just need to accept a minor compromise. If I choose to support IPv6, I have to accept that I will not have any IPv6 support during a failover. I have no problem with this compromise because we are still in the IPv6 transition phase and virtually everything is available via IPv4. I expect that applications sending traffic over an IPv6 interface will more or less transparently start using the IPv4 interface.

To add IPv6 support to the EdgeOS failover configuration, you can manually add the following sections to support an IPv6 firewall and a DHCPv6 prefix designation.

The firewall configuration (which goes into the firewall section) should look something like this:

    ipv6-name WANv6_IN {
        default-action drop
        description "WAN inbound traffic forwarded to LAN"
        enable-default-log
        rule 10 {
            action accept
            description "Allow established/related sessions"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid state"
            state {
                invalid enable
            }
        }
    }
    ipv6-name WANv6_LOCAL {
        default-action drop
        description "WAN inbound traffic to the router"
        enable-default-log
        rule 10 {
            action accept
            description "Allow established/related sessions"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid state"
            state {
                invalid enable
            }
        }
        rule 30 {
            action accept
            description "Allow IPv6 icmp"
            protocol ipv6-icmp
        }
        rule 40 {
            action accept
            description "allow dhcpv6"
            destination {
                port 546
            }
            protocol udp
            source {
                port 547
            }
        }
    }

 And this gets added to the eth0 interface configuration:

        dhcpv6-pd {
            pd 0 {
                interface switch0 {
                    host-address ::1
                    prefix-id :1
                    service slaac
                }
                prefix-length /60
            }
            rapid-commit enable
        }

Important Note: The /60 prefix length is provider specific. If you cannot get an IPv6 grant from your provider, you may need to change this value.

And finally, be sure to add the new IPv6 firewall labels to your eth0 interface firewall configuration to bring it all together:

        firewall {
            in {
                ipv6-name WANv6_IN
                name WAN_IN
            }
            local {
                ipv6-name WANv6_LOCAL
                name WAN_LOCAL
            }
         }

Load that configuration back to EdgeOS and you should be all set after a reboot.