We will be using a BIND Server that will allow recursive and authoritative requests for our clients. This way all devices will be utilizing the same cache and zone definitions. First let’s define who can access our server.
acl internal_hosts { 127.0.0.1; ::1; }; acl trusted_hosts { somehost1; somehost2; };
BIND will answer the requests using views. Views are used to serve zone details based on the querying IP and can be used for different zone representations, dependent on the source of the request.
The order of the view statements is significant — a client request will be resolved in the context of the first view that it matches.
We want to make sure the most specific rule matches the clients in this split DNS setup. It will therefore be defined before the view that serves authoritative requests to anyone.
view "internal" {match-clients { internal_hosts; trusted_hosts; }; minimal-responses yes; recursion yes; // Trusted hosts must be explicitly allowed recursion or they will be denied. // Default: 'localnets'/'localhost' allow-recursion { internal_hosts; trusted_hosts; }; allow-query-cache { internal_hosts; trusted_hosts; }; include "/etc/bind/named.conf.default-zones"; // Use external interface IPs for outgoing queries. // Port will be randomized by default query-source address 10.0.0.1; query-source-v6 address 2a02:beef:fa:1000::1; // Forwarder overrides go here include "/etc/bind/named.conf.forward-zones-internal"; include "/etc/bind/named.conf.forward-zones-external"; include "/etc/bind/named.conf.edns-no"; }; // Authoritative view for all zones we serve to anyone. view "external" { match-clients { any; }; minimal-responses yes; minimal-any yes; recursion no; rate-limit { responses-per-second 5; window 5; }; include "/etc/bind/named.conf.local"; // Disable Zone Transfers unless allowed in 'include' allow-transfer { none; }; };
Queries to our hosted zones will be forwarded to the primary authoritative NS using an include file.
zone "leuxner.net" {type forward; forward only; forwarders { 10.0.0.1; }; };