Eigene Zone & DNS betreiben

Seit einigen Tagen betreibe ich meinen eigenen DNS samt eigener Zone (ich nannte sie net.hutt) auf einem externen vServer. Das ganze ist für mein kleines Heimnetzwerk eigentlich sinnlos, aber irgendwie cool. Deswegen werde ich euch im Folgenden zeigen, wie ich es gemacht habe.

Inhalt

0. Voraussetzungen

  1. Einen Server fr unseren DNS (Hauptsache eine Uptime von 24/7)
    • mit fester IP Adresse (wenn der DNS extern betrieben werden soll) oder
    • mit fester IP Adresse im Heimnetz
  2. root-Access (Dein Account sollte sudoer sein.)
  3. Etwas Erfahrung mit DNS Records

Ich habe wie gesagt Zugriff auf einen vServer, auf dem Ubuntu 12.04 LTS läuft. Anhand dieser Vorraussetzungen werde ich erklären, bei anderen linuxoiden Betriebssystemen sollte es aber gleich oder ähnlich funktionieren.

1. Installation

Als erstes brauchen wir natürlich irgendeine Software für unseren DNS, alles wollen wir ja nicht selbst machen müssen. Ich benutze bind9, das bekommt man ganz einfach in der Paketverwaltung.

apt-get install bind9

Nach der Installation startet bind sofort, ohne vernünftige Config kann man das aber vergessen. Deshalb stoppen wir es erst einmal.

sudo /etc/init.d/bind9 stop 

oder

sudo service bind9 restart

(Der Befehl kann bei euch variieren.)

10. Zonen anlegen

Die Dokumente zum Konfigurieren von bind befinden sich bei Debian-Distributionen i.d.R. unter /etc/bind, also wechseln wir erst einmal das Verzeichnis dorthin (cd sollte euch geläufig sein, sonst solltet ihr das schleunigst abbrechen und euch mit den Grundlagen vertraut machen).
In diesem Verzeichnis befinden sich typischerweise nach der Installation bei Debian-Derivaten auch die Dateien named.conf, named.conf.options, named.conf.default-zones, named.conf.local usw., doch dazu später mehr.
Die gesamte Konfiguration aller Zonen findet in der Datei named.conf statt, der Übersichtlichkeit halber gibt es aber die oben genannten Zusatzdateien, auf die in der named.conf verwiesen wird. Ist das bei euch nicht so, könnt ihr es entweder manuell tun und die Zusatzdateien anlegen, oder alles in die named.conf schreiben, wie es euch am liebsten ist.
Meine named.conf:

include "/etc/bind/named.conf.acl"; //manuell hinzugefuegt  
include "/etc/bind/named.conf.options";  
include "/etc/bind/named.conf.local";  
include "/etc/bind/named.conf.default-zones";  

Wir öffnen nun die Datei named.conf.local, in der wir die Konfiguration für unsere lokale Zone unterbringen (sie ist ja nur für die Benutzer unseres DNS existent, dem Rest des Internets bleibt sie verborgen):

sudo nano named.conf.local

(ihr könnt selbstverständlich einen anderen Editor verwenden, achtet aber darauf, als Superuser darauf zuzugreifen.)
named.conf.local:

zone "net.hutt" IN {  
        type master;
        file "/etc/bind/zones/net.hutt.db";
};

zone "1.0.10.in-addr.arpa" {  
        type master;
        file "/etc/bind/zones/rev.1.0.10.in-addr.arpa";
};

Hier habe ich zwei Zonen definiert: einmal meine eigene, net.hutt, (forward lookup zone) und einmal die zugehörige reverse lookup zone, die die IP-Adressen zu den Domains rückauflösen soll, der Zonenname hängt vom IP Netz ab:
Für den reverse lookup mit in-addr.arpa drehen wir einfach unsere IP Adresse um und lassen die nun "erste" Stelle (die ersten 8 Bit) weg und schwups haben wir unseren Zonennamen. (Wer mehr über den reverse lookup erfahren möchte klickt hier.)

Das type master; legt fest, dass es sich hier um die zentrale Zonendatei handelt und diese Zone hier verwaltet wird, file "[String]"; sagt, dass weitere Informationen in einer anderen Datei zu finden sind. Es ist einfach übersichtlicher. ;-)

11. forward lookup zone

Für die eigentlichen Zonendateien habe ich nun (wie oben zu sehen) den Ordner zones angelegt (sudo mkdir zones) und dort eine Datei namens net.hutt.db angelegt:

$ORIGIN .
$TTL 86400      ; 1 Tag
net.hutt. IN SOA intra.net.hutt. mail.net.hutt.(  
    2014012702 ; Serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)

; NS sagt aus, dass intra.net.hutt der Nameserver ist.
; (Ob es nun stimmt oder nicht (stimmt nicht))
; MX sagt, dass intra.net.hutt auch noch Mailserver ist.
net.hutt.  IN NS intra.net.hutt.  
net.hutt.  IN MX 10 intra.net.hutt.

$ORIGIN net.hutt.

; IP Adresse dieses DNS
localhost    IN A 127.0.0.1

; Hostnamen in alphabetischer Reihenfolge
intra        IN A 10.0.1.10  
nowplaying   IN A 10.0.1.10  
printer      IN A 10.0.1.200  
router       IN A 10.0.1.1  
wetter       IN A 10.0.1.10

; Subdomains
; Bisher alle fuer die elenden www.-Tipper
www.wetter.net.hutt.    IN CNAME    wetter.net.hutt.  
www.nowplaying.net.hutt. IN CNAME    nowplaying.net.hutt.  
www.printer.net.hutt.    IN CNAME    printer.net.hutt.

Der Serial ist nur eine Zeitangabe, mit der bestimmt werden kann, ob die abhängigen DNS Server die richtigen Infos haben. Format: YYYYMMDDII wobei II der Index ist, für den Fall, dass man an einem Tag mehrere Änderungen macht. (2014012702 → zuletzt geändert am 27.01.2014; zum zweiten Mal)
Der Serial muss bei jeder Änderung erneuert werden!

Mein bestimmter NS- und MX-Record ist fiktiv, weil das mit dem Server außerhalb des Heimnetzes nicht funktionieren würde. Ich habe die trotzdem hinzugefügt weil bind extrem pingelig ist, was die Syntax und Semantik angeht.
Es existieren mehrere A-Records für die gleiche IP-Adresse, weil sich dahinter ein Webserver (eigentlich mein Mac) mit vHosts verbirgt.

100. reverse lookup zone

In der reverse lookup zone muss jede IP-Adresse zur Rückauflösung eingetragen werden. Bei mehreren Subdomains pro Adresse bin ich faul geworden und habe die unwichtigen unter den Tisch fallen lassen. Bitte nehmt euch niemals ein Beispiel an mir.
→ Meine rev.1.0.10.in-addr.arpa im Verzeichnis zones:

; IP-Adressen->Host pointer
@ IN SOA intra.net.hutt. mail.net.hutt. (
    2014012702 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
; Authoritativen Nameserver definieren:
           IN NS localhost.net.hutt.
; in net.hutt.db eingetragene Hosts, 
; nach IP-Adresse sortiert.
1         IN PTR router.net.hutt.  
10        IN PTR intra.net.hutt.  
; 10      IN PTR wetter.net.hutt.
; 10      IN PTR nowplaying.net.hutt.
; 10      IN PTR geraete.net.hutt.
200       IN PTR printer.net.hutt.

; IP Address-to-Host DNS Pointer fuer das Subnet
@ IN SOA intra.net.hutt. mail.net.hutt. (
    2014012501 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
; Authoritativen Nameserver definieren
           IN NS intra.net.hutt.
; Hosts in numerischer Reihenfolge
1         IN PTR router.net.hutt.  
10        IN PTR intra.net.hutt.  
; 10      IN PTR wetter.net.hutt.
; 10      IN PTR nowplaying.net.hutt.
; 10      IN PTR geraete.net.hutt.
200       IN PTR printer.net.hutt.  

Der SOA-Record für den Name- und Mailserver ist wieder fiktiv um Fehler seitens bind zuvorzukommen. Der Rest sollte selbsterklärend sein.

101. Ein wenig Sicherheit

Was passiert nun, wenn die gesuchte Domain nicht von unserem DNS aufgelöst werden kann? Nichts. Genau das soll sich noch ändern!

Dazu tragen wir in die Datei named.conf.options noch weitere DNS ein, die in diesem Fall versuchen aufzulösen.

Um Angriffen durch Überlastung auf den DNS Server vorzubeugen habe ich auch noch eine Beschränkung zur Beantwortung der Anfragen auf den IP-Pool meines _ISP_s eingebaut.
named.conf.options:

options {  
        allow-query { any; };

        directory "/var/cache/bind";

        listen-on port 53 { xxx.xxx.xxx.xxx; }; //xxx.xxx.xxx.xxx durch die IP eures DNS Servers ersetzen!

        allow-recursion { trusted; };

        forward only;

        forwarders {
                8.8.8.8;
                8.8.4.4;
        };

        dnssec-validation auto;

        auth-nxdomain no;    # konform zu RFC1035
        listen-on-v6 { any; };

};

Hier haben wir nun den Google DNS Service als forwarder eingetragen, der ist einfach schnell und die IPs sind leicht zu merken. Wer hier Bedenken hat kann aber auch jeden beliebigen anderen DNS forwarder eintragen.

Auerdem steht da allow-recursion { trusted; };, was den Zugriff auf unsere definierten Zoneninfos auf Clients aus dem IP-Netz trusted reduzieren soll.
Dieses trusted müssen wir jedoch noch genau definieren, wofür ich unter /etc/bind die Datei named.conf.acl angelegt habe:

acl "trusted" {  
       127.0.0.1/8;
       46.5.0.0/16;
};

Es dürfen nun Clients mit den IPs 127.0.0.0 - 127.255.255.255 (alles localhost) und 46.5.0.0 - 46.5.255.255 (IP-Netz meiner Region bei meinem ISP (immer noch 65536 mögliche DDoS-Strolche)) die Auflösung auf diesem DNS Server in Anspruch nehmen, die anderen Clients werden gleich von den forwardern übernommen. Das ist alles schön und gut, jedoch muss auf diese Datei noch in der named.conf verwiesen werden, wenn ihr nicht einfach meine named.conf (s.o.) kopiert habt:

include "/etc/bind/named.conf.acl";

(vor named.conf.options und named.conf.local einfügen!!!)

110. Bugfixing

Nun kann man bind wieder starten (sudo /etc/init.d/bind9 start / sudo service bind9 start) und erst einmal nach eventuellen Fehlern suchen. Dafür schaue ich mir einfach die letzten 30 Zeilen des _syslog_s an:

sudo tail -n 30 /var/log/syslog  

111. Testen!

Wenn der DNS nun up and running ist, sollte man ihn auch verwenden. Tragt einfach seine IP als Primär- / Sekundären DNS bei eurem Rechner oder Router-Interface ein (wenn schon, denn schon).
Jetzt könnt ihr natürlich fleißig testen, ob alles funktioniert. Ein paar Beispiele:

dig intra.net.hutt
nslookup intra.net.hutt

1000. Weiteres

Um das alles abzurunden habe ich auch noch meinen Webserver unter 10.0.1.10 (ich nenne die IP liebevoll achtunddreißig*) und einige vHosts dort. Unter anderem habe ich eine Seite die das Wetter anzeigt.
(Dogeweather von Katia Eirin ist mit eigener Zone so viel cooler!)

Besitzern eines Raspberry Pi empfehle ich, das alles darauf im Heimnetz laufen zu lassen. Das ist einfacher und sicherer. Wenn ich einen hätte, würde ich das auch tun.

Wenn es bei dir nicht funktioniert und du wirklich alle Fehlerquellen untersucht hast, kannst du mir auch eine Mail schreiben, meine Adresse und meinen PGP Public Key findest du im Impressum.

Oh, und ich übernehme keine Haftung für Fehler und eventuelle Schäden die entstehen könnten.