Configuring a Dual-Stacked Ubuntu Router on Aussie Broadband NBN

The NBN connection that was scheduled to arrive on my street in 2013 finally arrived last week. IPv4 worked straight out of the box, but IPv6 took considerably longer to get working. This is mostly caused by shortcomings in netplan (Ubuntu’s new network config renderer introduced in 18.04) and ISC DHCP Server when combined with ABB’s DHCPv6-PD system. My router is running Ubuntu 20.04, which doesn’t appear to be any different.

Even though Aussie Broadband provide you with a somewhat-fixed /48 prefix delegation, it will drop all traffic unless that prefix is currently leased through DHCPv6-PD. You must request it from DHCPv6, not statically define it.

Sign up to the IPv6 Beta


Firstly, IPv6 is opt-in. You can opt into the IPv6 beta here. You will be assigned two addresses. One is an IA-NA (a single /128 address from a /64 block for the router), the other is an IA-PD (/48 prefix delegation to use on your network).

Configure Network Interfaces with Netplan

Here’s how to set up /etc/netplan/01-netcfg.yaml for the LAN interface. Ensure that “fdxx:xxxx” is changed to a suitable ULA prefix. I use ULAs as it provides a guaranteed static IP for internal services which cannot leak to the outside internet. It provides a failover for the local network when the internet is down. Subtitute the MAC address of the LAN interface.

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0f0:
      match:
        macaddress: xx:xx:xx:xx:xx:xx
      addresses: ["fdxx:xxxx::1/64", 192.168.1.1/24]
      dhcp4: false
      dhcp6: false
      accept-ra: false
      set-name: lan

Here’s how to set up /etc/netplan/02-wancfg.yaml for the WAN interface. Again, set the correct MAC address.

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    enp1s0f2:
      match:
        macaddress: xx:xx:xx:xx:xx:xx
      dhcp4: true
      dhcp6: false
      accept-ra: false
      set-name: wan

You will notice that dhcp6 and accept-ra are disabled. This is intentional, as enabling either of these will invoke ISC dhcp client for IPv6, which prevents the wide-dhcp6-client service from functioning.
Run sudo netplan generate when done. This will render a network config that will be applied the next time the system boots.

Allow DHCPv6 through the firewall

DHCPv6 communicates through UDP port 546. Traffic on this port must be explicitly allowed in order to receive an address allocation through DHCPv6.

Add the following line to /etc/iptables/rules.v6:

-A INPUT -d fe80::/64 -i wan -p udp -m state --state NEW -m udp --dport 546 -j ACCEPT

Enable forwarding and router advertisements

Uncomment the following line in /etc/sysctl.conf to enable forwarding:

net.ipv6.conf.all.forwarding=1

Because enabling forwarding disables router advertisements (RA), it must be manually enabled on the WAN interface. Because netplan needs accept-ra set to ‘false’ to prevent ISC from blocking the interface, we need to enable it through /etc/rc.local:

#!/bin/sh -e

#Enable router advertisements on WAN
sysctl -w net.ipv6.conf.wan.accept_ra=2
sysctl -p

exit 0

Install WIDE DHCPv6 Client

Install the wide-dhcpv6-client apt package, then modify /etc/wide-dhcpv6/dhcp6c.conf:

# Default dhpc6c configuration: it assumes the address is autoconfigured using 
# router advertisements.
profile default
{
  information-only;
  request domain-name-servers;
  request domain-name;
  script "/etc/wide-dhcpv6/dhcp6c-script";
};
interface wan {
  send ia-na 1;
  send ia-pd 0;
};
id-assoc na 1 {
};
id-assoc pd 0 {
  prefix-interface lan {
    sla-id 1;
    sla-len 16;
  };
};

This enables both IA-NA and IA-PD (something netplan + ISC cannot do right now). The “sla-id 1” will assign the second /64 prefix to the LAN interface. We’re saving the first /64 (sla-id 0) for the WAN interface. “sla-len” is set to 16 because we’re allocating a /64 from a /48 prefix (16 bits difference).

RADVD Configuration

RADVD provides router advertisements to your local network. You must use the same prefix assigned to your LAN interface by wide-dhcp6-client (sla-id 01), hence the “01” at the end of the prefix.

Here is /etc/radvd.conf

interface lan
{
  AdvSendAdvert on;
  AdvOtherConfigFlag on;
  prefix fdxx:xxxx::/64
  {
    AdvOnLink on;
    AdvAutonomous on;
  };
  prefix 2403:58xx:xxxx:01::/64
  {
    AdvOnLink on;
    AdvAutonomous on;
  };
  RDNSS fdxx:xxxx::1 { };
};

Only add the RDNSS line if you are running a local DNS server.

Final steps

This should be enough for the router to provide IPv6 to your network. Reboot the router and see how it works. However, the /128 address assigned to the router doesn’t appear to give the router itself IPv6 access. You need to give it an IP address from within your assigned /48 delegated prefix.

sudo ip addr add 2403:58xx:xxxx::1/64 dev wan

Unfortunately, it appears you need to do this manually after the interface has come up, which means this is a manual process to be done on each boot. I’ll update here if I find a reliable way to trigger it automatically.

Debugging

If things go wrong, it’s necessary to see what DHCPv6 is doing.

sudo tcpdump -i wan -vv -n port 546

Run this command from one terminal and run sudo service wide-dhcpv6-client restart from another. I’ve found ABB’s DHCP server will respond with UnspecFail quite a lot, and when this happens, I find it’s necessary to reboot everything, including the modem. It’s also worth checking that you have a default route:

$ ip -6 route | grep default
default via fe80::2a2:ff:feb2:c2 dev wan proto ra metric 1024 expires 1702sec hoplimit 64 pref high

If you don’t have a default route, chances are that net.ipv6.conf.wan.accept_ra is not set to ‘2’. The default route is only configured if RAs are accepted by the interface. Lastly, make sure you have an actual /128 on the WAN, /64 global IP addresses on the WAN and LAN interfaces:

$ ip addr show lan
2: lan: mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether a0:36:9f:71:f1:58 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 brd 192.168.1.255 scope global lan
       valid_lft forever preferred_lft forever
    inet6 2403:58xx:xxxx:xx01:xxxx:xxxx:xxxx:xxxx/64 scope global
    valid_lft forever preferred_lft forever
    inet6 fdxx:xxxx::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::a236:9fff:fe71:f158/64 scope link
       valid_lft forever preferred_lft forever

$ ip addr show wan
3: wan: mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether a0:36:9f:71:f1:5a brd ff:ff:ff:ff:ff:ff
    inet 119.18.xxx.xxx/22 brd 119.18.27.255 scope global dynamic wan
       valid_lft 1235sec preferred_lft 1235sec
    inet6 2403:58xx:xxxx:xx00::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 2403:58xx:xxxx:xx:xxxx:xxxx:xxxx:xxxx/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::a236:9fff:fe71:f15a/64 scope link
       valid_lft forever preferred_lft forever

Posted

in

by

Tags:

Comments

3 responses to “Configuring a Dual-Stacked Ubuntu Router on Aussie Broadband NBN”

  1. anon

    Unfortunately this completely fails to explain any of the IPv6 concepts that you need to understand to configure this when you are only familiar with IPv4. Disappointingly, each and every article I find on Debian IPv6 config has this as assumed knowledge, and this is no different.

    You all go on about the need to change to IPv6, but nobody actually takes the time to explain it. Until that happens on a wider scale, adoption will stagnate.

    1. Russell Phillips

      This is more of a tech note. Honestly, this sort of thing should just work out of the box. If you had an OpenWRT router, you’d plug it into an ABB connection and IPv6 with prefix delegation would work without having to touch anything. This is what the title says – a document detailing the additional configuration required for Ubuntu.

  2. ABB User

    Thanks! Worked for me, without the manual address in Final Steps.
    Then dropped netplan/radv/wide-dhcp and used systemd networking only.
    This is 20.04 with a local domain name & DNS server.
    Do “systemctl enable systemd-networkd” to enable at boot, as netplan starts it with –runtime.
    These files go in /etc/systems/network:

    10-lan.link
    [Match]
    MACAddress=xx:xx:xx:xx:xx:xx

    [Link]
    Name=lan
    WakeOnLan=off

    10-lan.network
    [Match]
    Name=lan

    [Network]
    LinkLocalAddressing=ipv6
    Address=192.168.xxx.1/24
    Address=fdxx:xxxx:xxxx::1/64
    Domains=my.local.domain
    IPv6PrefixDelegation=yes

    [IPv6PrefixDelegation]
    RouterLifetimeSec=3600
    DNSLifetimeSec=10800
    EmitDNS=yes
    DNS=fdxx:xxxx:xxxx::1

    [IPv6Prefix]
    Prefix=fdxx:xxxx:xxxx::/64

    10-wan.link
    [Match]
    MACAddress=xx:xx:xx:xx:xx:xx

    [Link]
    Name=wan
    WakeOnLan=off

    10-wan.network
    [Match]
    Name=wan

    [Network]
    DHCP=ipv4
    LinkLocalAddressing=ipv6
    IPv6AcceptRA=yes

    [DHCPv4]
    RouteMetric=100
    UseMTU=yes
    # Don’t use these ABB supplied values
    UseDNS=no
    UseNTP=no
    UseHostname=no

    [DHCPv6]
    # Don’t use these ABB supplied values
    UseDNS=no
    UseNTP=no

    [IPv6AcceptRA]
    # Don’t use these RA values from ABB
    UseDNS=no
    UseDomains=no

Leave a Reply

Your email address will not be published. Required fields are marked *