If you don't configure any views, BIND 9 automatically creates a single, implicit view that it shows to all hosts that query it. To explicitly create a view, you use the view statement, which takes the name of the view as an argument:
Although the name of the view can be just about anything, using a descriptive name is always a good idea. And while quoting the name of the view isn't necessary, it's helpful to do so to avoid conflict with words BIND reserves for its own use (like "internal," for example). The view statement must come after any options statement, though not necessarily right after it.view "internal" { };
You select which hosts "see" a particular view using the match-clients view substatement, which takes an address match list as an argument. If you don't specify a community of hosts with match-clients, the view applies to all hosts.
Let's say we're setting up a special view of the fx.movie.edu zone on our name servers that we want only the Special Effects Department to see. We could create a view visible only to hosts on our subnet:
If you want to make that a little more readable, you can use an acl statement:view "internal" { match-clients { 192.253.254/24; }; };
Just be sure you define the ACL outside of the view, since you can't use acl statements inside views yet.acl "fx-subnet" { 192.253.254/24; }; view "internal" { match-clients { "fx-subnet"; }; };
What can you put inside a view statement? Nearly anything else. You can define zones with zone statements, describe remote name servers with server statements, and configure TSIG keys with key statements. You can use most options substatements within a view, but if you do, don't enclose them in an options statement; just use them "raw" in the view statement:
Any configuration option you specify within a view overrides the like-named global option (e.g., one in the options statement) for hosts that match match-clients.acl "fx-subnet" { 192.253.254/24; }; view "internal" { match-clients { "fx-subnet"; }; recursion yes; // turn recursion on for this view // (it's off globally, in the options statement) };
For a complete list of what's supported inside the view statement on the version of BIND 9 you run (because it changes from release to release), see the file doc/misc/options in the BIND distribution.
Here's the Special Effects Lab's full named.conf file, to give you an idea of the power of views:
Notice that each view has an fx.movie.edu and a 254.253.192.in-addr.arpa zone, but the zone data files are different in the "internal" and "external" views. This allows us to show the outside world a different "face" than we see internally.options { directory "/var/named"; }; acl "fx-subnet" { 192.253.254/24; }; view "internal" { // internal view of our zones match-clients { "fx-subnet"; }; zone "fx.movie.edu" { type master; file "db.fx.movie.edu"; }; zone "254.253.192.in-addr.arpa" { type master; file "db.192.253.254"; }; }; view "external" { // view of our zones for the rest of the world match-clients { any; }; // implicit recursion no; // outside of our subnet, they shouldn't be // requesting recursion zone "fx.movie.edu" { type master; file "db.fx.movie.edu.external"; // external zone data file }; zone "254.254.192.in-addr.arpa" { type master; file "db.192.253.254.external"; // external zone data file }; };
The order of the view statements is important because the first view that a host's IP address matches is the one that dictates what it sees. If the "external" view were listed first in the configuration file, it would occlude the "internal" view because the "external" view matches all addresses.
One last note on views (before we use them in the next chapter, anyway): if you configure even one view statement, all of your zone statements must appear within explicit views.