RDNSS and IPv6

When the IPv6 RFCs were completed to a point that the working groups were happy the protocol was ready, it had been deployed in limited ways and by engineers who could deal with anything that was a little tricky or inconvenient. When mass market adoption started and new users started playing with it, there was a need to make a few elements of it simpler. In November 2010, the RFC describing RDNSS was published and it basically fixes the kludge of using DHCP to do some stuff but RA to do other stuff. (In 2017, it was superseded by RFC 8106.)

Put it simply, IPv6 didn’t use DHCP to dish out IP addresses as there was a mechanism called SLAAC. But DHCP also sends out things like which nameservers to use, so you kinda had to use DHCP anyway. You could use it either stateless or stateful:

  • Stateless – just advertise things like DNS nameservers and other options needed for things like IP phones, don’t dish out IP addresses to clients and don’t remember that you have spoken to the client that asked for the info
  • Stateful – act just like DHCP does for IPv4. Dish out addresses, options, nameservers and keep a note of who is what and run a lease timer for everything

Stateless is best in my view as it allows the proper use of SLAAC and removes the overhead of an active IP database. Stateful feels very “old fashioned” in the IPv6 world. But still needing DHCP for DNS servers is an obvious kludge. I mean, why can’t the RA messages from the router send out all that stuff?

Well. RDNSS did just that. Problem solved! Well… er.. not quite because not everybody supported it. Microsoft finally did in 2017 in build 15063. Also, if DHCPv6 exists, the RDNSS advertisement will be quietly ignored. In Centos, the reverse is true.

So my advice is to enable BOTH for the moment, until there is a consensus, though that will be in favour of RDNSS for sure.

So, as I already threw a post together on IPv6 on Juniper SRX, I might as well cover the RDNSS bits as well. So here is my example config to cover both DHCPv6 and RDNSS on the same interface and cover all the bases:

This example uses 2a01:a000:110::/64. First the IPv6 build and SLAAC:

security {
   forwarding-options {
       family inet6 {
           mode flow-based
           }
       }
   }
}
interfaces {
    fe-0/0/0  {
       description "LAN Interface";
       unit 0 {
         family inet6 {
           address 2a01:a000:110::1/64;
         }
       }
    }
 
protocols {
     router-advertisement {
         interface fe-0/0/0.0 {
             prefix 2a01:a000:110::/64;
             link-mtu;
         }
}

At this point there are no DNS nameservers being advertised to clients, so let’s add DHCPv6 with the “O” flag set to make it stateless and use a token so clients know when we send any updates in future that it is us doing it. Note we don’t configure an address pool because DHCP is stateless.

system {
    services {
        dhcp-local-server {
              dhcpv6 {
                  reconfigure {
                      token 8ysIU9E32k8r;
                  }
                 group mygroup {
                     overrides {
                         interface-client-limit 200;
                          process-inform {
                               pool mypool;
                          }
                       }
                       interface fe-0/0/0.0;
                   }
               }
          }
}
access {
      address-assignment {
          pool mypool {
              family inet6 {
                  prefix 2a01:a000:110::/64;
                  dhcp-attributes {
                      maximum-lease-time 120;
                      grace-period 3600;
                      dns-server {
                          2a01:a000:2::11;
                          2a01:a000:2::14;
                      }
                  }
              }
          }
}
protocols {
      router-advertisement {
          interface fe-0/0/0 {
              other-stateful-configuration;
               prefix 2a01:a000:110::/64;
           }
  }

You can test that all works using a PC on the LAN. When you are happy, let’s put RDNSS on as well:

protocols {
    router-advertisement {
       interface fe-0/0/0 {
             dns-server-address 2a01:a000:2::11 {
                 lifetime 100;
             }
             dns-server-address 2a01:a000:2::14 {
                 lifetime 200;
             }
        }
    }
}

If it is working, you’ll get this sort of behaviour in response to netsh :

C:\Users\simkin>netsh int ipv6 show dnsservers

I recommend using different DNS servers for DHCPv4, DHCPv6 and RDNSS so you can try different combinations and see what gets its addresses from where.

Don’t forget that a client running dual stack will log DNS servers in IPv4 and v6 and can keep one or both sets and resolve accordingly. This behaviour will rely on local system policy. By default, Windows will prefer IPv6 over IPv4 and then prefer DHCPv6 over RDNSS. To fix your preferences, use the registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\