Split DNS via PowerDNS Recursor
After fumbling around for some time on my Fedora 20, I seem to have made it work. I haven't found a full how-to anywhere, so a short writeup for a minimal setup:
We want to resolve
webserver.dyndns.org to access a web service on it, both from the Internet and the LAN.
From the Internet
Machine a on the Internet resolves
webserver.dyndns.org to the IP address IPisp. Behing IPisp is a router with NAT, which port-forwards port 80 to LAN IP IPx, thus making a web service available on the Internet.
This is naturally done by registering IP address IPisp at the authoritative nameserver for domain dyndns.org, which, in the case of a service like DynDns, is done using ddclient running on the router or somewhere in the LAN, and thus of no further interest here.
From the LAN
Machine b on the LAN resolves
webserver.dyndns.org to the IP address IPx, so that the web service becomes available on the LAN directly. Additionally, assuming all the machines on the LAN are named along the lines of bar.localdomain, the name
webserver.localdomain should also resolve to IPx. We also want to have reverse lookup for good measure, resolving IPx to
webserver.dyndns.orginside the LAN (on the Internet, IPx resolves of course to nothing and IPisp resolves to some arbitrary string generated by the ISP.)
We assume pdns-recursor is running on a separate machine with IP IPdns, but we could also have it running on the webserver (on the same IP address as IPx or on an alias), or have only a single machine on the LAN.
Machine "b" may be configured statically or dynamically via DHCP; see
dnsmasq and possibly
NetworkManager also enters here because it may rewrite
/etc/resolv.conf; for now, assume static configuration.
IPx = 192.168.1.1
IPdns = 192.168.1.2
IPbar = 192.168.1.3
/etc/resolv.conf on any machine:
Configuration for pdns-recursor:
/etc/pdns-recursor/recursor.conf basically reduces to:
allow-from=127.0.0.0/8, 192.168.1.0/8, ::1/128, fe80::/10
auth-zones=webserver.dyndns.org=/etc/pdns-recursor/[webserver.dyndns.org].zone, localdomain=/etc/pdns-recursor/[localdomain].zone, 168.192.in-addr.arpa=/etc/pdns-recursor/[168.192.in-addr.arpa].zone
The above references very much cut-down zone files (their actual names are unimportant):
/etc/pdns-recursor/[168.192.in-addr.arpa].zone (note the lack of a dot at the end of the record name - it is a relative name not an absolute one:
220.127.116.11.in-addr.arpa). This works with or without the "IN".
1.1 IN PTR webserver.dyndns.org.
2.1 IN PTR dns.localdomain.
3.1 IN PTR b.localdomain.
/etc/pdns-recursor/[webserver.dyndns.org].zone (note the dot at the end of the record name - it is an absolute name not a relative one)
webserver.dyndns.org. IN A 192.168.1.1
webserver IN A 192.168.1.1
dns IN A 192.168.1.2
b IN A 192.168.1.3
After a restart of
pdns-recursor, on can test using
dig by running these commands:
# Test unknwon domain resolution and webserver resolution
dig @$PDNS www.cnn.com | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS webserver.dyndns.org | grep -A1 ";; ANSWER SECTION:"
# Test responses for localdomain
dig @$PDNS unknown.localdomain | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS webserver.localdomain | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS b.localdomain | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS dns.localdomain A | grep -A1 ";; ANSWER SECTION:"
# Test responses for localdomain if the domain is omitted
dig +search @$PDNS webserver | grep -A1 ";; ANSWER SECTION:"
# Test reverse resolution
dig @$PDNS -x 192.168.1.1 | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS -x 192.168.1.2 | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS -x 192.168.1.3 | grep -A1 ";; ANSWER SECTION:"
dig @$PDNS -x 192.168.1.4 | grep -A1 ";; ANSWER SECTION:"