Split DNS – Cleanest solution for easy maintenance

domain-name-systeminternal-dnssplit-dns

We have split DNS set up for our domain, which causes internal clients to resolve different DNS records from external clients.

As it is right now, the two zones are managed completely separately. For records that differ between internal and external, it's no problem, but for everything else, all of the records have to be duplicated in both places. Most CNAME records, MX records, SPF records, and some A records all need to be entered and maintained in both places.

While this isn't inherently unacceptable, data duplication like this is less than ideal from a design perspective. I feel like ideally, the internal nameserver would simply forward results from the external nameserver, but allow for us to override or add additional records. While it looks like I could use a designated forwarder (like dnsmasq) to do something like this, the flat file configuration would make it difficult to sell the idea to the rest of the team.

Aside from that, the best solution I've been able to come up with consists of PowerDNS with a MySQL backend and web interface. This makes it fairly easy to add a zone and root A record for each sub-domain we'd like to override (e.g. www.example.com), which means other records on the root domain (e.g. example.com) will still be forwarded from the external nameserver.

That still seems like I'm straying kind of far from the norm for something that's supposedly very common, right? Is there a cleaner way to manage Split DNS without maintaining duplicate records? Or is there something I'm missing?

Best Answer

In a network where one of the authoritative nameservers sits on the border of the internal network, I use bind views and the $INCLUDE directive:

mydomain-global.zone:

@ IN SOA ns1 hostmaster ( 12345; 1D; 2M; 1M; 3H )
  IN NS ns1
  IN NS ns2

  IN MX 10 mail

  www               IN A 1.2.3.4
  other-public-host IN A 1.2.3.5

mydomain-internal.zone:

$INCLUDE mydomain-global.zone

an-internal-record IN A   10.20.30.40
_kerberos          IN SRV 0 0 88 dir

The zones are chosen based on view definitions:

view "internal" {
  match-clients { 10.0.0.0/8; };
  zone "mydomain" {
    type master;
    file "mydomain-internal.zone";
  };
  include "named.conf.internalzones";
}

view "global" {
  match-clients { any; };
    zone "mydomain" {
    type master;
    file "mydomain-global.zone";
  };

To be able to assign a record different targets for internal/external queries, add two further zone fragments and $INCLUDE at the bottom of mydomain-(internal|global).zone.