I’ve been using radvd for a while now to hand out IPv6 addresses to all the different devices in my Dogghouse, and I thought that it would be nice to have a working dynamic DNS setup for IPv6, in the same way as I have DDNS for IPv4.

First, we need to configure radvd to advertise the IPv6 routing on our network, so lets take a look at our radvd configuration.

# RADVD with DHCPd6 configuration
# /etc/radvd.conf
interface br0 {
        AdvManagedFlag on;
        AdvSendAdvert on;
        AdvAutonomous off;
        AdvOtherConfigFlag on;
        MinRtrAdvInterval 3;
        MaxRtrAdvInterval 60;
};

This is a very basic radvd setup, which will just advertise the routing gateway to the network, and nothing more. If we are going to use DHCPd6 to hand out addresses, then this is exactly what we want for our radvd configuration. Make sure to change the interface name in the example to the interface name you will be handing out IPv6 addresses on; I have multiple interfaces bridged for my internal network and use interface br0.

If you want to use radvd to hand out addresses, then just use the following example instead.

# RADVD with no DHCPd6 configuration
# /etc/radvd.conf
interface br0 {
        AdvManagedFlag on;
        AdvSendAdvert on;
        AdvAutonomous on;
        AdvLinkMTU 1480;
        AdvOtherConfigFlag on;
        MinRtrAdvInterval 3;
        MaxRtrAdvInterval 60;
        prefix 2001:0db8:edfa:1234::/64 {
                AdvOnLink on;
                AdvRouterAddr on;
        };
};

Again, make sure to change the interface to your interface name, and change the IPv6 network prefix to your addresses.

Now, to use DHCPd for IPv6, we need a separate configuration and service/daemon to handle the IPv6 addresses, since DHCPd can’t give out both IPv4 and IPv6 addresses at the same time. If you already have a working IPv4 DHCPd setup, you can use a lot of the same configuration values in your DHCPd6 setup. Below is a basic configuration for DHCPd6.

# /etc/dhcp/dhcpd6.conf

ddns-update-style interim;
ddns-updates on;
ddns-domainname "your.domain.com";
ddns-rev-domainname "ip6.arpa";
allow client-updates;
update-conflict-detection false;
update-optimization false;
authoritative;
option domain-name-servers dns.your.domain.com;
default-lease-time 86400;
preferred-lifetime 80000;
allow leasequery;
option dhcp6.name-servers 2001:0db8:edfa:1234::1;
option dhcp6.domain-search "your.domain.com","domain.com";
include "/etc/rndc.key";
option dhcp6.preference 255;

zone a.f.d.e.8.b.d.0.1.0.0.2.ip6.arpa. {
        primary 10.0.0.1;
        key rndckey;
}
zone your.domain.com {
        primary 10.0.0.1;
        key rndckey;
}

subnet6 2001:0db8:edfa:1234::/64 {
        # Range for clients
        range6 2001:0db8:edfa:1234:5678::aaaa 2001:0db8:edfa:1234:5678::ffff;
        # Example of a fixed host address
        host client.your.domain.com {
               host-identifier option dhcp6.client-id 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd;
               fixed-address6 2001:0db8:edfa:1234:5678::1;
        }
}

This configuration will get also give out a fixed address to one of our clients, to ensure that it always gets the same IPv6 addresses from our server. Make sure that you replace the IPv6 addresses, domain names, zone, host, and subnet settings with the correct info for your network.

Notice the line include "/etc/rndc.key";. This is where I keep the key that the DHCP and DNS servers use to allow updates, so we don’t have unknown unauthorized outside sources modifying our DNS records! Below is what my rndc.key file looks like.

# /etc/rndc.key

key "rndckey" {
        algorithm hmac-md5;
        secret "super-secret-key 31337";
};

Finally, we need to make sure that our DNS server is configured to accept updates for our zones.

In our named.conf file, we need our rndc key, controls, and zone info.

key rndckey {
        algorithm hmac-md5;
        secret "super-secret-key 31337";
        };
controls {
        inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { rndckey; };
        inet ::1 port 953 allow { ::1; } keys { rndckey; };
        };


zone "your.domain.com" {
	type master;
	file "/var/named/your.domain.com.hosts";
        notify yes;
        allow-update {
                key rndckey;
        };
};
zone "a.f.d.e.8.b.d.0.1.0.0.2.ip6.arpa" {
	type master;
	file "/var/named/2001:0db8:edfa::_48.rev";
	allow-update {
		key rndckey;
		};
	};

Finally, make sure that you have the correct firewall rules in place to accept DHCPd6 requests! You’re going to need to accept ipv6-icmp traffic, and both TCP and UDP traffic on ports 546 and 547 from the link-local address range fe80::/16 to the all-dhcp-agents link-local multicast group ff02::1:2. Here are some basic ip6tables rule examples for DNS and DHCP via IPv6:

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp -m multiport -s fe80::/16 -d ff02::1:2 -i br0 -j ACCEPT --dports 546,547
-A INPUT -p udp -m udp -m multiport -s fe80::/16 -d ff02::1:2 -i br0 -j ACCEPT --dports 546,547

Now, this is a pretty basic setup, but should get you rolling with a working DHCPd6 DDNS setup!

One thing to note, I have found that Android devices (a 2.3 phone and a 3.2 tablet) don’t like to get IPv6 addresses from our DHCPd6 server; however everything else on the network (including other wifi devices) will correctly get addresses from the DHCPd6 server. Android devices will however get stateless autoconfiguration addresses from a radvd standalone setup. Perhaps this is a misconfiguration on my part, or an incompatibility in the Android OS; if you have any idea please let me know! Arf!