Silmor . de
Site Links:
Impressum / Publisher

IPv6 DNS Name Resolution

With addresses like 2001:db8:42:a38:20c:29ff:fe98:2d8 it becomes slightly harder to memorize a lot of them.

Thankfully there are several mechanisms to translate more mnemonic names into addresses. The oldest and for very small networks easiest mechanism is the host file - on Unix-like systems /etc/hosts under Windows c:\Windows\system32\drivers\etc\hosts. The format of the file is very simple: it is human readable ASCII text, IP address left, all names right of it, one line per address.

For example:

127.0.0.1 localhost
::1 localhost6
192.168.0.1 myhost
2001:db8:42:a38:20c:29ff:fe98:2d8 myhost6

In the example above we now only need to type "myhost" to use the IPv4 address of the host and "myhost6" to use its IPv6 address.

Unfortunately whenever an address is changed or added the file needs to be changed on every host in the network. While this may be acceptable with a network of 2 or 3 hosts, it becomes tiresome with any bigger network. That is what DNS is for - to have a central place where the translation between names and addresses is stored.

I will show IPv6 DNS configuration with Bind on a Linux system as an example. I will only show a very basic configuration for local resolution of IPv6 addresses - there are plenty of DNS tutorials out there for the "more interesting cases".

Please read the Wikipedia article on DNS as an intro if you are not familiar with DNS yet.

Bind

Bind is available in almost every distribution. You should use bind 9.x, since 8.x is hopelessly outdated for our purpose. After the installation of bind, it should be in its default configuration:

As soon as you enter any of the IP addresses of that bind server into your /etc/resolv.conf requests for domains will be directed to your own server and should already be able to answer any query for outside domains.

The tools host and dig will be indispensable during tests.

Important Records

DNS uses Request/Response Records (short: RRs) in its queries. The ones we are interested in are of the class "IN" (INternet), the following types are of interest:

Forward Resolving

First we need to tell bind that we have a locally administered domain by adding a zone entry in named.conf (Debian Lenny: /etc/bind/named.conf.local):

zone "lan.local"  {
        type master;
        file "/etc/bind/db.lan";
};

Then we need to create the actual zone file:

$TTL    604800
@       IN      SOA     ns1.local. root.myhost.lan.local. (
                             61         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
;
@       IN      NS      ns1.local.

myhost  IN      A       192.168.0.1
        IN      AAAA    2001:db8:1:2:2e0:81ff:fe2e:b6d1
blah    IN      CNAME   myhost

windoze IN      A       192.168.0.22
        IN      AAAA    2001:db8:1:2:20c:29ff:fe98:2d8

The file starts with setting the default timeout of any entry to 1 week (604800 seconds). The "@" sign is automatically replaced by the zone name ("lan.local") by bind - we define two RRs for the domain directly: a SOA RR and a NS RR.

The SOA RR first defines that the master server is ns1.local - the final dot tells bind that it should not append the zone name as it usually does. Second it defines root@myhost.lan.local as the administrators email - for domains in bigger networks and definitely for domains that are globally visible this should be a valid email address (the @ is replaced with a dot). The remaining items in SOA are:

If you use a publicly visible domain check with your registry: some of them (eg. DeNIC) have restrictions on the SOA values.

The NS record tells us what the nameservers for this domain are - these should be identical to the ones in the parent domain (if it exists). In the parent domain "local" the entry should look like this:

@     IN  NS  ns1.local.
lan   IN  NS  ns1.local.
ns1   IN  AAAA 2001:db8:1:2:111

For the local domain it is kind of moot to define a server outside the domain - it does not need to be resolved since the server hosting the local domain is also the one used for resolving it. This changes of course if the domain is globally visible.

The hosts "myhost" and "windoze" both get A and AAAA records, so that they can be reached via IPv4 and IPv6. If you are using a globally visible domain please make sure you don't expose private network addresses (like those from 192.168.0.0/16 or fd00::/8) to the outside.

The host "blah" is an alias (CNAME) for "myhost" here and ultimately resolves to the same addresses (you will see the difference with dig).

If we reload bind now we should already be able to query for local hosts.

Reverse Resolving

To make things complete we need reverse resolution - ie. if we query an IP address we should get the host name.

For this we need to know what happens if we type host 2001:db8:1:2:2e0:81ff:fe2e:b6d1 -

  1. transform it into the full hex version: 2001:0db8:0001:0002:02e0:81ff:fe2e:b6d1
  2. reverse the digits: 1d6be2efff180e20200010008bd01002
  3. put a dot between each digit: 1.d.6.b.e.2.e.f.f.f.1.8.0.e.2.0.2.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2
  4. append .ip6.arpa.: 1.d.6.b.e.2.e.f.f.f.1.8.0.e.2.0.2.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
  5. query for this "host"
  6. the response (if available) is a PTR record

The setup for this is usually done by creating a zone for each sub-net:

// 2001:db8:1:2::/64
zone "2.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa" {
        type master;
        file "/etc/bind/db.v6.1";
};

And putting the host IDs into the zone file:

$TTL    604800
@       IN      SOA     lan.local. root.bistro.lan.local. (
                             61         ; Serial
                         604800         ; Refresh
                          86400         ; Retry
                        2419200         ; Expire
                         604800 )       ; Negative Cache TTL
@       IN      NS      ns1.local.

1.1.1.0.0.0.0.0.0.0.0.0.0.0.0.0 IN      PTR     ns1.local.
1.d.6.b.e.2.e.f.f.f.1.8.0.e.2.0 IN      PTR     myhost.lan.local.
8.d.2.0.8.9.e.f.f.f.9.2.0.c.2.0 IN      PTR     windoze.lan.local.

The advantage of putting the reverse domain at the 64 bit boundary between network ID and host ID is that renumbering (change of network ID) only needs a change in the zone configuration in named.conf.

Client Configuration

There are several possibilities to configure the nameserver as the local resolver at the client side:

The manual option is the simplest, but also the most tiresome for big networks.

If a dual-stack solution is used and IPv4 addresses are assigned via DHCP, then the DNS server can be entered in the DHCP configuration - after all the DNS server does not care whether it sends IPv6 addresses over a DNS packet in IPv4 or IPv6.

If you happen to have one of the very few DHCPv6 servers you can enter the data there. Usually there is no need for DHCP in an IPv6 environment (unless one needs more configuration work and is uncomfortable with autoconfiguration).

The last option uses the router advertisements of IPv6 autoconfiguration to transmit Recoursive DNS Server (RDNSS) addresses.

RDNSS

If we look at our radvd configuration, we can easily extend it to transport name server addresses as well:

interface eth0
{
   AdvSendAdvert on;
   prefix 2001:db8:1:2::/64 { };
   RDNSS 2001:db8:1:2::111 { };
};

On Linux and most other sane systems name resolution is done in user space while most of the auto configuration happens in kernel space, this means that a package needs to be installed to handle RDNSS. On Linux systems this is rdnssd (on Debian the packages rdnssd and resolvconf). As soon as this is installed the system should automatically make appropriate changes to /etc/resolv.conf if a RDNSS record is in the router advertisement packets.

Links


Webmaster: webmaster AT silmor DOT de