When most IPv6-capable computers join a network they attempt to automatically find a router on the network so they can figure out what addresses to use, how to set up routing, and so forth. On BSD systems like my router, the
rtadvd(8)program manages the router’s side of this exchange. While
rtadvdis rather flexible, its configuration file is frustratingly terse and its documentation assumes the reader has a fair amount of knowledge already.
For IPv4, my network uses DHCP to hand out addresses and DNS information. When rolling out IPv6, I wanted to set things up similarly, but without managing addresses centrally with DHCP since machines can configure themselves correctly without one. Configuration like this is the sort of thing that I tend to forget and have to re-learn periodically, so for reference, the
rtadvd.conffile I used for that setup looked something like this:
vether0:\ :addr="2001:db8:1221::":\ :prefixlen#64:\ :raflags#64:\ :rdnss="2001:db8:1221::1,2001:4860:4860::8888,2001:4860:4860::8844":\ :dnssl="internal.example.com":
This makes machines configure themselves for the network
2001:db8:1221::/64, DNS domain
internal.example.com, and three DNS servers: a local one at
2001:db8:1221::1, and both of Google’s public servers.
The source of most of my confusion was figuring out the
raflagsis a bit mask with two flags: M, which means a DHCP server manages addresses, and O, which means that non-address-related information (in this case, DNS information) is available that way even if addresses are not. This network setup requires the O flag to be set and the M flag to be unset, which means
raflagshas to be 64.
Now that I’ve rolled this out I get all the niceness of auto-configuration without the need for a central DHCP server to keep track of addresses. Well, for IPv6, at least.
Amazon’s Route53 DNS service, along with several content delivery networks and other DNS providers let one create an “alias” pseudo-record that causes the server to respond to requests for one name with results for another name. While the ways current implementations of this function vary a bit, the biggest difference between all of them and a
CNAMEis that while a
CNAMEgets applied to every query regardless of the type of record something is looking for, an alias is specific to just one type of record.
While this sounds like a trivial difference, the benefits are surprisingly enormous. The most obvious effect is that it lets you point a bare domain name (e.g.
example.com) at something else (e.g.
www.example.com). The reason you can’t normally do this is because the
CNAMErecord you would normally use to do this would conflict with the
SOArecord at the top of your domain, but since the alias you would use for this only applies to
Aaddress records, this is no longer a problem.
Another property aliases have is that they don’t actually go over the wire. While a CNAME record returns to the machine looking up a DNS name, causing it to restart its search with a different name, the answer for an alias comes right out of the DNS server’s own database. This means that aliases can only be used for records for which the server is authoritative or at least has some means of reliably learning the answer it should return, but that’s good enough for a great deal of use cases, notably including those of most content delivery networks. The fact that servers look up what an alias points to before they send anything over the wire means that they can include this functionality without violating standards – no one else needs to change their servers or their clients to support it. If DNS standards evolve to support it in the future, this makes transitioning even easier as that change rolls out.
In short, aliases would solve one of the most commonly-encountered shortcomings of DNS, namely its inability to use a CNAME to point a bare domain at its www equivalent. Given that there are multiple proprietary systems out there that do this already, it’s about time we standardized on an approach.
Taking a DNS name and resolving it to the address of a machine is easy to understand and easy to implement if you’re an administrator. Doing a reverse lookup from an address back to a name, however, is more difficult due to the way addresses are divided up. I won’t attempt to describe the details here (I recommend Liu and Albitz’s DNS and BIND for the gory details), but in short, the way this works is by breaking an IP address into its four octets and handling them from there like regular hierarchical names in the special
126.96.36.199.in-addr-arpa. PTR foo.example.com.
This is problematic for two main reasons:
- You have to change two zones every time you change a DNS name.
- If you have fewer than 256 addresses, your ISP can’t delegate the appropriate subset of the
in-addr.arpazone to you so you can maintain it yourself. This usually forces you to log into a web page provided by your ISP every time you change a DNS name.
RFC 2317 notes that you can work around this by filling up your subset of the
CNAMErecords instead of the usual
PTRrecords like this:
$ORIGIN 2.0.192.in-addr.arpa. 1 CNAME 1.ip4.example.com. 2 CNAME 2.ip4.example.com. ... 253 CNAME 253.ip4.example.com. 254 CNAME 254.ip4.example.com.
After you set this up you can control your forward and reverse DNS records from the same place without needing to change the reverse zone you just set up:
$ORIGIN example.com. foo A 192.0.2.1 bar A 192.0.2.2 ... baz A 192.0.2.253 bop A 192.0.2.254 1.ip4 PTR foo 2.ip4 PTR bar ... 253.ip4 PTR baz 254.ip4 PTR bop
Of course, if you rely on your ISP to create reverse DNS names for you they have to be willing to create non-
PTRrecords before you can take advantage of this.
If you’re lucky enough to have an entire /24 block of addresses all to yourself you can simplify the reverse DNS zone by simply mapping the entire set of addresses with a single
DNAMEinstead of a long list of
$ORIGIN 2.0.192.in-addr.arpa. @ DNAME ip4.example.com.
This has the same net effect as the list of CNAMEs, but it shortens things significantly.