DNS – Part 4 – Private Network Domain Name Resolution
Lets do this!
Motivation
So I need to be even lazier and remember even less stuff.
With LXC, if you’re like me, by the time your setup has matured you’ll end up with a lot of containers. Consequently, when you want to change stuff up, no matter how organized you are, local IP addresses start to blur in your mind.
With 16 distinct IP addresses to memorize, from multiple IP ranges, this hypnofrog feeling will be familiar.
That image is so freaky… certainly gives Futurama a new depth. 😀
One way to resolve this white people problem is to use a DNS server to resolve local names for you. With this approach, the only thing I need to do to access a particular container is to remember it’s function. For instance, instead of doing this:
ssh 10.2.4.123
I can do this:
ssh web.joaolino.com
Yes, I’m proudly that lazy.
To do this, bind will have to have split personality. To outsiders it reports A and to insiders it reports B.
A is the same face it showed up until now. When queried, as it always did, it will resolve a www service, a mail service, a name service and some other aliases of the joaolino.com domain.
B is the new personality. When queried, this new personality will resolve local endpoint names according to their function. These functions include web, cdn, mail, router, etc functions and it will also resolve local machine names.
Theory
To do this spiting of personalities, I’ll be using the view concept. A view translates into the configurations as a keyword with a bit of semantics around it. More on that at ZYTRAX.
The view clause allows BIND to provide different functionality based on the hosts accessing it.
This is basically how it should be used:
view Clause Syntax
view “view_name” [class] {
[ match-clients { address_match_list } ; ]
[ match-destinations { address_match_list } ; ]
[ match-recursive-only { yes | no } ; ]
// view statements
// zone clauses
};
Each of the keywords used in the view clause are used to:
match-clients
match-clients { address_match_element; … };
match-clients { 10.2.3.0/8;172.16.30.0/16;!192.168.0.0/16; };
# the above could be re-written as
match-clients { 10/8;172.16/16;!192.168/16; };
# (More info on IP Prefix notation)A view clause matches when either or both of its match-clients and match-destinations statements match and when the match-recursive-only condition is met. If either or both of match-clients and match-destinations are missing they default to any (all hosts match). The match-clients statement defines the address_match_list for the source IP address of the incoming messages. Any IP which matches will use the defined view clause. This statement may only be used in a view clause.
match-destinations
match-destinations { address_match_element; … };
match-destinations { 192.168.0.3; };A view clause matches when either or both of its match-clients and match-destinations statements match and when the match-recursive-only condition is met. If either or both of match-clients and match-destinations are missing they default to any (all hosts match). The match-destination statement defines the address_match_list for the destination IP address of the incoming messages. Any IP which matches will use the defined view clause. This statement may only be used in a view clause.
match-recursive-only
match-recursive-only (yes | no);
match-recursive-only yes;A view clause matches when either or both of its match-clients and match-destinations statements match and when the match-recursive-only condition is met. If either or both of match-clients and match-destinations are missing they default to any (all hosts match). The match-recursive-only can be used in conjunction with match-clients and match-destinations or on its own if that is sufficient differentiation. The default is no. This statement may only be used in a view clause.
So basically:
- all zones must be inside views, otherwise nothing makes sense.
- Each client can be matched to a view by using match-client clause and the any, localhost, localnets, privatenets acls.
Hum..that’s easy..
Setup
First, Looking at /etc/bind/named.conf you’ll get a sense of where changes will need to be made:
include "/etc/bind/named.conf.options"; include "/etc/bind/named.conf.local"; include "/etc/bind/named.conf.default-zones";
options has no zones in it. local and default-zones have zone clauses so they must be modified.
Second, the /etc/bind/named.conf.options file has no zones inside so for this configurations, it will be left alone.
The /etc/bind/named.conf.default-zones has some, so lets mod it now, running the command:
sudo nano /etc/bind/named.conf.default-zones
And making it look like this, adding the orange parts:
view "default" { match-clients { any; }; // prime the server with knowledge of the root servers zone "." { type hint; file "/etc/bind/db.root"; }; // be authoritative for the localhost forward and reverse zones, and for // broadcast zones as per RFC 1912 zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127"; }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; };
Third, the /etc/bind/named.conf.local also has some zones, so lets mod it now, runing the command:
sudo nano /etc/bind/named.conf.local
And making it look like this, adding the orange parts and commenting out the blue parts:
// // Do any local configuration here // // Consider adding the 1918 zones here, if they are not used in your // organization //include "/etc/bind/zones.rfc1918"; //zone "joaolino.com" { // type master; // file "/etc/bind/zones/zone.joaolino.com"; //}; view "private" { match-clients { localhost; localnets; privatenets; }; zone "joaolino.com" { type master; file "/etc/bind/private/zone.joaolino.com"; }; }; view "internet" { match-clients { any; }; zone "joaolino.com" { type master; file "/etc/bind/zones/zone.joaolino.com"; }; };
Forth, now that the zones are into the proper views, lets create the private view folder and create/open the private zone file.
sudo mkdir /etc/bind/private nano /etc/bind/private/zone.joaolino.com
Make it look something like this…
$INCLUDE /etc/bind/zones/zone.joaolino.com @ IN A 192.168.1.4 web IN A 10.0.42.121 cdn IN A 10.0.42.122 email IN A 10.0.42.123 meo IN A 192.168.1.1 link IN A 192.168.0.1 office IN A 192.168.1.173 server IN A 192.168.1.127 jarbas IN A 192.168.1.193 pi IN A 192.168.1.119 vpn-joao-samsung IN A 10.0.6.103 vpn-tiago-zte IN A 10.0.6.131 vpn-pedro-nokia IN A 10.0.6.160
Fifth I just need to restart Bind9:
sudo service bind9 restart
BOOM…done!