Unix: bind v8

bind ist ein Nameserver. Im Internet gibt es prnzipiell nur IP-Adressen mit welchen Rechner addressiert werden können. Da aber kaum jemand sich IP-Adressen merken kann wurde der DNS (Domain Name Service) entwickelt. Der DNS ist eine Art Telefonbuch, das Domainnamen in IP-Adressen und umgekehrt umsetzen kann. Rund um den Globus sind mehrere Root-Nameserver verteilt, die Tabellen über Domains verwalten oder wissen, welcher andere Root-Nameserver eine bestimmte TLD (Top Level Domain, z.B. .de) kennt. Die Root-Nameserver können dann sagen, welche Nameserver mehr Infos zu der gewünschten Domain haben bis schließlich der Nameserver gefunden wurde, der die DNS-Anfrage beantworten kann. Damit dieses hierarchische System nicht für jede Anfrage durchlaufen werden muß, speichern Nameserver bekannt Infos in einem interen Cache für eine bestimmte Zeit. Mehr dazu im Text. Bevor ich es vergesse, aktuelle Version ist 9.x.

Inhalt

Übersetzen

bind besteht aus drei Paketen. Für uns ist erstmal nur das Source-Paket interessant. Wie immer: entpacken, README & INSTALL lesen und make. Da die meisten Systeme DNS Tools bereits installiert haben, empfehle ich nur die für bind notwendigen Programme nach /usr/local/sbin zu kopieren. Dies wären named, named-xfer und ndc. Die Programme finden sich nach dem Übersetzen im Unterverzeichnis bin, wobei jedes Programme wiederum ein Unterverzeichnis hat. Danach sollten Sie noch ein Init-Script zum automatischen Starten von bind schreiben (/etc/init.d).

Konfigurieren

Der bind hat eigentlich nur eine Konfigurationsdatei, in der per include weitere Dateien eingebunden werden. Diese primäre Datei ist /etc/named.conf.

named.conf

Als Beispiel soll folgende named.conf herhalten :-)

  #
  # /etc/named.conf
  #

  // So are C++-style comments
  # So are shell-style comments
  // watch out for ";" -- it's important!


  #
  # basic options
  #

  options {
    directory "/usr/local/named";
    named-xfer "/usr/local/sbin/named-xfer";
    dump-file "named_dump.db";
    pid-file "/var/run/named.pid"; 
    statistics-file "named.stats";
    memstatistics-file "named.memstats";
    check-names master fail;
    check-names slave warn;
    check-names response ignore;
    host-statistics no;
    deallocate-on-exit no;
    datasize default;
    stacksize default;
    coresize default;
    files unlimited;
    recursion yes;
    fetch-glue yes;
    fake-iquery no;
    notify yes;
    auth-nxdomain yes;
    multiple-cnames no;
    allow-query { any; };
    allow-transfer { any; };
    transfers-in 10;
    transfers-per-ns 2;
    transfers-out 0;
    max-transfer-time-in 120;
    transfer-format one-answer;
    query-source address * port *;
    forward first;
    forwarders { };
    topology { localhost; localnets; };
    listen-on port 53 { any; };
    cleaning-interval 60; 
    interface-interval 60;
    statistics-interval 60;
  };

  #
  # logging
  #

  logging {

    /* channals */

    channel default_log {
      file "/var/log/named/debug.log";
      severity info;
      print-time yes;
      print-category yes;
    };

    channel lame_servers {
      file "/var/log/named/lame-servers.log";
      severity info;
      print-time yes; 
    };

    channel queries {
      file "/var/log/named/queries.log";
      severity info;
      print-time yes;
    };

    channel zone_xfer_in {
      file "/var/log/named/xfer-in.log";
      severity info;
      print-time yes;
    };

    channel zone_xfer_out {
      file "/var/log/named/xfer-out.log";
      severity info;
      print-time yes;
    };      

    channel parser_errors {
      file "/var/log/named/parser.errors";
      severity error;
      print-time yes;
    };

    channel load_zone {
      file "/var/log/named/zone-load.log";
      severity info;
      print-time yes;
    };

    /* categories */

    category default {
      default_log;
    };

    category parser {
      parser_errors;
    };

    category config {
      parser_errors;
    };

    category lame-servers {
      lame_servers;
    };
        
    category xfer-in {
      zone_xfer_in;
    };
        
    category xfer-out {
      zone_xfer_out;
    };

    category queries {
       queries;
    };
  };


  #
  # include other files
  #

  include "zone.conf";
 

Im ersten Teil finden sich globale Parameter. Im zweiten sind unter logging zuerst die Channels definiert (wohin & wie etwas protokolliert wird) und dann die categories (welche Informations zu welchen Channel geschickt werden). Wichtig sind die Datei-Pfade. Die anderen Parameter können Sie im Doku-Paket von bind nachlesen.

zone.conf

In der obigen named.conf wird zone.conf per include-Direktive eingebunden. Die zone.conf enthält Informations über die Domain, die unser Namserver verwalten soll:

  #
  # zone.conf -- zone configurations
  #

  # basic zones

  zone "." in {
    type hint;
    file "basic/cache";
  };

  zone "localhost" in {
    type master;
    file "basic/localhost";
  };

  zone "0.0.127.in-addr.arpa" in {
    type master;
    file "basic/127.0.0";
  };

  # local zones, primary nameserver

  zone "meine-domain.de" in {
    type master;
    file "primary/meine-domain.de";
  };

  zone "0.168.192.in-addr.arpa" in {
    type master;
    file "primary/192.168.0";
  };

  # local zones, secondary DNS

  zone "domain-von-freund.com" in {
    type slave;
    file "secondary/domain-von-freund.com";
    masters { 192.192.101.1; };
  };  
 

Die Zone "." ist eine Datei mit den Root-Nameservern (Datei cache). Die aktuelle Cache-Datei können Sie meist per FTP bei ISPs oder Unis bekommen. Ihr Nameserver kann zwei Aufgaben erfüllen. Zum einen kann er Nameserver für die lokalen Domains sein. Zum anderen kann er Resolver sein, d.h. er löst über das Cache-File auch nicht-lokale Domains auf. Natürlich ist auch beides gleichzeit möglich. ISPs verwenden aus Management- und Performance-Gründen oft getrennte Nameserver und Resolver.

Die Zonen "localhost" und "0.0.127.in-addr.arpa" dienen dazu, daß sich der Rechner selber (Loopback-Device) kennt. Mit "0.0.127.in-addr.arpa" hat es etwas besonderes auf sich. Für das Reverse Mapping (Umsetzung IP-Adresse in Name) wurde aus historischen Gründen das Class-C in umgekehrter Reihenfolge mit dem in-addr.arpa angehängt zum Namen der Zone erklärt. Das Loopback-Interface Deines Rechner hat 127.0.0.1 als IP-Adresse. Das Class-C Netz dazu ist 127.0.0.0/24 (bzw. 172.0.0.0 mit der Netzmaske 255.255.255.0). Nun wird das Netz umgedreht und Du hast "0.0.127". Als letzes kommt noch "in-addr.arpa" dazu. Ganz nebenbei wissen Sie jetzt, daß das Reverse Mapping nur Class-C-weise funktioniert.

localhost Zone-Files

Die Zone-Files beschreiben die einzelnen Zonen (Domains). Es gibt unterschiedliche Schreibweisen, die Sie in der Doku zu bind nachlesen können. Zunächst das Zone-File zu "localhost":

  $ORIGIN localhost.
  @       1D IN SOA       @ root (
                          42              ; serial
                          3H              ; refresh
                          15M             ; retry
                          1W              ; expiry
                          1D )            ; minimum

          1D IN NS        @
          1D IN A         127.0.0.1
 

... und "0.0.127.in-addr.arpa":

  $ORIGIN 0.0.127.in-addr.arpa.
  @       1D IN SOA       localhost. root.localhost. (
                          42              ; serial
                          3H              ; refresh
                          15M             ; retry
                          1W              ; expiry
                          1D )            ; minimum

          1D IN NS        localhost.
  1       1D IN PTR       localhost.
 

Beispiel Domain

... in einer übersichtlicheren Schreibweise.

  $ORIGIN theca-tabellaria.de.
  @       IN SOA  ns.theca-tabellaria.de. hostmaster.theca-tabellaria.de. (
                  1999022801      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
 
  @       IN NS   ns.theca-tabellaria.de.
          IN NS   dns.my-provider.net.
          IN MX   10 mail.theca-tabellaria.de.
                  190 relay.my-provider.net.
          IN A    1.2.3.4
  ;
  ns      IN A    1.2.3.2
  mail    IN A    1.2.3.3
          IN MX   10 mail.theca-tabellaria.de.
  router  IN A    1.2.3.1
  server  IN A    1.2.3.4
  www     IN CNAME   server
  ftp     IN CNAME   server
 

Das Zonefile beschreibt die Domain theca-tabellaria.de ($ORIGIN). Hinter manchen Namen steht ein Punkt. Der Punkt markiert das Ende des Namens. Fehlt der Punkt wird automatisch der Domainname angehängt. Nun ist der SOA-Bereich dran. Zuerst kommt der primäre Namserver und der Verwalter (EMail-Adresse ohne @) der Domain. Die Seriennummer sollte die Form YYYYMMDDRR (Y=Year M=Month D=Day R=Revision) haben. Falls Sie igendetwas am Zonefile ändern, immer die Seriennummer aktualisieren. Anhand dieser Nummer können andere Nameserver feststellen, ob es ein neues Zonefile gibt oder nicht. Ist die Seriennummer nicht größer als die alte, nimmt ein anderer Nameserver an, daß sich nicht geändert hat. Die refresh time gibt vor nach welcher Zeit in Sekunden spätestens ein anderer Nameserver nach aktuellen Daten fragt. Und wenn die Nachfrage schief geht, soll er immer spätestens nach der retry time einen neuen Versuch starten. Ist die expire time erreicht, ohne daß ein Update geholt werden konnte, wird die Zone für tot erklärt. Die minimum TTL sagt aus, wie lange mindestens die Daten im Cache der anderen Nameserver gültig bleiben sollen.

Für die Zone selber (@) legen wir Grundinformationen fest. Mit IN NS sind die zuständigen Nameserver definiert. IN MX sagt wohin Mail für unsere Domain geschickt werden sollen. Die Zahl vor den Namen ist die Priorität. Je kleiner die desto höher die Prirität. Fällt der erste Mailserver aus, wird die Post an den nächsten geschickt. Der zweite Mailserver lagert die Post zwischen und schickt sie dann weiter an den eigentlichen Server, wenn er wieder erreichbar ist (Mail Relay). Der Spezialeintrag IN A 1.2.3.4 gibt bereits dem Domainnamen selber eine IP-Adresse, z.B. für http://theca-tabellaria.de.

Nun sind die Rechner bzw. Sub-Domains dran. Jede Sub-Domain kann wiederum eigene Namserver oder Mailserver haben. Sie arbeiten hier meist mit IN A, um eine IP-Adresse anzugeben, oder mit IN CNAME für ein alias auf einen bereits bekannten Namen. Bei Alias aufpassen, daß Sie keine Schleifen erzeugen. Der Mailserver hat selber noch mal einen MX-Eintrag auf sich selbst (hilft dem sendmail) für lokale EMail-Zustellung).

Beispiel Reverse Mapping

  $ORIGIN 3.2.1.in-addr.arpa.
  @       IN SOA  ns.theca-tabellaria.de. hostmaster.theca-tabellaria.fun. (
                  1999022801      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
 
  @       IN NS   ns.theca-tabellaria.de.
          IN NS   dns.my-provider.net.
  ;
  1       IN PTR  router.theca-tabellaria.de.
  2       IN PTR  ns.theca-tabellaria.de.
  3       IN PTR  mail.theca-tabellaria.de.
  4       IN PTR  server.theca-tabellaria.de.
 

Das ist das Reverse Mapping für das Netz 1.2.3.0/24. Links steht die IP-Adresse und nach IN PTR der Name. Jede IP-Adresse darf nur einmal vorkommen!

Wichtig!

Folgende Regeln sind sehr wichtig:

Access Listen

Mittels Accesslisten lassen sich Nameserverabfragen kontrollieren. Zuerst schreiben Sie eine Access Liste acl.conf und binden sie per include in die named.conf ein, z.B.:

  #
  # acl.conf - access lists
  #

  acl my_subnet {
    3.2.1.0/24;
  };

  acl my_provider {
    my_subnet;
    1.2.3.4/32;
    1.2.4.3/32;
 

Es gibt auch schon vier vordefinierte Listen:

In der zone.conf können Sie nun für jede einzelne Zone die Access-Listen nutzen. Dazu gibt es zusätzliche Optionen:

allow-update ist standardmäßig auf none gesetzt.

Es gibt aber auch noch globale Optionen für die named.conf:

In der named.conf ist oft voreingestellt:

  options {
    allow-query { any; };
    allow-transfer { any; };
  };
 

Somit dürfen alle Rechner im Internet unseren Nameserver für Abfragen nutzen und Zonefiles ziehen. Nun wollen wir aber das Abfragen des kompletten Zonefiles einer Domain einschränken. Nur meine eigenen Rechner und die beiden Nameserver meines Providers sollen Zugriff auf Zonefile-Transfers haben. Also in der zone.conf eintragen:

  zone "theca-tabellaria.de" in {
    type master;
    file "primary/theca-tabellaria.de";
    allow-transfer { my_provider; };
  };
 

Wenn ich noch eine "geheime" interne Domain habe, und nur interne DNS-Abfragen zulasse:

  zone "geheim.intra" in {
    type master;
    file "primary/geheim.intra";
    allow-query { intranet; };
    allow-transfer { none; };
  };
 

Hinweis: Viele NICs testen bei einer Domainregistration die Nameserver. Manche prüfen dies durch ein Zonefile-Transfer. Wenn die Transfers gesperrt sind, wird das NIC die Domain nicht registrieren.

Administrieren

Das Tool ndc hilft Ihnen beim Administrieren des Nameservers. Vor v8.2 war ndc ein Shellscript. Nun ist es ein Binary, daß per Optionen oder interaktiv einige Funktionen bietet. Die wichtigste Funktion ist ein Reload der Konfiguration. Nach Änderungen von z.B. zone.conf oder eines Zonefile sollten sie:

  ndc reload
 

ausführen. Bei Syntax-Fehlern in der Konfiguration steht in der Log-Datei parser.errors was bind nicht mag. Oft fehlen Semikolons oder Anführungszeichen oder sind zu viel. Zum Überprüfen des Nameservers sind nslookup, dig oder host nützlich.

Bind unterstützt auch zahlreiche Sicherheits-Features. Sie könnten Zonefile-Transfers einschränken oder Secure DNS aktivieren. Mehr dazu in dem Doku-Paket von bind.

Tricks

Kleine Tricks mit großer Wirkung.

Reverse Mapping für Netze kleiner /24

Für die Deligierung von Reverse Mapping für Sub-Netze gibt es einen Trick (siehe auch RFC 2317: Classless IN-ADDR.ARPA delegation). Der Trick funktioniert nur einmal. d.h. ein Sub-Netz kann nicht nochmal weiter deligiert werden. Die Basis des Tricks ist eine Weiterdelegation via CNAME. Das Zonefile für das Class-C sieht z.B. so aus:

  $ORIGIN 3.2.1.in-addr.arpa.
  @       IN SOA  ns.theca-tabellaria.de. hostmaster.theca-tabellaria.fun. (
                  1999022801      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
 
  @       IN NS   ns.theca-tabellaria.net.
          IN NS   ns2.theca-tabellaria.net.

  ; 3.2.1.0/29
  0/29     NS      ns.kunde.de.
  0/29     NS      ns2.kunde.de.
  ;
  1    IN CNAME    1.0/29
  2    IN CNAME    2.0/29
  3    IN CNAME    3.0/29
  4    IN CNAME    4.0/29
  5    IN CNAME    5.0/29
  6    IN CNAME    6.0/29
  7    IN CNAME    7.0/29

  ; 3.2.1.8/30
  8/30     NS      ns.anderer-kunde.de.
  8/30     NS      ns2.theca-tabellaria.net.
  ;
  9    IN CNAME    9.8/30
  10   IN CNAME    10.8/30
 

Das Zonefile für ns.kunde.de wäre:

  $ORIGIN 0/29.3.2.1.in-addr.arpa.
  @       IN SOA  ns.kunde.de. hostmaster.kunde.de. (
                  1999070903      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
  @       IN NS   ns.kunde.de.
          IN NS   ns2.kunde.de.

  1       IN PTR  router.kunde.de.
  2       IN PTR  server.kunde.de.
  3       IN PTR  ns.kunde.de.
  4       IN PTR  ns2.kunde.de.
  7       IN PTR  mail.kunde.de.
 

Für ns.anderer-kunde.de entsprechend:

  $ORIGIN 8/30.3.2.1.in-addr.arpa.
  @       IN SOA  ns.anderer-kunde.de. hostmaster.anderer-kunde.de. (
                  1999063001      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
  @       IN NS   ns.anderer-kunde.de.
          IN NS   ns.theca-tabellartia.net.

  9       IN PTR  server.anderer-kunde.de.
  10      IN PTR  www.bla-bla.de.
 

Hidden Primary

Bei Hidden Primary wird der primäre Nameserver versteckt. Offiziell sind andere Nameserver für die Domain zuständig. Der Vorteil kommt zu tragen, wenn die offiziellen Nameserver wesentlch besser als der Primäre am Internet angebunden sind. Nameserveranfragen werden etwas schneller beantwortet. Auf dem primären Nameserver vom Kunden:

  $ORIGIN kunde.de.
  @       IN SOA  ns.my-provider.net. hostmaster.my-provider.net. (
                  1999063001      ; serial
                  43200           ; refresh after 12 hours
                  3600            ; retry after 1 hour
                  2419200         ; expire after 4 weeks
                  86400           ; minimum TTL of 1 day
                  )
  @       IN NS   ns.my-provider.net.
          IN NS   ns2.my-provider.net.

  server      IN A   1.2.3.200
 

Der Provider trägt die Domain kunde.de auf seinen beiden Nameservern ein, als ob seine Nameserver secondary DNS für die Domain anbieten. Und offiziell wird bei dem zuständigen NIC die Domain mit den beiden Provider-Nameservern registriert.