title: Internal DNS configuration woes
body: <p>Alright, I am going to state up front that this question may be too involved (amount of detail not complexity) for this medium.  But I figured this was the best place to start.</p>
  
  <p>I am attempting to setup a proof of concept project and my BIND configuration is my first big hurdle.  I want to setup 3 DNS servers on 3 physical boxes.  <strong>None</strong> of these boxes needs to resolve public addresses, this is internal <strong>only</strong>.  I have read through how to setup internal roots in the (mostly) excellent DNS &amp; BIND 5th ed book.  But my translation of their example is not functional. All IP's are RFC 1918 non-routable.</p>
  
  <p>Box 1 will be authoritative for addresses on the <em>box1.bogus</em> domain, and Box 2 will be authoritative for addresses on the <em>box2.bogus</em> domain.  Box 3 will act as both an internal root and the TLD server for the domain <em>bogus</em>.</p>
  
  <p>Current unresolved issues:</p>
  
  <ul>
  <li><p>I have a hints file on box 1 and 2 that contains a single <strong>NS</strong> record to the NS definition of the root zone.  Additionally there is an <strong>A</strong> record that translates the NS to the ip of the root.  if I <code>dig .</code> from box 1 I get an <em>authority</em> Section with the NS name, not an <em>answer</em> and <em>additional</em> record section.  Therefore I am unable to actually resolve the IP of the root server from box 1.</p></li>
  <li><p>If I point my <code>/etc/resolv.conf</code> from box 1 directly at the root server and do a <code>dig box1.bogus</code> I get the ns.box1.bogus <em>answer</em> record and the translation in the <em>additional</em> section.  However on the next iteration (when should get the A record) I get <code>dig: couldn't get address for ns.box1.bogus</code></p></li>
  </ul>
  
  <p>Obviously my configs are <strong>not</strong> correct.  I don't see a way to attach them to this post, so if people want to walk through this step by step I will cut'n'paste them into a comment for this question.  Otherwise I am open to taking this 'offline' with a "DNS guy" to figure out where I'm missing a '.' or have one too many!</p>
  
  <p>I personally think the web could do with another internal root example that doesn't make use of the Movie-U example.</p>
  
  <p>OK, if we are going to do this, then we should use a concrete example eh?  I have 3 machines setup on a private VLAN for testing this.  As a sanity check I paired down all my relevant configs, condensed when able, and redeployed 2 of the namesevers.  I left out Scratchy for now.  Same results as above.  Here are the configs and initial dig outputs.</p>
  
  <hr>
  
  <h2>Bogus</h2>
  
  <pre><code>Machine Name: Bogus (I just realized I should change this...)  
  Role:         Internal Root and TLD Nameserver  
  IP:           10.0.0.1  
  BIND:         9.5.0-16.a6.fc8  
  </code></pre>
  
  <h3>/etc/named.conf</h3>
  
  <pre><code>// Controls who can make queries of this DNS server. Currently only the
  // local test bed. When there is a standardized IP addr scheme, we can have
  // those addr ranges enabled so that even if firewall rules get broken, the
  // public internet can't query the internal DNS.
  //
  acl "authorized" {
          localhost;      // localhost
          10.0.0.0/24;          // Local Test
  };
  
  options {
      listen-on port 53 {
          127.0.0.1;
          10.0.0.1;
      };
      listen-on-v6 port 53 { ::1; };
      directory   "/var/named";
      dump-file   "/var/named/data/cache_dump.db";
      statistics-file "/var/named/data/named_stats.txt";
      memstatistics-file "/var/named/data/named_mem_stats.txt";
      pid-file    "/var/run/named/named.pid";
      allow-query     { any; };
      recursion no;
  };
  
  logging {
          channel default_debug {
                  file "data/named.run";
                  severity dynamic;
          };
  };
  
  //
  // The fake root.
  //
  zone "." {
      type master;
      file "master/root";
      allow-query { authorized; };
  };
  
  //
  // The TLD for testing
  //
  zone "bogus" {
      type master;
      file "master/bogus";
      allow-query { authorized; };
      allow-transfer { authorized; };
  };
  </code></pre>
  
  <h3> /var/named/master/root </h3>
  
  <pre><code>$TTL    3600
  .                   SOA ns.bogustld. hostmaster.internal.bogus. (
                          2008101601  ; serial
                          1H      ; refresh
                          2H      ; retry
                          14D     ; expire
                          5M )        ; minimum
  ;
  ; Fake root zone servers defined.
  ;
  .                   NS  ns.bogustld.
  ns.bogustld.        A   10.0.0.1
  ;
  ; Testing TLD
  ;
  bogus           NS  ns1.bogus.
  ns1.bogus.              A   10.0.0.1
  </code></pre>
  
  <h3>/var/named/master/bogus</h3>
  
  <pre><code>$TTL 3600
  @           SOA ns1.internal.bogus. hostmaster.internal.bogus. (
                  2008102201  ; serial date +seq
                  1H      ; refresh
                  2H      ; retry
                  14D     ; expire
                  5M)     ; min TTL
  ;
              NS  ns1.internal.bogus.
  ;
  ; Auth servers
  ;
  ns1.internal.bogus. A   10.0.0.1
  ;
  ; Customer delegations each customer 2nd level domain has it's
  ; own zone file.
  ;
  ;Modified to be unique nameservers in the bogus domain
  itchy           NS  ns1-itchy.bogus.
  ns1-itchy.bogus.    A   10.0.0.2
  ;
  scratchy        NS  ns1-scratchy.bogus.
  ns1-scratchy.bogus. A   10.0.0.3
  </code></pre>
  
  <h3>Output from dig .</h3>
  
  <pre><code>; &lt;&lt;&gt;&gt; DiG 9.5.0-P2 &lt;&lt;&gt;&gt; .
  ;; global options:  printcmd
  ;; Got answer:
  ;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 57175
  ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
  ;; WARNING: recursion requested but not available
  
  ;; QUESTION SECTION:
  ;.                              IN      A
  
  ;; AUTHORITY SECTION:
  .                       300     IN      SOA     ns.bogustld. hostmaster.internal
  .bogus. 2008101601 3600 7200 1209600 300
  
  ;; Query time: 1 msec
  ;; SERVER: 10.0.0.1#53(10.0.0.1)
  ;; WHEN: Tue Oct 21 12:23:59 2008
  ;; MSG SIZE  rcvd: 88
  </code></pre>
  
  <h3>Output from dig +trace itchy.bogus </h3>
  
  <pre><code>; &lt;&lt;&gt;&gt; DiG 9.5.0-P2 &lt;&lt;&gt;&gt; +trace itchy.bogus
  ;; global options:  printcmd
  .                       3600    IN      NS      ns.bogustld.
  ;; Received 57 bytes from 10.0.0.1#53(10.0.0.1) in 1 ms
  
  itchy.bogus.            3600    IN      NS      ns1-itchy.bogus.
  ;; Received 69 bytes from 10.0.0.1#53(ns.bogustld) in 0 ms
  
  itchy.bogus.            3600    IN      A       10.0.0.2
  itchy.bogus.            3600    IN      NS      ns1.itchy.bogus.
  ;; Received 79 bytes from 10.0.0.2#53(ns1-itchy.bogus) in 0 ms
  </code></pre>
  
  <hr>
  
  <h2>Itchy</h2>
  
  <pre><code>Machine Name: Itchy   
  Role:         SLD Nameserver (supposed to be owner of itchy.bogus) 
  IP:           10.0.0.2  
  BIND:         9.5.0-16.a6.fc8  
  </code></pre>
  
  <h3>/etc/named.conf</h3>
  
  <pre><code>// Controls who can make queries of this DNS server. Currently only the
  // local test bed. When there is a standardized IP addr scheme, we can have
  // those addr ranges enabled so that even if firewall rules get broken, the
  // public internet can't query the internal DNS.
  //
  acl "authorized" {
          localhost;      // localhost
          10.0.0.0/24;          // LAN Test
  };
  
  options {
      listen-on port 53 {
          127.0.0.1;
          10.0.0.2;
      };
      listen-on-v6 port 53 { ::1; };
      directory   "/var/named";
      dump-file   "/var/named/data/cache_dump.db";
          statistics-file "/var/named/data/named_stats.txt";
          memstatistics-file "/var/named/data/named_mem_stats.txt";
      pid-file    "/var/run/named/named.pid";
      allow-query     { any; };
      recursion no;
  };
  
  logging {
          channel default_debug {
                  file "data/named.run";
                  severity dynamic;
          };
  };
  
  zone "." IN {
      type hint;
      file "master/root.hint";
   };
  
  zone "itchy.bogus" {
      type master;
      file "master/itchy.bogus";
      allow-query { authorized; };
      allow-transfer { authorized; };
  };
  </code></pre>
  
  <h3>/var/named/master/itchy.bogus</h3>
  
  <pre><code>$TTL    3600
  @       SOA     ns1.itchy.bogus. hostmaster.itchy.bogus. (
                  2008102202  ; serial
                  1H      ; refresh
                  2H      ; retry
                  14D     ; expire
                  5M )        ; minimum
  ;
          A   10.0.0.2
          NS      ns1.itchy.bogus.
  ns1     A   10.0.0.2
  </code></pre>
  
  <h3>/var/named/master/root.hint</h3>
  
  <pre><code>.                        3600000      NS    ns.bogustld.
  ns.bogustld.         3600000       A    10.0.0.1
  ; End of File
  </code></pre>
  
  <h3>/etc/resolv.conf</h3>
  
  <pre><code>nameserver 10.0.0.2
  </code></pre>
  
  <h3> Output from dig .</h3>
  
  <pre><code>; &lt;&lt;&gt;&gt; DiG 9.5.0-P2 &lt;&lt;&gt;&gt; .
  ;; global options:  printcmd
  ;; Got answer:
  ;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 31291
  ;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
  ;; WARNING: recursion requested but not available
  
  ;; QUESTION SECTION:
  ;.                              IN      A
  
  ;; AUTHORITY SECTION:
  .                       3600000 IN      NS      ns.bogustld.
  
  ;; Query time: 0 msec
  ;; SERVER: 10.0.0.2#53(10.0.0.2)
  ;; WHEN: Tue Oct 21 17:09:53 2008
  ;; MSG SIZE  rcvd: 41
  </code></pre>
  
  <h3>Output from dig + trace itchy.bogus </h3>
  
  <pre><code>; &lt;&lt;&gt;&gt; DiG 9.5.0-P2 &lt;&lt;&gt;&gt; +trace itchy.bogus
  ;; global options:  printcmd
  .                       3600000 IN      NS      ns.bogustld.
  ;; Received 41 bytes from 10.0.0.2#53(10.0.0.2) in 0 ms
  
  dig: couldn't get address for 'ns.bogustld': failure
  </code></pre>