say my name

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.

hypnofrogWith 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!

Leave a Reply