IPv6, DHCPv6 and DDNS

Hello,

As you already know IPv6 uses stateless configuration right off the bat.

If you have a small network, this is not a problem, and I mean small meaning maybe 10 or so devices.

You can manually update your devices using DNS and you will be fine.

But in the enterprise where you can have hundreds if not thousands of devices then you have a nightmare.

You will not remember IPv6 addresses as you did with IPv4, you need DDNS so devices can register themselves with DNS.

For this you would need the following.

    • A DNS server that allows IPV6 dynamic registrations
    • A DHCP server that supports such registrations.
    • A DHCP server that can issue IPv6 addresses and other options.
    • A RADVD or Router that is capable of advertising a default route.

I want to show you how to configure this using GNS3 and VirtualBox. This lab hopefully will be instructional.

Before I continue you may be asking, why do you need a RADVD server when DHCPv6 should be able to offer a default route?

DHCPv4 does it.

Well DHCPv6 lacks that functionality.

The initial specification of DHCPv6 did not have an option to offer a default route. Then a draft was introduced so DHCPv6 would have an option to send a default route.

Unfortunately as of today it is still a draft. You can check the  ISC server for example.

To provide that functionality, you need instead a RADVD server or a router.

You also need to suppress advertisements for the network on the segment you want but still allow it to send RA if asked.

On Cisco routers you do that with the following command on the interface you want IPv6:

ipv6 nd prefix xxxx:xxx::/xx no advertise
ipv6 nd managed-config-flag

With the above your devices will receive a default gateway in addition to any other options you are giving via DHCPv6.

On the other hand if you do not want to use a router but a RADVD server then the following configuration will do the trick:

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

Of course you need to disable SLAAC altogether on your router.

But I digress.

Figure 1. shows the lab topology.

Fig1. Lab Topology.

The lab uses:

    • GNS3
    • VirtualBox
    • A Cisco router acting as the default gateway.
    • A L2/L3 Cisco switch to enable VLAN behavior.
    • A sever running Fedora 23, this will run DHCPv6, DNS.
    • Two Linux client machines,  running Debian, you can use whatever client you feel more comfortable.
    • A Win7 machine to test windows.

Disclaimer

I cannot stress enough the following:

    • I do not have Cisco IOS images to give. Please do not ask for them. The ones I use for the lab where obtained legally.
    • Do not use the IPv6 addresses I used on my examples on a real system, meaning if it is connected to an IPv6 network.
    • Once again.  do not use the IPv6 addresses used in my examples they will not be routable on the Internet, since they are not assign to you. For the purposes of the lab they will work as long as they are kept in the lab.
    • You should already know how to setup GNS3 and VirtualBox, and also how to have guests interact with GNS3.
    • A tutorial on GNS3 and VirtualBox is beyond the scope of this lab.

Lab Setup

This is a pure IPv6 network with the only exception of the severs. They have IPv4 on a “host only network” so you can ssh to them to configure the devices.

Notice that I have two switches in between the devices and the core. This mimics L2/L3 switches you may have in a real situation.

GW Setup

The following  is the pertinent setup for the GW router.

ipv6 unicast-routing

interface Loopback0
 no ip address
 ipv6 address 2012:AA::4/127
 ipv6 enable
!
interface FastEthernet0/0
 no ip address
 duplex auto
 speed auto
 ipv6 address 2012:AA::2/127
 ipv6 enable

router bgp 100
 no synchronization
 bgp router-id 1.1.1.1
 bgp log-neighbor-changes
 neighbor 2012:AA::3 remote-as 100
 neighbor 2012:AA::3 next-hop-self
 neighbor 2012:AA::3 soft-reconfiguration inbound
 no auto-summary
 !
 address-family ipv6
  neighbor 2012:AA::3 activate
  neighbor 2012:AA::3 default-originate
  redistribute connected
  no synchronization
 exit-address-family

A few things to notice:

    • Enable ipv6 routing otherwise it will not work.
    • I am using a /127 on the loopback interface. A /128 probably would have been better.
    • I am using a /127 on the link between routers, This is allowed as of the latest RFC. This is the equivalent of using /30 on point-to-point connections.
    • I am  using BGP.  Any dynamic routing will do, I just decided on BGP. You can try OSPFv3 or EIGRP if you fancy it.
    • When everything is working correctly, you should be able to ping the loopback interface from any of the IPv6 guests.

Core Router

The pertinent configuration for the core router.

ipv6 unicast-routing

interface FastEthernet3/15
 switchport access vlan 10

interface Vlan1
 no ip address
 ipv6 address 2012:AA:0:1::1/64
 ipv6 enable
 ipv6 nd prefix 2012:AA:0:1::/64 no-advertise
 ipv6 nd managed-config-flag
!
interface Vlan10
 no ip address
 ipv6 address 2012:AA:0:2::1/64
 ipv6 enable
 ipv6 nd prefix 2012:AA:0:2::/64 no-advertise
 ipv6 nd managed-config-flag
 ipv6 dhcp relay destination 2012:AA:0:1::10 Vlan1
!
router bgp 100
 no synchronization
 bgp router-id 2.2.2.2
 bgp log-neighbor-changes
 neighbor 2012:AA::2 remote-as 100
 neighbor 2012:AA::2 next-hop-self
 neighbor 2012:AA::2 soft-reconfiguration inbound
 no auto-summary
 !
 address-family ipv6
  neighbor 2012:AA::2 activate
  redistribute connected
  no synchronization
 exit-address-family

Things to notice:

  • Notice the following two commands on the vlan  interfaces
ipv6 nd prefix 2012:AA:0:2::/64 no-advertise
ipv6 nd managed-config-flag
    • Above disables network advertisements, DHCPv6 will take care of it. RA will still be announced.
    • We also tell the router that DHCP will provide other options.
    • Finally for vlan 10 we also set relay information so devices on that vlan can find the DHCP server and obtain addresses.
    • Notice that static IP addresses need to be given to the interfaces and the VLANs, there is no way around this. On an IPv4 you would do the same for your routers or servers.

Server Setup.

The server setup is as follows, first a couple of notes:

    • I am running Fedora 23. I had already downloaded it, but you can use any server you wish.
    • The server needs to run DNS (named) and DHCPv6 (ISC server).

You need to configure a static IPV6 on the server:

[root@Test-IPV6 named]# more /etc/sysconfig/network-scripts/ifcfg-enp0s8
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6ADDR=2012:aa:0:1::10/64
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=enp0s8
ONBOOT=yes

A couple of things to consider.

    • Replace the correct interface for your server.
    • You will also need to add a default gateway, this is the IP of the router of course.
/sbin/route -A inet6 add default gw 2012:aa:0:1::1 dev enp0s8

The configuration for DHCP:

#
# DHCPv6 Server Configuration file.
#   see /usr/share/doc/dhcp-server/dhcpd6.conf.example
#   see dhcpd.conf(5) man page
#
# DDNS statements
ddns-updates on;           # default but good practice
ddns-update-style interim; # only supported active option
allow client-updates;      # default but good practice
#do-forward-updates;        # default but good practice
authoritative;
option dhcp6.name-servers 2012:aa:0:1::10;
# zone clauses are optional and required
# only to define params for DDNS
# may be one or more zone clauses
zone example.com {
  primary ns1.example.com;
  # uses name format could use IPv6 address format
}
zone 1.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa. {
  primary ns1.example.com;
  # the above can use a dns name, instead of an IP
  # which is probably more flexible
  # primary ns1.example.com.
  # and for IPv6 can be much shorter
}
zone 2.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa. {
  primary ns1.example.com;
  # the above can use a dns name, instead of an IP
  # which is probably more flexible
  # primary ns1.example.com.
  # and for IPv6 can be much shorter
}
# must be at least one subnet clause
# in a dhcpd.conf file
subnet6 2012:aa:0:1::/64 {
  # useable IP addresses in this subnet
  # can be range or /prefix format (used in example)
  #range6 2001:db8::/112;
  # optional use of temporary IPv6 addresses will not update
  # forward or reverse maps as defined by RFC 4941
  range6 2012:aa:0:1::100 2012:aa:0:1::200;
  #range6 2001:db8:0:0:1::/104 temporary;
  #subnet statements
  # DDNS statements
  ddns-domainname "example.com.";
  # use this domain name to update AAAA RR (forward map)
  ddns-rev-domainname "ip6.arpa.";
  # use this domain name to update PTR RR (reverse map)
}
subnet6 2012:aa:0:2::/64 {
  # useable IP addresses in this subnet
  # can be range or /prefix format (used in example)
  #range6 2001:db8::/112;
  # optional use of temporary IPv6 addresses will not update
  # forward or reverse maps as defined by RFC 4941
  range6 2012:aa:0:2::100 2012:aa:0:2::105;
  #range6 2001:db8:0:0:1::/104 temporary;
  #subnet statements
  # DDNS statements
  ddns-domainname "example.com.";
  # use this domain name to update AAAA RR (forward map)
  ddns-rev-domainname "ip6.arpa.";
  # use this domain name to update PTR RR (reverse map)
}

The configuration for named:

//
// named.conf
//
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//

options {
        listen-on port 53 { localhost; };
        listen-on-v6 port 53 { any; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-query     { any; };
        allow-query-cache {any; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion no;

        dnssec-enable yes;
        dnssec-validation yes;

        /* Path to ISC DLV key */
        /* In case you want to use ISC DLV, please uncomment the following line. */
        //bindkeys-file "/etc/named.iscdlv.key";

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

 zone "example.com" IN {
 type master;
 file "example.com.zone";
 allow-update { any; };
 };

 zone "1.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa" {
 type master;
 file "reverse.zone";
 allow-update { any; };
 };

 zone "2.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa" {
 type master;
 file "reverse2.zone";
 allow-update { any; };
 };

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

The last thing to do is create the zones we have defined on named.conf

example.com.zone
$ORIGIN .
$TTL 86400      ; 1 day
example.com             IN SOA  ns1.example.com. hostmaster.example.com. (
                                66         ; serial
                                28800      ; refresh (8 hours)
                                7200       ; retry (2 hours)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      ns1.example.com.
$ORIGIN example.com.
ns1                     AAAA    2012:aa:0:1::10
r1                      AAAA    2012:aa:0:1::

reverse.zone
$ORIGIN .
$TTL 3600       ; 1 hour
1.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa IN SOA ns1.example.com. hostmaster.example.com. (
                                56         ; serial
                                3600       ; refresh (1 hour)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                3600       ; minimum (1 hour)
                                )
                        NS      ns1.example.com.

reverse2.com
$ORIGIN .
$TTL 3600       ; 1 hour
2.0.0.0.0.0.0.0.a.a.0.0.2.1.0.2.ip6.arpa IN SOA ns1.example.com. hostmaster.example.com. (
                                57         ; serial
                                3600       ; refresh (1 hour)
                                900        ; retry (15 minutes)
                                604800     ; expire (1 week)
                                3600       ; minimum (1 hour)
                                )
                        NS      ns1.example.com.

That’s it. All is left is to start the services.

Workstations

The workstations just need to be created and started. They need to be configured to obtain IPv6 addresses via DHCP. If everything is done right they will obtain Ipv6 addresses via DHCP and they will register with the server.

Caveats

The Linux machines may not register with the DHCPv6 server, this is due to a problem with the dhcp client configuration. The Linux workstation sometimes will not send the proper host name configured so if your Linux machines are not registering, use the DHCP_HOSTNAME option on the client configuration file.

I have found that the above is hit and miss. On FC it works but on Ubuntu it does not if you use NetworkManager for example, even if you add the corresponding variable to send the hostname.

But if you use “dhclient” it will work if the DHCP_HOSTNAME is set.

If you cannot get it to work on a Linux workstation a solution is to use nsupdate. nsupdate will allow you to add and delete DNS records dynamically.

There are a couple of scripts in the wild that will, gather the name of the machine, query the DNS server for its IPv6 address, then taking the domain name as parameter will add the DNS and PTR records and delete old records.

Just run it once a day, if the IPv6 of the machine have changed delete the old records and add the new records.

Finally I did not use authentication when updating DDNS records. On a production environment this is a must, it will be the subject of another blog hopefully.

Conclusions

Hopefully this lab will help someone, setting DDNS for IPv6 is not that difficult.

Of course there is always some other caveat. In our case this has to do with Android phones. It turns out that the developer in charge for Google feels there is not need for Android phones to request IPv6 addresses using DHCP.

Thus DHCPv6 is not supported on Android phones. nice is it not.

Well there is solution, you could use for your phones DNSMASQ, which is a very small footprint DNS+DHCPv6+RADVD all in one.

So you could have two servers and named can be configured to forward request for DNS resolution to the DNSMASQ server.

Leave a Reply

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