IPv6 on Ubnt EdgeRouter X with DIGI PPPoE

     

Basics

Ingredients:

Interfaces:

  • eth0, eth1, eth2, eth3: LAN, put into a virtual switch so that they behave the same way and don’t need individual configuration
  • eth4: WAN

Now you might be scratching your head: by default, eth0 is WAN, so why change it? First I didn’t understand that either, even though I saw it in a lot of the guides I read. After resetting the unit a few times I realized: it’s because by default, the ER-X can only be accessed from eth0. Naturally, you manage your routers from the LAN, so you have to unplug the WAN cable from eth0, plug the LAN cable into eth0, reconfigure the router, then plug the LAN cable back into eth1, then plug the WAN cable back into eth0 again. It’s a pain in the ass. So we might as well give up and use eth4 for WAN. This way we have a bunch of LAN ports in sequence, too.

For management, you gotta familiarize yourself with SSH, coz that’s how we can manage the router from the CLI, which will be absolutely necessary to get everything right. On Windows, I recommend the PuTTY client. If you’re on Linux, I bet you already know how to use SSH 😉

After logging in, you can query the current config with:

show configuration

If you want to change a setting, you need to enter configure mode first:

configure

After this, you’ll notice that the shell prompt changes from $ to #. Take note of this when you’re working in the CLI, it’s a useful little indicator.

When you’re finished with your settings, you can apply the changes:

commit

This will only store them until the next reboot, so if you also want them to be permanently saved, you also need to:

save

Then you can exit from configure mode:

exit

That’s pretty much it to get going with the router.

Useful Snippets

Ping over IPv6:

ping6 google.com

Restart PPPoE:

disconnect interface pppoe0; connect interface pppoe0

Display interface status:

show interfaces

Show PPPoE log continuously:

show interfaces pppoe pppoe0 log tail

Display PPPoE log file contents:

cat /var/log/vyatta/ppp_pppoe0.log

Reset to factory defaults:

cp /opt/vyatta/etc/config.boot.default /config/config.boot
reboot

Cleanup

I like clean solutions, so I recommend you to start by backing up your current config from the web UI, then doing a reset. It can be a single line of an old configuration option that breaks things for you, so instead of modifying an existing config, you should start from scratch, get IPv6 working, then feel free to add back your previous options one by one.

Make sure you have your PPPoE username and password at hand before doing the reset.

The other defaults you need to know:

Item Default value
IP 192.168.1.1
Interface eth0
Username ubnt
Password ubnt

After performing the reset, your configuration should look something like this:

interfaces {
    ethernet eth0 {
        address 192.168.1.1/24
        duplex auto
        speed auto
    }
    ethernet eth1 {
        duplex auto
        speed auto
    }
    ethernet eth2 {
        duplex auto
        speed auto
    }
    ethernet eth3 {
        duplex auto
        speed auto
    }
    ethernet eth4 {
        duplex auto
        speed auto
    }
    loopback lo {
    }
    switch switch0 {
        mtu 1500
    }
}
service {
    gui {
        http-port 80
        https-port 443
        older-ciphers enable
    }
    ssh {
        port 22
        protocol-version v2
    }
}
system {
    host-name ubnt
    login {
        user ubnt {
            authentication {
                encrypted-password ****************
            }
            level admin
        }
    }
    ntp {
        server 0.ubnt.pool.ntp.org {
        }
        server 1.ubnt.pool.ntp.org {
        }
        server 2.ubnt.pool.ntp.org {
        }
        server 3.ubnt.pool.ntp.org {
        }
    }
    syslog {
        global {
            facility all {
                level notice
            }
            facility protocols {
                level debug
            }
        }
    }
    time-zone UTC
}

Configuration

Spoiler

This is the full config that should work as a bare minimum:

firewall {
    ipv6-name WANv6_IN {
        default-action drop
        description "IPv6 packets from the internet to LAN and WAN"
        enable-default-log
        rule 10 {
            action accept
            description "Allow established and related packets"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid packets"
            log enable
            state {
                invalid enable
            }
        }
        rule 30 {
            action accept
            description "Allow ICMPv6 packets"
            log enable
            protocol icmpv6
        }
    }
    ipv6-name WANv6_LOCAL {
        default-action drop
        description "IPv6 packets from internet to router"
        enable-default-log
        rule 10 {
            action accept
            description "Allow established and related packets"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid packets"
            log enable
            state {
                invalid enable
            }
        }
        rule 30 {
            action accept
            description "Allow ICMPv6 packets"
            log enable
            protocol icmpv6
        }
        rule 40 {
            action accept
            description "Allow DHCPv6 client/server"
            destination {
                port 546
            }
            protocol udp
            source {
                port 547
            }
        }
    }
    ipv6-receive-redirects disable
    ipv6-src-route disable
    name WAN_IN {
        default-action drop
        description "WAN to internal"
        rule 10 {
            action accept
            description "Allow established/related"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid state"
            state {
                invalid enable
            }
        }
    }
    name WAN_LOCAL {
        default-action drop
        description "WAN to router"
        rule 10 {
            action accept
            description "Allow established/related"
            state {
                established enable
                related enable
            }
        }
        rule 20 {
            action drop
            description "Drop invalid state"
            state {
                invalid enable
            }
        }
    }
    options {
        mss-clamp {
            mss 1452
        }
    }
}
interfaces {
    ethernet eth0 {
        duplex auto
        speed auto
    }
    ethernet eth1 {
        duplex auto
        speed auto
    }
    ethernet eth2 {
        duplex auto
        speed auto
    }
    ethernet eth3 {
        duplex auto
        speed auto
    }
    ethernet eth4 {
        description "Internet (PPPoE)"
        duplex auto
        firewall {
            in {
                ipv6-name WANv6_IN
            }
            local {
                ipv6-name WANv6_LOCAL
            }
        }
        pppoe 0 {
            default-route auto
            dhcpv6-pd {
                pd 0 {
                    interface switch0 {
                        prefix-id :0
                        service slaac
                    }
                    prefix-length /64
                }
            }
            firewall {
                in {
                    name WAN_IN
                }
                local {
                    name WAN_LOCAL
                }
            }
            ipv6 {
                dup-addr-detect-transmits 1
                enable {
                }
            }
            mtu 1492
            name-server auto
            password ****************
            user-id ****************
        }
        speed auto
    }
    loopback lo {
    }
    switch switch0 {
        address 192.168.1.1/24
        mtu 1500
        switch-port {
            interface eth0 {
            }
            interface eth1 {
            }
            interface eth2 {
            }
            interface eth3 {
            }
        }
    }
}
service {
    dhcp-server {
        shared-network-name LAN {
            subnet 192.168.1.0/24 {
                default-router 192.168.1.1
                dns-server 1.1.1.1
                dns-server 9.9.9.9
                start 192.168.1.100 {
                    stop 192.168.1.254
                }
            }
        }
    }
    gui {
        http-port 80
        https-port 443
        older-ciphers enable
    }
    nat {
        rule 5010 {
            description "Masquerade for WAN"
            outbound-interface pppoe0
            type masquerade
        }
    }
    ssh {
        port 22
        protocol-version v2
    }
}
system {
    host-name ubnt
    login {
        user ubnt {
            authentication {
                encrypted-password ****************
            }
            level admin
        }
    }
    ntp {
        server 0.ubnt.pool.ntp.org {
        }
        server 1.ubnt.pool.ntp.org {
        }
        server 2.ubnt.pool.ntp.org {
        }
        server 3.ubnt.pool.ntp.org {
        }
    }
    syslog {
        global {
            facility all {
                level notice
            }
            facility protocols {
                level debug
            }
        }
    }
    time-zone UTC
}

But how do you import this into ER-X? No way. You need to enter commands in the correct order, but here it is for your convenience.

Breakdown

Firewall

Begin with the IPv6 firewall rules. The descriptions should speak for themselves.

Enter these in the configure terminal:

edit firewall
set ipv6-name WANv6_IN default-action drop
set ipv6-name WANv6_IN description "IPv6 packets from the internet to LAN and WAN"
set ipv6-name WANv6_IN enable-default-log
set ipv6-name WANv6_IN rule 10 action accept
set ipv6-name WANv6_IN rule 10 description "Allow established and related packets"
set ipv6-name WANv6_IN rule 10 state established enable
set ipv6-name WANv6_IN rule 10 state related enable
set ipv6-name WANv6_IN rule 20 action drop
set ipv6-name WANv6_IN rule 20 description "Drop invalid packets"
set ipv6-name WANv6_IN rule 20 log enable
set ipv6-name WANv6_IN rule 20 state invalid enable
set ipv6-name WANv6_IN rule 30 action accept
set ipv6-name WANv6_IN rule 30 description "Allow ICMPv6 packets"
set ipv6-name WANv6_IN rule 30 log enable
set ipv6-name WANv6_IN rule 30 protocol icmpv6
set ipv6-name WANv6_LOCAL default-action drop
set ipv6-name WANv6_LOCAL description "IPv6 packets from internet to router"
set ipv6-name WANv6_LOCAL enable-default-log
set ipv6-name WANv6_LOCAL rule 10 action accept
set ipv6-name WANv6_LOCAL rule 10 description "Allow established and related packets"
set ipv6-name WANv6_LOCAL rule 10 state established enable
set ipv6-name WANv6_LOCAL rule 10 state related enable
set ipv6-name WANv6_LOCAL rule 20 action drop
set ipv6-name WANv6_LOCAL rule 20 description "Drop invalid packets"
set ipv6-name WANv6_LOCAL rule 20 log enable
set ipv6-name WANv6_LOCAL rule 20 state invalid enable
set ipv6-name WANv6_LOCAL rule 30 action accept
set ipv6-name WANv6_LOCAL rule 30 description "Allow ICMPv6 packets"
set ipv6-name WANv6_LOCAL rule 30 log enable
set ipv6-name WANv6_LOCAL rule 30 protocol icmpv6
set ipv6-name WANv6_LOCAL rule 40 action accept
set ipv6-name WANv6_LOCAL rule 40 description "Allow DHCPv6 client/server"
set ipv6-name WANv6_LOCAL rule 40 destination port 546
set ipv6-name WANv6_LOCAL rule 40 source port 547
set ipv6-name WANv6_LOCAL rule 40 protocol udp
set ipv6-receive-redirects disable
set ipv6-src-route disable
exit

Something similar for IPv4:

edit firewall
set name WAN_IN default-action drop
set name WAN_IN description "WAN to internal"
set name WAN_IN rule 10 action accept
set name WAN_IN rule 10 description "Allow established/related"
set name WAN_IN rule 10 state established enable
set name WAN_IN rule 10 state related enable
set name WAN_IN rule 20 action drop
set name WAN_IN rule 20 description "Drop invalid state"
set name WAN_IN rule 20 state invalid enable
set name WAN_LOCAL default-action drop
set name WAN_LOCAL description "WAN to router"
set name WAN_LOCAL rule 10 action accept
set name WAN_LOCAL rule 10 description "Allow established/related"
set name WAN_LOCAL rule 10 state established enable
set name WAN_LOCAL rule 10 state related enable
set name WAN_LOCAL rule 20 action drop
set name WAN_LOCAL rule 20 description "Drop invalid state"
set name WAN_LOCAL rule 20 state invalid enable
exit

Here’s a very important part for MTU, without which stuff wouldn’t work for the most part:

set firewall options mss-clamp mss 1452

You might need to adjust this value, the Ubnt default after running some wizards is 1412. Please see:

Interfaces

First of all, you need fix the LAN virtual switch. Remember, by default, ER-X assigns 192.168.1.1 to eth0, but here we want to assign that to a group of interfaces. So first you gotta remove the address from eth0, then create the virtual switch, then add all the members, then assign an address, then commit. If you mess things up, you might lose all Ethernet connectivity to the router, in which case you’ll have to perform a physical reset.

delete interfaces ethernet eth0 address
edit interfaces switch switch0
set address 192.168.1.1/24
set mtu 1500
set switch-port interface eth0
set switch-port interface eth1
set switch-port interface eth2
set switch-port interface eth3
exit
commit

Now is the time to set up the WAN interface, with PPPoE and all (make sure to replace the credentials):

edit interfaces ethernet eth4
set description "Internet (PPPoE)"
set duplex auto
set firewall in ipv6-name WANv6_IN
set firewall local ipv6-name WANv6_LOCAL
set pppoe 0 default-route auto
set pppoe 0 mtu 1492
set pppoe 0 name-server auto
set pppoe 0 user-id ****************
set pppoe 0 password ****************
set pppoe 0 dhcpv6-pd pd 0 interface switch0 prefix-id :0
set pppoe 0 dhcpv6-pd pd 0 interface switch0 service slaac
set pppoe 0 dhcpv6-pd pd 0 prefix-length /64
set pppoe 0 firewall in name WAN_IN
set pppoe 0 firewall local name WAN_LOCAL
set pppoe 0 ipv6 dup-addr-detect-transmits 1
set pppoe 0 ipv6 enable
exit

Services

Here we set up NAT first, which is necessary for IPv4:

edit service nat rule 5010
set description "Masquerade for WAN"
set outbound-interface pppoe0
set type masquerade
exit

Then also some minimal DHCP server configuration:

edit service dhcp-server shared-network-name LAN subnet 192.168.1.0/24
set default-router 192.168.1.1
set dns-server 1.1.1.1
set dns-server 9.9.9.9
set start 192.168.1.100 stop 192.168.1.254
exit

Aaand that’s it. Apply the changes and pray:

commit

Testing

There are 2 great sites I know of, which are pretty good for testing IPv6 connectivity:

Windows

Sometimes, even if your router config is fine, these might show failures. Make sure to try disabling and re-enabling the Ethernet interface on your Windows machine. Even reboot, if needed.

For full pass, you need to pass ICMPv6 traffic on your interface. To do so, please refer to Passing ICMPv6 on Windows Defender Firewall

Backup & Restore

At this point, it is a wise idea to back up your config via the web UI. Should any issue arise, you can just reset your unit and load this known-to-work setup.

Better yet, use Git and version your router config, so that you can track what changes occur to it. For hosting, I recommend GitLab, because they offer free private repos, which is rather crucial since the config file contains sensitive info, such as your PPPoE credentials.

Make sure you always backup your config from the web UI’s relevant menu. show configuration is useful for troubleshooting purposes, but the output generated by it cannot be used for restoring your config after a reset. Trust me, I learned the hard way.

Success

A picture is worth a thousand words:

Welp, that was a mouthful, enjoy, folks!